ai-tool-adapter 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ /**
3
+ * Tests for OpenAI adapter
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const vitest_1 = require("vitest");
7
+ const openai_1 = require("./openai");
8
+ (0, vitest_1.describe)('openaiAdapter', () => {
9
+ (0, vitest_1.it)('should convert a basic tool with required params', () => {
10
+ const tool = {
11
+ name: 'get_weather',
12
+ description: 'Get current weather for a location',
13
+ params: {
14
+ location: {
15
+ type: 'string',
16
+ description: 'City name',
17
+ required: true,
18
+ },
19
+ },
20
+ };
21
+ const result = (0, openai_1.openaiAdapter)(tool);
22
+ (0, vitest_1.expect)(result).toEqual({
23
+ type: 'function',
24
+ function: {
25
+ name: 'get_weather',
26
+ description: 'Get current weather for a location',
27
+ parameters: {
28
+ type: 'object',
29
+ properties: {
30
+ location: {
31
+ type: 'string',
32
+ description: 'City name',
33
+ },
34
+ },
35
+ required: ['location'],
36
+ },
37
+ },
38
+ });
39
+ });
40
+ (0, vitest_1.it)('should handle enum values', () => {
41
+ const tool = {
42
+ name: 'set_temperature',
43
+ description: 'Set temperature unit',
44
+ params: {
45
+ unit: {
46
+ type: 'string',
47
+ enum: ['celsius', 'fahrenheit', 'kelvin'],
48
+ required: true,
49
+ },
50
+ },
51
+ };
52
+ const result = (0, openai_1.openaiAdapter)(tool);
53
+ (0, vitest_1.expect)(result.function.parameters.properties.unit).toEqual({
54
+ type: 'string',
55
+ enum: ['celsius', 'fahrenheit', 'kelvin'],
56
+ });
57
+ });
58
+ (0, vitest_1.it)('should handle array types with items', () => {
59
+ const tool = {
60
+ name: 'process_items',
61
+ description: 'Process a list of items',
62
+ params: {
63
+ items: {
64
+ type: 'array',
65
+ description: 'List of items',
66
+ items: { type: 'string' },
67
+ required: true,
68
+ },
69
+ },
70
+ };
71
+ const result = (0, openai_1.openaiAdapter)(tool);
72
+ (0, vitest_1.expect)(result.function.parameters.properties.items).toEqual({
73
+ type: 'array',
74
+ description: 'List of items',
75
+ items: { type: 'string' },
76
+ });
77
+ });
78
+ (0, vitest_1.it)('should handle default values', () => {
79
+ const tool = {
80
+ name: 'paginate',
81
+ description: 'Get paginated results',
82
+ params: {
83
+ page: {
84
+ type: 'number',
85
+ default: 1,
86
+ },
87
+ limit: {
88
+ type: 'number',
89
+ default: 10,
90
+ },
91
+ },
92
+ };
93
+ const result = (0, openai_1.openaiAdapter)(tool);
94
+ (0, vitest_1.expect)(result.function.parameters.properties.page).toEqual({
95
+ type: 'number',
96
+ default: 1,
97
+ });
98
+ (0, vitest_1.expect)(result.function.parameters.properties.limit).toEqual({
99
+ type: 'number',
100
+ default: 10,
101
+ });
102
+ });
103
+ (0, vitest_1.it)('should handle mixed required and optional params', () => {
104
+ const tool = {
105
+ name: 'search',
106
+ description: 'Search for items',
107
+ params: {
108
+ query: {
109
+ type: 'string',
110
+ description: 'Search query',
111
+ required: true,
112
+ },
113
+ limit: {
114
+ type: 'number',
115
+ description: 'Result limit',
116
+ default: 10,
117
+ },
118
+ exact: {
119
+ type: 'boolean',
120
+ description: 'Exact match',
121
+ },
122
+ },
123
+ };
124
+ const result = (0, openai_1.openaiAdapter)(tool);
125
+ (0, vitest_1.expect)(result.function.parameters.required).toEqual(['query']);
126
+ (0, vitest_1.expect)(result.function.parameters.properties).toHaveProperty('query');
127
+ (0, vitest_1.expect)(result.function.parameters.properties).toHaveProperty('limit');
128
+ (0, vitest_1.expect)(result.function.parameters.properties).toHaveProperty('exact');
129
+ });
130
+ (0, vitest_1.it)('should handle empty params', () => {
131
+ const tool = {
132
+ name: 'get_status',
133
+ description: 'Get current status',
134
+ params: {},
135
+ };
136
+ const result = (0, openai_1.openaiAdapter)(tool);
137
+ (0, vitest_1.expect)(result.function.parameters).toEqual({
138
+ type: 'object',
139
+ properties: {},
140
+ required: [],
141
+ });
142
+ });
143
+ (0, vitest_1.it)('should use lowercase type names', () => {
144
+ const tool = {
145
+ name: 'test_types',
146
+ description: 'Test all types',
147
+ params: {
148
+ str: { type: 'string' },
149
+ num: { type: 'number' },
150
+ bool: { type: 'boolean' },
151
+ arr: { type: 'array', items: { type: 'string' } },
152
+ obj: { type: 'object' },
153
+ },
154
+ };
155
+ const result = (0, openai_1.openaiAdapter)(tool);
156
+ const props = result.function.parameters.properties;
157
+ (0, vitest_1.expect)(props.str.type).toBe('string');
158
+ (0, vitest_1.expect)(props.num.type).toBe('number');
159
+ (0, vitest_1.expect)(props.bool.type).toBe('boolean');
160
+ (0, vitest_1.expect)(props.arr.type).toBe('array');
161
+ (0, vitest_1.expect)(props.obj.type).toBe('object');
162
+ });
163
+ (0, vitest_1.it)('should wrap in function object', () => {
164
+ const tool = {
165
+ name: 'test',
166
+ description: 'Test tool',
167
+ params: {},
168
+ };
169
+ const result = (0, openai_1.openaiAdapter)(tool);
170
+ (0, vitest_1.expect)(result).toHaveProperty('type', 'function');
171
+ (0, vitest_1.expect)(result).toHaveProperty('function');
172
+ (0, vitest_1.expect)(result.function).toHaveProperty('name');
173
+ (0, vitest_1.expect)(result.function).toHaveProperty('description');
174
+ (0, vitest_1.expect)(result.function).toHaveProperty('parameters');
175
+ });
176
+ });
package/dist/index.d.ts CHANGED
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Universal AI Tool Schema Adapter
3
+ *
4
+ * Write tool definitions once, convert to any LLM provider format.
5
+ * Eliminates duplication and provider lock-in.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { adapt } from 'ai-tool-adapter';
10
+ *
11
+ * const tool = {
12
+ * name: 'get_weather',
13
+ * description: 'Get current weather for a location',
14
+ * params: {
15
+ * location: { type: 'string', required: true },
16
+ * units: { type: 'string', enum: ['celsius', 'fahrenheit'] }
17
+ * }
18
+ * };
19
+ *
20
+ * const openaiTool = adapt(tool, 'openai');
21
+ * const anthropicTool = adapt(tool, 'anthropic');
22
+ * ```
23
+ */
24
+ import { UniversalTool, Provider } from './types';
25
+ /**
26
+ * Convert a universal tool definition to a specific provider's format
27
+ *
28
+ * @param tool - Universal tool definition
29
+ * @param provider - Target AI provider
30
+ * @returns Provider-specific tool format
31
+ * @throws {Error} If provider is not supported
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const tool = {
36
+ * name: 'calculate',
37
+ * description: 'Perform arithmetic calculation',
38
+ * params: {
39
+ * operation: { type: 'string', required: true, enum: ['add', 'subtract'] },
40
+ * a: { type: 'number', required: true },
41
+ * b: { type: 'number', required: true }
42
+ * }
43
+ * };
44
+ *
45
+ * const openaiTool = adapt(tool, 'openai');
46
+ * ```
47
+ */
48
+ export declare function adapt(tool: UniversalTool, provider: Provider): unknown;
49
+ /**
50
+ * Convert multiple universal tool definitions to a specific provider's format
51
+ *
52
+ * @param tools - Array of universal tool definitions
53
+ * @param provider - Target AI provider
54
+ * @returns Array of provider-specific tool formats
55
+ * @throws {Error} If provider is not supported
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const tools = [
60
+ * { name: 'get_weather', description: 'Get weather', params: {...} },
61
+ * { name: 'get_time', description: 'Get time', params: {...} }
62
+ * ];
63
+ *
64
+ * const openaiTools = adaptAll(tools, 'openai');
65
+ * ```
66
+ */
67
+ export declare function adaptAll(tools: UniversalTool[], provider: Provider): unknown[];
68
+ /**
69
+ * Get list of all supported AI providers
70
+ *
71
+ * @returns Array of supported provider names
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * const providers = getProviders();
76
+ * console.log(providers); // ['openai', 'anthropic', 'gemini', 'mistral']
77
+ * ```
78
+ */
79
+ export declare function getProviders(): Provider[];
80
+ /**
81
+ * Export types for TypeScript consumers
82
+ */
83
+ export type { UniversalTool, ToolParam, Provider, ParamType } from './types';
package/dist/index.js CHANGED
@@ -1 +1,106 @@
1
1
  "use strict";
2
+ /**
3
+ * Universal AI Tool Schema Adapter
4
+ *
5
+ * Write tool definitions once, convert to any LLM provider format.
6
+ * Eliminates duplication and provider lock-in.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { adapt } from 'ai-tool-adapter';
11
+ *
12
+ * const tool = {
13
+ * name: 'get_weather',
14
+ * description: 'Get current weather for a location',
15
+ * params: {
16
+ * location: { type: 'string', required: true },
17
+ * units: { type: 'string', enum: ['celsius', 'fahrenheit'] }
18
+ * }
19
+ * };
20
+ *
21
+ * const openaiTool = adapt(tool, 'openai');
22
+ * const anthropicTool = adapt(tool, 'anthropic');
23
+ * ```
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.adapt = adapt;
27
+ exports.adaptAll = adaptAll;
28
+ exports.getProviders = getProviders;
29
+ const openai_1 = require("./adapters/openai");
30
+ const anthropic_1 = require("./adapters/anthropic");
31
+ const gemini_1 = require("./adapters/gemini");
32
+ const mistral_1 = require("./adapters/mistral");
33
+ /**
34
+ * Adapter registry mapping provider names to their adapter functions
35
+ */
36
+ const adapters = {
37
+ openai: openai_1.openaiAdapter,
38
+ anthropic: anthropic_1.anthropicAdapter,
39
+ gemini: gemini_1.geminiAdapter,
40
+ mistral: mistral_1.mistralAdapter,
41
+ };
42
+ /**
43
+ * Convert a universal tool definition to a specific provider's format
44
+ *
45
+ * @param tool - Universal tool definition
46
+ * @param provider - Target AI provider
47
+ * @returns Provider-specific tool format
48
+ * @throws {Error} If provider is not supported
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const tool = {
53
+ * name: 'calculate',
54
+ * description: 'Perform arithmetic calculation',
55
+ * params: {
56
+ * operation: { type: 'string', required: true, enum: ['add', 'subtract'] },
57
+ * a: { type: 'number', required: true },
58
+ * b: { type: 'number', required: true }
59
+ * }
60
+ * };
61
+ *
62
+ * const openaiTool = adapt(tool, 'openai');
63
+ * ```
64
+ */
65
+ function adapt(tool, provider) {
66
+ const adapter = adapters[provider];
67
+ if (!adapter) {
68
+ throw new Error(`Unknown provider: ${provider}. Supported providers: ${getProviders().join(', ')}`);
69
+ }
70
+ return adapter(tool);
71
+ }
72
+ /**
73
+ * Convert multiple universal tool definitions to a specific provider's format
74
+ *
75
+ * @param tools - Array of universal tool definitions
76
+ * @param provider - Target AI provider
77
+ * @returns Array of provider-specific tool formats
78
+ * @throws {Error} If provider is not supported
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const tools = [
83
+ * { name: 'get_weather', description: 'Get weather', params: {...} },
84
+ * { name: 'get_time', description: 'Get time', params: {...} }
85
+ * ];
86
+ *
87
+ * const openaiTools = adaptAll(tools, 'openai');
88
+ * ```
89
+ */
90
+ function adaptAll(tools, provider) {
91
+ return tools.map((tool) => adapt(tool, provider));
92
+ }
93
+ /**
94
+ * Get list of all supported AI providers
95
+ *
96
+ * @returns Array of supported provider names
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * const providers = getProviders();
101
+ * console.log(providers); // ['openai', 'anthropic', 'gemini', 'mistral']
102
+ * ```
103
+ */
104
+ function getProviders() {
105
+ return Object.keys(adapters);
106
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Integration tests for the public API
3
+ */
4
+ export {};
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ /**
3
+ * Integration tests for the public API
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const vitest_1 = require("vitest");
7
+ const index_1 = require("./index");
8
+ (0, vitest_1.describe)('adapt', () => {
9
+ const sampleTool = {
10
+ name: 'get_weather',
11
+ description: 'Get current weather for a location',
12
+ params: {
13
+ location: {
14
+ type: 'string',
15
+ description: 'City name',
16
+ required: true,
17
+ },
18
+ units: {
19
+ type: 'string',
20
+ enum: ['celsius', 'fahrenheit'],
21
+ },
22
+ },
23
+ };
24
+ (0, vitest_1.it)('should adapt tool to OpenAI format', () => {
25
+ const result = (0, index_1.adapt)(sampleTool, 'openai');
26
+ (0, vitest_1.expect)(result).toHaveProperty('type', 'function');
27
+ (0, vitest_1.expect)(result).toHaveProperty('function');
28
+ });
29
+ (0, vitest_1.it)('should adapt tool to Anthropic format', () => {
30
+ const result = (0, index_1.adapt)(sampleTool, 'anthropic');
31
+ (0, vitest_1.expect)(result).toHaveProperty('name', 'get_weather');
32
+ (0, vitest_1.expect)(result).toHaveProperty('input_schema');
33
+ (0, vitest_1.expect)(result).not.toHaveProperty('type');
34
+ });
35
+ (0, vitest_1.it)('should adapt tool to Gemini format', () => {
36
+ const result = (0, index_1.adapt)(sampleTool, 'gemini');
37
+ (0, vitest_1.expect)(result).toHaveProperty('name', 'get_weather');
38
+ (0, vitest_1.expect)(result).toHaveProperty('parameters');
39
+ (0, vitest_1.expect)(result).not.toHaveProperty('type');
40
+ });
41
+ (0, vitest_1.it)('should adapt tool to Mistral format', () => {
42
+ const result = (0, index_1.adapt)(sampleTool, 'mistral');
43
+ (0, vitest_1.expect)(result).toHaveProperty('type', 'function');
44
+ (0, vitest_1.expect)(result).toHaveProperty('function');
45
+ });
46
+ (0, vitest_1.it)('should throw error for unknown provider', () => {
47
+ (0, vitest_1.expect)(() => {
48
+ (0, index_1.adapt)(sampleTool, 'unknown');
49
+ }).toThrow('Unknown provider: unknown');
50
+ });
51
+ (0, vitest_1.it)('should include list of supported providers in error message', () => {
52
+ (0, vitest_1.expect)(() => {
53
+ (0, index_1.adapt)(sampleTool, 'invalid');
54
+ }).toThrow(/openai.*anthropic.*gemini.*mistral/);
55
+ });
56
+ });
57
+ (0, vitest_1.describe)('adaptAll', () => {
58
+ const tools = [
59
+ {
60
+ name: 'get_weather',
61
+ description: 'Get weather',
62
+ params: {
63
+ location: { type: 'string', required: true },
64
+ },
65
+ },
66
+ {
67
+ name: 'get_time',
68
+ description: 'Get current time',
69
+ params: {
70
+ timezone: { type: 'string' },
71
+ },
72
+ },
73
+ {
74
+ name: 'calculate',
75
+ description: 'Perform calculation',
76
+ params: {
77
+ operation: { type: 'string', enum: ['add', 'subtract'], required: true },
78
+ a: { type: 'number', required: true },
79
+ b: { type: 'number', required: true },
80
+ },
81
+ },
82
+ ];
83
+ (0, vitest_1.it)('should adapt multiple tools to OpenAI format', () => {
84
+ const results = (0, index_1.adaptAll)(tools, 'openai');
85
+ (0, vitest_1.expect)(results).toHaveLength(3);
86
+ results.forEach((result) => {
87
+ (0, vitest_1.expect)(result).toHaveProperty('type', 'function');
88
+ (0, vitest_1.expect)(result).toHaveProperty('function');
89
+ });
90
+ });
91
+ (0, vitest_1.it)('should adapt multiple tools to Anthropic format', () => {
92
+ const results = (0, index_1.adaptAll)(tools, 'anthropic');
93
+ (0, vitest_1.expect)(results).toHaveLength(3);
94
+ results.forEach((result) => {
95
+ (0, vitest_1.expect)(result).toHaveProperty('name');
96
+ (0, vitest_1.expect)(result).toHaveProperty('input_schema');
97
+ });
98
+ });
99
+ (0, vitest_1.it)('should adapt multiple tools to Gemini format', () => {
100
+ const results = (0, index_1.adaptAll)(tools, 'gemini');
101
+ (0, vitest_1.expect)(results).toHaveLength(3);
102
+ results.forEach((result) => {
103
+ (0, vitest_1.expect)(result).toHaveProperty('name');
104
+ (0, vitest_1.expect)(result).toHaveProperty('parameters');
105
+ });
106
+ });
107
+ (0, vitest_1.it)('should adapt multiple tools to Mistral format', () => {
108
+ const results = (0, index_1.adaptAll)(tools, 'mistral');
109
+ (0, vitest_1.expect)(results).toHaveLength(3);
110
+ results.forEach((result) => {
111
+ (0, vitest_1.expect)(result).toHaveProperty('type', 'function');
112
+ (0, vitest_1.expect)(result).toHaveProperty('function');
113
+ });
114
+ });
115
+ (0, vitest_1.it)('should handle empty array', () => {
116
+ const results = (0, index_1.adaptAll)([], 'openai');
117
+ (0, vitest_1.expect)(results).toEqual([]);
118
+ });
119
+ (0, vitest_1.it)('should throw error for unknown provider', () => {
120
+ (0, vitest_1.expect)(() => {
121
+ (0, index_1.adaptAll)(tools, 'invalid');
122
+ }).toThrow('Unknown provider');
123
+ });
124
+ });
125
+ (0, vitest_1.describe)('getProviders', () => {
126
+ (0, vitest_1.it)('should return array of all supported providers', () => {
127
+ const providers = (0, index_1.getProviders)();
128
+ (0, vitest_1.expect)(providers).toBeInstanceOf(Array);
129
+ (0, vitest_1.expect)(providers).toHaveLength(4);
130
+ });
131
+ (0, vitest_1.it)('should include all four providers', () => {
132
+ const providers = (0, index_1.getProviders)();
133
+ (0, vitest_1.expect)(providers).toContain('openai');
134
+ (0, vitest_1.expect)(providers).toContain('anthropic');
135
+ (0, vitest_1.expect)(providers).toContain('gemini');
136
+ (0, vitest_1.expect)(providers).toContain('mistral');
137
+ });
138
+ });
139
+ (0, vitest_1.describe)('Cross-provider consistency', () => {
140
+ const tool = {
141
+ name: 'test_tool',
142
+ description: 'A test tool for validation',
143
+ params: {
144
+ required_param: {
145
+ type: 'string',
146
+ description: 'A required parameter',
147
+ required: true,
148
+ },
149
+ optional_param: {
150
+ type: 'number',
151
+ description: 'An optional parameter',
152
+ default: 42,
153
+ },
154
+ enum_param: {
155
+ type: 'string',
156
+ enum: ['option1', 'option2', 'option3'],
157
+ },
158
+ array_param: {
159
+ type: 'array',
160
+ items: { type: 'string' },
161
+ },
162
+ },
163
+ };
164
+ (0, vitest_1.it)('should preserve tool name across all providers', () => {
165
+ const openai = (0, index_1.adapt)(tool, 'openai');
166
+ const anthropic = (0, index_1.adapt)(tool, 'anthropic');
167
+ const gemini = (0, index_1.adapt)(tool, 'gemini');
168
+ const mistral = (0, index_1.adapt)(tool, 'mistral');
169
+ (0, vitest_1.expect)(openai.function.name).toBe('test_tool');
170
+ (0, vitest_1.expect)(anthropic.name).toBe('test_tool');
171
+ (0, vitest_1.expect)(gemini.name).toBe('test_tool');
172
+ (0, vitest_1.expect)(mistral.function.name).toBe('test_tool');
173
+ });
174
+ (0, vitest_1.it)('should preserve tool description across all providers', () => {
175
+ const openai = (0, index_1.adapt)(tool, 'openai');
176
+ const anthropic = (0, index_1.adapt)(tool, 'anthropic');
177
+ const gemini = (0, index_1.adapt)(tool, 'gemini');
178
+ const mistral = (0, index_1.adapt)(tool, 'mistral');
179
+ (0, vitest_1.expect)(openai.function.description).toBe('A test tool for validation');
180
+ (0, vitest_1.expect)(anthropic.description).toBe('A test tool for validation');
181
+ (0, vitest_1.expect)(gemini.description).toBe('A test tool for validation');
182
+ (0, vitest_1.expect)(mistral.function.description).toBe('A test tool for validation');
183
+ });
184
+ (0, vitest_1.it)('should preserve required params across all providers', () => {
185
+ const openai = (0, index_1.adapt)(tool, 'openai');
186
+ const anthropic = (0, index_1.adapt)(tool, 'anthropic');
187
+ const gemini = (0, index_1.adapt)(tool, 'gemini');
188
+ const mistral = (0, index_1.adapt)(tool, 'mistral');
189
+ (0, vitest_1.expect)(openai.function.parameters.required).toContain('required_param');
190
+ (0, vitest_1.expect)(anthropic.input_schema.required).toContain('required_param');
191
+ (0, vitest_1.expect)(gemini.parameters.required).toContain('required_param');
192
+ (0, vitest_1.expect)(mistral.function.parameters.required).toContain('required_param');
193
+ });
194
+ (0, vitest_1.it)('should preserve enum values across all providers', () => {
195
+ const openai = (0, index_1.adapt)(tool, 'openai');
196
+ const anthropic = (0, index_1.adapt)(tool, 'anthropic');
197
+ const gemini = (0, index_1.adapt)(tool, 'gemini');
198
+ const mistral = (0, index_1.adapt)(tool, 'mistral');
199
+ const expectedEnum = ['option1', 'option2', 'option3'];
200
+ (0, vitest_1.expect)(openai.function.parameters.properties.enum_param.enum).toEqual(expectedEnum);
201
+ (0, vitest_1.expect)(anthropic.input_schema.properties.enum_param.enum).toEqual(expectedEnum);
202
+ (0, vitest_1.expect)(gemini.parameters.properties.enum_param.enum).toEqual(expectedEnum);
203
+ (0, vitest_1.expect)(mistral.function.parameters.properties.enum_param.enum).toEqual(expectedEnum);
204
+ });
205
+ (0, vitest_1.it)('should preserve default values across all providers', () => {
206
+ const openai = (0, index_1.adapt)(tool, 'openai');
207
+ const anthropic = (0, index_1.adapt)(tool, 'anthropic');
208
+ const gemini = (0, index_1.adapt)(tool, 'gemini');
209
+ const mistral = (0, index_1.adapt)(tool, 'mistral');
210
+ (0, vitest_1.expect)(openai.function.parameters.properties.optional_param.default).toBe(42);
211
+ (0, vitest_1.expect)(anthropic.input_schema.properties.optional_param.default).toBe(42);
212
+ (0, vitest_1.expect)(gemini.parameters.properties.optional_param.default).toBe(42);
213
+ (0, vitest_1.expect)(mistral.function.parameters.properties.optional_param.default).toBe(42);
214
+ });
215
+ });
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Universal AI Tool Schema Adapter - Type Definitions
3
+ *
4
+ * This is the Single Source of Truth for the data contract.
5
+ * All adapters import from here to ensure consistency.
6
+ */
7
+ /**
8
+ * Supported parameter types in the universal schema
9
+ */
10
+ export type ParamType = 'string' | 'number' | 'boolean' | 'array' | 'object';
11
+ /**
12
+ * Parameter definition in the universal tool schema
13
+ */
14
+ export interface ToolParam {
15
+ /** The type of this parameter */
16
+ type: ParamType;
17
+ /** Human-readable description of what this parameter does */
18
+ description?: string;
19
+ /** Whether this parameter is required (default: false) */
20
+ required?: boolean;
21
+ /** Default value for this parameter */
22
+ default?: unknown;
23
+ /** Allowed values for this parameter (for enum-like behavior) */
24
+ enum?: string[];
25
+ /** For array types, defines the type of array items */
26
+ items?: {
27
+ type: ParamType;
28
+ };
29
+ /** For object types, defines nested properties */
30
+ properties?: Record<string, ToolParam>;
31
+ }
32
+ /**
33
+ * Universal tool definition that can be converted to any provider format
34
+ *
35
+ * This is the core data contract. Changes to this interface require
36
+ * a MAJOR version bump per semantic versioning rules.
37
+ */
38
+ export interface UniversalTool {
39
+ /** Function/tool name - must be valid identifier */
40
+ name: string;
41
+ /** Human-readable description of what this tool does */
42
+ description: string;
43
+ /** Parameter definitions for this tool */
44
+ params: Record<string, ToolParam>;
45
+ }
46
+ /**
47
+ * Supported AI provider platforms
48
+ *
49
+ * Adding new providers requires:
50
+ * 1. Adding the provider name to this union type
51
+ * 2. Creating a new adapter in src/adapters/
52
+ * 3. Registering the adapter in src/index.ts
53
+ * 4. Adding test coverage
54
+ */
55
+ export type Provider = 'openai' | 'anthropic' | 'gemini' | 'mistral';
package/dist/types.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * Universal AI Tool Schema Adapter - Type Definitions
4
+ *
5
+ * This is the Single Source of Truth for the data contract.
6
+ * All adapters import from here to ensure consistency.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-tool-adapter",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Universal tool schema adapter for AI providers (OpenAI, Anthropic, Gemini, Mistral)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -10,7 +10,8 @@
10
10
  "scripts": {
11
11
  "build": "tsc",
12
12
  "prepublishOnly": "npm run build",
13
- "test": "echo \"Error: no test specified\" && exit 1"
13
+ "test": "vitest run",
14
+ "test:watch": "vitest"
14
15
  },
15
16
  "keywords": [
16
17
  "ai",
@@ -27,6 +28,7 @@
27
28
  "license": "ISC",
28
29
  "type": "commonjs",
29
30
  "devDependencies": {
30
- "typescript": "^5.0.0"
31
+ "typescript": "^5.0.0",
32
+ "vitest": "4.0.17"
31
33
  }
32
34
  }