@semantictools/ai-toolbox 0.1.0
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.
- package/LICENSE +190 -0
- package/README.md +778 -0
- package/package.json +38 -0
- package/src/toolmanager.mjs +605 -0
- package/src/translators/atfunc.mjs +450 -0
package/README.md
ADDED
|
@@ -0,0 +1,778 @@
|
|
|
1
|
+
# @semantictools/ai-toolbox
|
|
2
|
+
|
|
3
|
+
A flexible tool manager for managing and executing AI function calling toolboxes. This package provides a centralized system for registering, organizing, and executing functions that can be used with AI models supporting function calling (like Anthropic Claude, OpenAI GPT, etc.).
|
|
4
|
+
|
|
5
|
+
**Note:** This package uses a standardized interface format. See the [Interface Standard](#interface-standard) section below for detailed specifications.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Toolbox Registration**: Register multiple toolboxes with their own sets of functions
|
|
10
|
+
- **Hierarchical Organization**: Support for root toolboxes and namespaced function calls
|
|
11
|
+
- **Function Discovery**: List and find functions across all registered toolboxes
|
|
12
|
+
- **Flexible Calling**: Call functions using dot notation (e.g., `toolbox.function`)
|
|
13
|
+
- **Built-in Translators**: Production-ready translator included (`atfunc`) for AI text-based function calling
|
|
14
|
+
- **Custom Translators**: Support for custom function interface translators with configurable case sensitivity
|
|
15
|
+
- **Response Parsing**: Extract and execute function calls from AI model text responses
|
|
16
|
+
- **Control Functions**: Built-in introspection functions (domain: `tools`) for dynamic function discovery
|
|
17
|
+
- **Interface Validation**: Automatic validation of function interfaces during registration
|
|
18
|
+
- **Parameter Validation**: Runtime validation of required parameters with clear error messages
|
|
19
|
+
- **Statistics Tracking**: Monitor tool and function call counts
|
|
20
|
+
- **Result Truncation**: Configurable truncation for long function outputs
|
|
21
|
+
- **Standardized Interface**: Well-defined interface format for consistent toolbox development
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @semantictools/ai-toolbox
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
import {
|
|
33
|
+
register,
|
|
34
|
+
setRootToolBox,
|
|
35
|
+
setFunctionTranslator,
|
|
36
|
+
TRANSLATOR_ATFUNC,
|
|
37
|
+
call,
|
|
38
|
+
getFunctions,
|
|
39
|
+
executeResponseFunctions
|
|
40
|
+
} from '@semantictools/ai-toolbox';
|
|
41
|
+
|
|
42
|
+
// 1. Set up the built-in translator (do this first!)
|
|
43
|
+
setFunctionTranslator(TRANSLATOR_ATFUNC);
|
|
44
|
+
|
|
45
|
+
// 2. Create your toolbox
|
|
46
|
+
const myToolBox = {
|
|
47
|
+
getName: () => 'mytoolbox',
|
|
48
|
+
getFunction: (fname) => {
|
|
49
|
+
if (fname === 'greet') {
|
|
50
|
+
return {
|
|
51
|
+
f: async (args) => `Hello, ${args.name}!`,
|
|
52
|
+
interface: {
|
|
53
|
+
domain: 'mytoolbox', // Must match getName()
|
|
54
|
+
name: 'greet', // Lowercase, snake_case recommended
|
|
55
|
+
type: 'function', // 'function' or 'api-wrapper'
|
|
56
|
+
description: 'Greet a person by name',
|
|
57
|
+
params: { // Use 'params', not 'parameters'
|
|
58
|
+
name: {
|
|
59
|
+
type: 'string',
|
|
60
|
+
isRequired: true, // Use 'isRequired', not 'required'
|
|
61
|
+
description: 'Person\'s name'
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
returns: 'string'
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
},
|
|
70
|
+
functions: { greet: true }
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// 3. Register the toolbox
|
|
74
|
+
register(myToolBox);
|
|
75
|
+
setRootToolBox('mytoolbox');
|
|
76
|
+
|
|
77
|
+
// 4. Call functions
|
|
78
|
+
const result = await call('greet', { name: 'World' });
|
|
79
|
+
console.log(result); // "Hello, World!"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## API Reference
|
|
83
|
+
|
|
84
|
+
### Core Functions
|
|
85
|
+
|
|
86
|
+
#### `register(toolBox)`
|
|
87
|
+
Register a toolbox with the tool manager.
|
|
88
|
+
|
|
89
|
+
**Parameters:**
|
|
90
|
+
- `toolBox`: Object with `getName()`, `getFunction(fname)`, and `functions` property
|
|
91
|
+
|
|
92
|
+
#### `setRootToolBox(toolBoxName)`
|
|
93
|
+
Set the root toolbox (functions can be called without namespace prefix).
|
|
94
|
+
|
|
95
|
+
**Parameters:**
|
|
96
|
+
- `toolBoxName`: String name of the toolbox
|
|
97
|
+
|
|
98
|
+
#### `call(toolPath, args, truncateLength)`
|
|
99
|
+
Call a function by its path.
|
|
100
|
+
|
|
101
|
+
**Parameters:**
|
|
102
|
+
- `toolPath`: String in format `'function'` or `'toolbox.function'`
|
|
103
|
+
- `args`: Object with function arguments
|
|
104
|
+
- `truncateLength`: Optional number for result truncation (default: 5000)
|
|
105
|
+
|
|
106
|
+
**Returns:** Function result
|
|
107
|
+
|
|
108
|
+
#### `getFunctions(toolBoxName)`
|
|
109
|
+
Get list of all functions or functions in a specific toolbox.
|
|
110
|
+
|
|
111
|
+
**Parameters:**
|
|
112
|
+
- `toolBoxName`: Optional string to filter by toolbox
|
|
113
|
+
|
|
114
|
+
**Returns:** Array of function names
|
|
115
|
+
|
|
116
|
+
#### `findFunction(toolPath)`
|
|
117
|
+
Find a function by its path.
|
|
118
|
+
|
|
119
|
+
**Parameters:**
|
|
120
|
+
- `toolPath`: String in format `'function'` or `'toolbox.function'`
|
|
121
|
+
|
|
122
|
+
**Returns:** Function object with `f` (function) and `interface` properties
|
|
123
|
+
|
|
124
|
+
### Advanced Features
|
|
125
|
+
|
|
126
|
+
#### `setFunctionTranslator(converterObject)`
|
|
127
|
+
Set a custom function interface converter for AI model compatibility.
|
|
128
|
+
|
|
129
|
+
**Parameters:**
|
|
130
|
+
- `converterObject`: Translator object, translator name string, or translator constant (e.g., `TRANSLATOR_ATFUNC`)
|
|
131
|
+
|
|
132
|
+
**Examples:**
|
|
133
|
+
```javascript
|
|
134
|
+
// Option 1: Use translator constant (recommended)
|
|
135
|
+
import { setFunctionTranslator, TRANSLATOR_ATFUNC } from '@semantictools/ai-toolbox';
|
|
136
|
+
setFunctionTranslator(TRANSLATOR_ATFUNC);
|
|
137
|
+
|
|
138
|
+
// Option 2: Use translator name string
|
|
139
|
+
setFunctionTranslator('atfunc');
|
|
140
|
+
|
|
141
|
+
// Option 3: Load explicitly with getTranslator
|
|
142
|
+
const translator = getTranslator('atfunc');
|
|
143
|
+
setFunctionTranslator(translator);
|
|
144
|
+
|
|
145
|
+
// Option 4: Use custom translator object
|
|
146
|
+
import * as myTranslator from './my-translator.mjs';
|
|
147
|
+
setFunctionTranslator(myTranslator);
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### `getTranslator(name)`
|
|
151
|
+
Get a built-in standard translator by name.
|
|
152
|
+
|
|
153
|
+
**Parameters:**
|
|
154
|
+
- `name`: String name of the translator (e.g., `'atfunc'`)
|
|
155
|
+
|
|
156
|
+
**Returns:** Translator object with `generateFunctionIfText`, `getFunctionCallsFromText`, and `formatFunctionCallResults`
|
|
157
|
+
|
|
158
|
+
**Example:**
|
|
159
|
+
```javascript
|
|
160
|
+
import { getTranslator, setFunctionTranslator } from '@semantictools/ai-toolbox';
|
|
161
|
+
|
|
162
|
+
const translator = getTranslator('atfunc');
|
|
163
|
+
setFunctionTranslator(translator);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### `getStandardTranslatorList()`
|
|
167
|
+
Get list of all available built-in translators.
|
|
168
|
+
|
|
169
|
+
**Returns:** Array of translator names
|
|
170
|
+
|
|
171
|
+
**Example:**
|
|
172
|
+
```javascript
|
|
173
|
+
import { getStandardTranslatorList } from '@semantictools/ai-toolbox';
|
|
174
|
+
|
|
175
|
+
console.log(getStandardTranslatorList()); // ['atfunc']
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Translator Constants
|
|
179
|
+
|
|
180
|
+
The package exports constants for easy access to built-in translators:
|
|
181
|
+
|
|
182
|
+
- **`TRANSLATOR_ATFUNC`** - The atfunc production translator
|
|
183
|
+
|
|
184
|
+
**Example:**
|
|
185
|
+
```javascript
|
|
186
|
+
import { setFunctionTranslator, TRANSLATOR_ATFUNC } from '@semantictools/ai-toolbox';
|
|
187
|
+
|
|
188
|
+
// Most convenient way to set a built-in translator
|
|
189
|
+
setFunctionTranslator(TRANSLATOR_ATFUNC);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Control Functions
|
|
193
|
+
|
|
194
|
+
The toolmanager provides built-in control functions (domain: `tools`) for introspection and management. These are **registered by default** and can be called like any other function.
|
|
195
|
+
|
|
196
|
+
#### Available Control Functions
|
|
197
|
+
|
|
198
|
+
##### `tools.get_toolboxes()`
|
|
199
|
+
Get list of all registered toolboxes.
|
|
200
|
+
|
|
201
|
+
**Returns:** Array of toolbox names
|
|
202
|
+
|
|
203
|
+
##### `tools.get_functions(toolbox?)`
|
|
204
|
+
Get all functions, optionally filtered by toolbox.
|
|
205
|
+
|
|
206
|
+
**Parameters:**
|
|
207
|
+
- `toolbox` (optional): String - Filter by toolbox name
|
|
208
|
+
|
|
209
|
+
**Returns:** Array of function names
|
|
210
|
+
|
|
211
|
+
##### `tools.get_function_interface(function_name, separator?)`
|
|
212
|
+
Get the interface definition of a specific function as text.
|
|
213
|
+
|
|
214
|
+
**Parameters:**
|
|
215
|
+
- `function_name` (required): String - Full function name (e.g., "weather.get_temp")
|
|
216
|
+
- `separator` (optional): Boolean - Add visual separator
|
|
217
|
+
|
|
218
|
+
**Returns:** String with function interface in text format
|
|
219
|
+
|
|
220
|
+
##### `tools.set_truncate_length(length)`
|
|
221
|
+
Set the output truncation length for function results.
|
|
222
|
+
|
|
223
|
+
**Parameters:**
|
|
224
|
+
- `length` (required): Number - Truncation length in characters
|
|
225
|
+
|
|
226
|
+
**Returns:** Confirmation string
|
|
227
|
+
|
|
228
|
+
#### Managing Control Functions
|
|
229
|
+
|
|
230
|
+
```javascript
|
|
231
|
+
import {
|
|
232
|
+
registerControlFunctions,
|
|
233
|
+
unregisterControlFunctions,
|
|
234
|
+
registerControlFunction,
|
|
235
|
+
unregisterControlFunction
|
|
236
|
+
} from '@semantictools/ai-toolbox';
|
|
237
|
+
|
|
238
|
+
// Unregister all control functions
|
|
239
|
+
unregisterControlFunctions();
|
|
240
|
+
|
|
241
|
+
// Re-register all control functions
|
|
242
|
+
registerControlFunctions();
|
|
243
|
+
|
|
244
|
+
// Register individual control function
|
|
245
|
+
registerControlFunction('get_toolboxes');
|
|
246
|
+
|
|
247
|
+
// Unregister individual control function
|
|
248
|
+
unregisterControlFunction('get_toolboxes');
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### Usage Examples
|
|
252
|
+
|
|
253
|
+
**Direct calls:**
|
|
254
|
+
```javascript
|
|
255
|
+
const toolboxes = await call('tools.get_toolboxes');
|
|
256
|
+
const allFunctions = await call('tools.get_functions');
|
|
257
|
+
const weatherFunctions = await call('tools.get_functions', { toolbox: { value: 'weather' } });
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**AI text-based calls:**
|
|
261
|
+
```javascript
|
|
262
|
+
const aiResponse = `
|
|
263
|
+
@tools.get_toolboxes()
|
|
264
|
+
@tools.get_functions("weather")
|
|
265
|
+
`;
|
|
266
|
+
const result = await executeResponseFunctions(aiResponse);
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**Use cases:**
|
|
270
|
+
- Let AI discover available functions dynamically
|
|
271
|
+
- Allow AI to inspect function interfaces
|
|
272
|
+
- Enable AI to adjust truncation settings
|
|
273
|
+
- Debug and introspection during development
|
|
274
|
+
|
|
275
|
+
## Validation
|
|
276
|
+
|
|
277
|
+
The toolmanager includes comprehensive validation to catch errors early and provide clear error messages.
|
|
278
|
+
|
|
279
|
+
### Interface Validation
|
|
280
|
+
|
|
281
|
+
Function interfaces are automatically validated when toolboxes are registered. This catches configuration errors before runtime.
|
|
282
|
+
|
|
283
|
+
**What is validated:**
|
|
284
|
+
- Required fields: `domain`, `name`, `type`, `description`, `returns`
|
|
285
|
+
- `type` must be `'function'` or `'api-wrapper'`
|
|
286
|
+
- `domain` must match toolbox `getName()`
|
|
287
|
+
- Parameter structure: each param must have `type`, `isRequired`, `description`
|
|
288
|
+
- For API wrappers: validates `path_params`, `query_params` structure
|
|
289
|
+
|
|
290
|
+
**Example error:**
|
|
291
|
+
```javascript
|
|
292
|
+
const badToolbox = {
|
|
293
|
+
getName: () => 'weather',
|
|
294
|
+
getFunction: () => ({
|
|
295
|
+
f: async () => 'result',
|
|
296
|
+
interface: {
|
|
297
|
+
domain: 'wrong', // Doesn't match 'weather'
|
|
298
|
+
name: 'get_temp',
|
|
299
|
+
type: 'function',
|
|
300
|
+
// ... other fields
|
|
301
|
+
}
|
|
302
|
+
}),
|
|
303
|
+
functions: { get_temp: true }
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
register(badToolbox);
|
|
307
|
+
// Throws: "Validation failed for function 'get_temp' in toolbox 'weather':
|
|
308
|
+
// Interface domain 'wrong' does not match toolbox name 'weather'"
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Parameter Validation
|
|
312
|
+
|
|
313
|
+
Required parameters are validated at runtime when functions are called, providing immediate feedback.
|
|
314
|
+
|
|
315
|
+
**What is validated:**
|
|
316
|
+
- All parameters with `isRequired: true` must be present in function calls
|
|
317
|
+
- Validation happens in both `call()` and `executeResponseFunctions()`
|
|
318
|
+
- Clear error messages identify which parameters are missing
|
|
319
|
+
|
|
320
|
+
**Example error:**
|
|
321
|
+
```javascript
|
|
322
|
+
// Interface requires 'location' parameter
|
|
323
|
+
await call('weather.get_temp'); // Missing location
|
|
324
|
+
|
|
325
|
+
// Throws: "Missing required parameter for function 'weather.get_temp': location"
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Handling validation errors in AI responses:**
|
|
329
|
+
```javascript
|
|
330
|
+
const aiResponse = '@weather.get_temp()'; // Missing required param
|
|
331
|
+
const result = await executeResponseFunctions(aiResponse);
|
|
332
|
+
|
|
333
|
+
// Result includes validation error:
|
|
334
|
+
// "Function call: weather.get_temp()
|
|
335
|
+
// Returned: Error: Missing required parameter for function 'weather.get_temp': location"
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Benefits
|
|
339
|
+
|
|
340
|
+
✅ **Fail Fast** - Errors caught at registration/call time, not deep in execution
|
|
341
|
+
✅ **Clear Messages** - Know exactly what's wrong and where
|
|
342
|
+
✅ **Development Aid** - Catch typos and mistakes during development
|
|
343
|
+
✅ **Type Safety** - Ensure interfaces match expected structure
|
|
344
|
+
✅ **AI Safety** - Handle malformed AI function calls gracefully
|
|
345
|
+
|
|
346
|
+
#### `executeResponseFunctions(promptText)`
|
|
347
|
+
Parse and execute function calls from AI model response text.
|
|
348
|
+
|
|
349
|
+
**Parameters:**
|
|
350
|
+
- `promptText`: String containing function calls
|
|
351
|
+
|
|
352
|
+
**Returns:** Object with `functionsOutput` and `functionCalCount`
|
|
353
|
+
|
|
354
|
+
#### `getRootInterfaceAsText()`
|
|
355
|
+
Get all function interfaces as formatted text.
|
|
356
|
+
|
|
357
|
+
**Returns:** String with all function interface descriptions
|
|
358
|
+
|
|
359
|
+
#### `getStats()`
|
|
360
|
+
Get statistics on tool and function calls.
|
|
361
|
+
|
|
362
|
+
**Returns:** Object with `toolCalls` and `functionCalls` counts
|
|
363
|
+
|
|
364
|
+
#### `resetStats()`
|
|
365
|
+
Reset call statistics to zero.
|
|
366
|
+
|
|
367
|
+
## Toolbox Structure
|
|
368
|
+
|
|
369
|
+
A toolbox must implement:
|
|
370
|
+
|
|
371
|
+
```javascript
|
|
372
|
+
{
|
|
373
|
+
getName: () => 'toolbox-name',
|
|
374
|
+
getFunction: (functionName) => {
|
|
375
|
+
return {
|
|
376
|
+
f: async (args, truncateLength) => {
|
|
377
|
+
// Function implementation
|
|
378
|
+
return result;
|
|
379
|
+
},
|
|
380
|
+
interface: {
|
|
381
|
+
domain: 'toolbox-name', // Must match getName()
|
|
382
|
+
name: 'function_name', // Lowercase, use snake_case
|
|
383
|
+
type: 'function', // 'function' or 'api-wrapper'
|
|
384
|
+
description: 'What the function does',
|
|
385
|
+
params: { // Use 'params', not 'parameters'
|
|
386
|
+
param1: {
|
|
387
|
+
type: 'string',
|
|
388
|
+
isRequired: true, // Use 'isRequired', not 'required'
|
|
389
|
+
description: 'Parameter description'
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
returns: 'string' // or 'object', 'array', etc.
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
},
|
|
396
|
+
functions: {
|
|
397
|
+
'function_name': true
|
|
398
|
+
// ... list all available functions
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Important:** Case sensitivity is determined by your translator. The `atfunc` translator is case-insensitive (flexible for AI), while custom translators can be case-sensitive or case-insensitive based on their needs. See the [Case Sensitivity](#case-sensitivity) section for details.
|
|
404
|
+
|
|
405
|
+
## Interface Standard
|
|
406
|
+
|
|
407
|
+
### Function Interface Format
|
|
408
|
+
|
|
409
|
+
All function interfaces must follow this standardized structure:
|
|
410
|
+
|
|
411
|
+
```javascript
|
|
412
|
+
{
|
|
413
|
+
domain: 'toolbox-name', // The toolbox name (must match getName())
|
|
414
|
+
name: 'function_name', // Function name (lowercase, snake_case recommended)
|
|
415
|
+
type: 'function', // Type: 'function' or 'api-wrapper'
|
|
416
|
+
description: 'What the function does',
|
|
417
|
+
params: { // Function parameters (note: 'params', not 'parameters')
|
|
418
|
+
param_name: {
|
|
419
|
+
type: 'string' | 'number' | 'boolean' | 'object',
|
|
420
|
+
isRequired: true | false, // Note: 'isRequired', not 'required'
|
|
421
|
+
description: 'Parameter description'
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
returns: 'string' | 'number' | 'object' | 'array'
|
|
425
|
+
}
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
#### Required Fields
|
|
429
|
+
|
|
430
|
+
- **domain**: Must match the toolbox name from `getName()`
|
|
431
|
+
- **name**: Function name (lowercase, preferably snake_case)
|
|
432
|
+
- **type**: Either `'function'` or `'api-wrapper'`
|
|
433
|
+
- **description**: Clear description of what the function does
|
|
434
|
+
- **params**: Object containing parameter definitions
|
|
435
|
+
- **returns**: The return type of the function
|
|
436
|
+
|
|
437
|
+
#### Naming Conventions
|
|
438
|
+
|
|
439
|
+
Naming conventions depend on your translator's case sensitivity:
|
|
440
|
+
|
|
441
|
+
**For case-insensitive translators (like atfunc):**
|
|
442
|
+
- Use any casing style (camelCase, snake_case, PascalCase)
|
|
443
|
+
- `getCurrentWeather`, `get_current_weather`, or `GetCurrentWeather` all work
|
|
444
|
+
- Recommendation: Use snake_case for consistency with the text format
|
|
445
|
+
|
|
446
|
+
**For case-sensitive translators:**
|
|
447
|
+
- Use exact case matching
|
|
448
|
+
- `getCurrentWeather` ≠ `getcurrentweather`
|
|
449
|
+
- Choose a consistent style (camelCase or snake_case)
|
|
450
|
+
|
|
451
|
+
**General recommendations:**
|
|
452
|
+
- **Function names**: snake_case (e.g., `get_current_weather`)
|
|
453
|
+
- **Domain/toolbox names**: lowercase or PascalCase
|
|
454
|
+
- **Parameter names**: snake_case for consistency
|
|
455
|
+
|
|
456
|
+
#### API Wrapper Type
|
|
457
|
+
|
|
458
|
+
For `type: 'api-wrapper'`, additional fields are supported:
|
|
459
|
+
|
|
460
|
+
```javascript
|
|
461
|
+
{
|
|
462
|
+
domain: 'api',
|
|
463
|
+
name: 'get_user',
|
|
464
|
+
type: 'api-wrapper',
|
|
465
|
+
description: 'Get user information',
|
|
466
|
+
path_params: {
|
|
467
|
+
user_id: {
|
|
468
|
+
type: 'string',
|
|
469
|
+
isRequired: true,
|
|
470
|
+
description: 'User ID'
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
query_params: {
|
|
474
|
+
include_details: {
|
|
475
|
+
type: 'boolean',
|
|
476
|
+
isRequired: false,
|
|
477
|
+
description: 'Include detailed information'
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
request_body: {
|
|
481
|
+
field_name: {
|
|
482
|
+
type: 'string',
|
|
483
|
+
required: true,
|
|
484
|
+
description: 'Field description'
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
response_type: 'application/json',
|
|
488
|
+
returns: 'object'
|
|
489
|
+
}
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### Function Translator Interface
|
|
493
|
+
|
|
494
|
+
A translator enables text-based function calling for AI model integration. To create a translator, implement these three functions:
|
|
495
|
+
|
|
496
|
+
#### 1. `generateFunctionIfText(funcInterface, useSeparator)`
|
|
497
|
+
|
|
498
|
+
Converts a function interface to text format for AI consumption.
|
|
499
|
+
|
|
500
|
+
**Parameters:**
|
|
501
|
+
- `funcInterface`: The function interface object
|
|
502
|
+
- `useSeparator`: Boolean to add visual separator (optional)
|
|
503
|
+
|
|
504
|
+
**Returns:** String representation of the function
|
|
505
|
+
|
|
506
|
+
**Example Output:**
|
|
507
|
+
```
|
|
508
|
+
@weather.get_current_weather( <*location>, <unit> )
|
|
509
|
+
Description: Get current weather information for a location
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
#### 2. `getFunctionCallsFromText(text, interfaces, rootToolBox)`
|
|
513
|
+
|
|
514
|
+
Parses text to extract function calls.
|
|
515
|
+
|
|
516
|
+
**Parameters:**
|
|
517
|
+
- `text`: String containing function calls
|
|
518
|
+
- `interfaces`: Array of all available function interfaces
|
|
519
|
+
- `rootToolBox`: String name of root toolbox (can be null)
|
|
520
|
+
|
|
521
|
+
**Returns:** Array of function call objects:
|
|
522
|
+
```javascript
|
|
523
|
+
[
|
|
524
|
+
{
|
|
525
|
+
name: 'domain.function_name',
|
|
526
|
+
params: { param_name: value, ... },
|
|
527
|
+
interface: <matching interface object>
|
|
528
|
+
}
|
|
529
|
+
]
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
#### 3. `formatFunctionCallResults(functionCalls)`
|
|
533
|
+
|
|
534
|
+
Formats function execution results for display.
|
|
535
|
+
|
|
536
|
+
**Parameters:**
|
|
537
|
+
- `functionCalls`: Array of function call objects with results
|
|
538
|
+
|
|
539
|
+
**Returns:** Formatted string showing calls and results
|
|
540
|
+
|
|
541
|
+
### Text Format for Function Calls
|
|
542
|
+
|
|
543
|
+
When using a translator, functions are represented in this text format:
|
|
544
|
+
|
|
545
|
+
```
|
|
546
|
+
@domain.function_name( <*required_param>, <optional_param{type}> )
|
|
547
|
+
Description: What the function does
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
**Format Conventions:**
|
|
551
|
+
- `@` prefix indicates a function call
|
|
552
|
+
- `*` prefix on parameter means required
|
|
553
|
+
- `{type}` suffix shows non-string types (e.g., `{number}`, `{boolean}`)
|
|
554
|
+
- String types have no type suffix
|
|
555
|
+
- Optional `with_body [[ ]]` syntax for API wrappers with request bodies
|
|
556
|
+
|
|
557
|
+
**Examples:**
|
|
558
|
+
```
|
|
559
|
+
@weather.get_current_weather( <*location>, <unit> )
|
|
560
|
+
Description: Get current weather information for a location
|
|
561
|
+
|
|
562
|
+
@math.calculate_power( <*base{number}>, <*exponent{number}> )
|
|
563
|
+
Description: Calculate base raised to the power of exponent
|
|
564
|
+
|
|
565
|
+
@api.create_user( <*username>, <*email> ) with_body [[
|
|
566
|
+
{
|
|
567
|
+
"username": "john_doe",
|
|
568
|
+
"email": "john@example.com",
|
|
569
|
+
"age": 30
|
|
570
|
+
}
|
|
571
|
+
]]
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### Setting Up a Translator
|
|
575
|
+
|
|
576
|
+
#### Using a Built-in Translator (Recommended)
|
|
577
|
+
|
|
578
|
+
```javascript
|
|
579
|
+
import { setFunctionTranslator, TRANSLATOR_ATFUNC } from '@semantictools/ai-toolbox';
|
|
580
|
+
|
|
581
|
+
// Set translator BEFORE registering toolboxes (using constant)
|
|
582
|
+
setFunctionTranslator(TRANSLATOR_ATFUNC);
|
|
583
|
+
|
|
584
|
+
// Alternative: use translator name string
|
|
585
|
+
setFunctionTranslator('atfunc');
|
|
586
|
+
|
|
587
|
+
// Alternative: load explicitly
|
|
588
|
+
import { getTranslator, setFunctionTranslator } from '@semantictools/ai-toolbox';
|
|
589
|
+
const translator = getTranslator('atfunc');
|
|
590
|
+
setFunctionTranslator(translator);
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
#### Using a Custom Translator
|
|
594
|
+
|
|
595
|
+
```javascript
|
|
596
|
+
import * as translator from './my-translator.mjs';
|
|
597
|
+
import { setFunctionTranslator } from '@semantictools/ai-toolbox';
|
|
598
|
+
|
|
599
|
+
// Set translator BEFORE registering toolboxes
|
|
600
|
+
setFunctionTranslator(translator);
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
Your custom translator module must export:
|
|
604
|
+
|
|
605
|
+
```javascript
|
|
606
|
+
// Optional: Declare case sensitivity preference (default: true = case-sensitive)
|
|
607
|
+
export const caseSensitive = false;
|
|
608
|
+
|
|
609
|
+
export {
|
|
610
|
+
generateFunctionIfText,
|
|
611
|
+
getFunctionCallsFromText,
|
|
612
|
+
formatFunctionCallResults
|
|
613
|
+
};
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
**Case Sensitivity Property:**
|
|
617
|
+
- `caseSensitive: true` - Exact case matching required (default)
|
|
618
|
+
- `caseSensitive: false` - Case-insensitive matching (like atfunc)
|
|
619
|
+
- If not specified, defaults to `true` (case-sensitive)
|
|
620
|
+
|
|
621
|
+
### Case Sensitivity
|
|
622
|
+
|
|
623
|
+
Case sensitivity is **determined by the translator** you use:
|
|
624
|
+
|
|
625
|
+
- **Default (no translator set)**: Case-sensitive
|
|
626
|
+
- **atfunc translator**: Case-insensitive (handles AI text variability)
|
|
627
|
+
- **Custom translators**: Specify via `caseSensitive` property
|
|
628
|
+
|
|
629
|
+
**How it works:**
|
|
630
|
+
|
|
631
|
+
```javascript
|
|
632
|
+
// Custom translator with case sensitivity preference
|
|
633
|
+
export const caseSensitive = false; // or true
|
|
634
|
+
|
|
635
|
+
export function generateFunctionIfText(...) { ... }
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
When you set a translator with `setFunctionTranslator()`, the toolmanager automatically adapts to its case sensitivity preference.
|
|
639
|
+
|
|
640
|
+
**Examples:**
|
|
641
|
+
|
|
642
|
+
```javascript
|
|
643
|
+
// Using atfunc (case-insensitive)
|
|
644
|
+
setFunctionTranslator(TRANSLATOR_ATFUNC);
|
|
645
|
+
register(myToolbox); // getName() returns 'Weather'
|
|
646
|
+
|
|
647
|
+
// All of these work:
|
|
648
|
+
call('weather.getTemp');
|
|
649
|
+
call('Weather.getTemp');
|
|
650
|
+
call('WEATHER.GETTEMP');
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
```javascript
|
|
654
|
+
// Custom case-sensitive translator
|
|
655
|
+
const myTranslator = {
|
|
656
|
+
caseSensitive: true,
|
|
657
|
+
generateFunctionIfText: ...,
|
|
658
|
+
getFunctionCallsFromText: ...,
|
|
659
|
+
formatFunctionCallResults: ...
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
setFunctionTranslator(myTranslator);
|
|
663
|
+
register(myToolbox); // getName() returns 'Weather'
|
|
664
|
+
|
|
665
|
+
// Only exact case works:
|
|
666
|
+
call('Weather.getTemp'); // ✓ Works
|
|
667
|
+
call('weather.getTemp'); // ✗ Error
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
**Important:** Set the translator **before** registering toolboxes for the case sensitivity to apply correctly.
|
|
671
|
+
|
|
672
|
+
### Why This Standard?
|
|
673
|
+
|
|
674
|
+
The interface standard was designed with these principles:
|
|
675
|
+
|
|
676
|
+
1. **Translator-Driven Case Handling**: Each translator declares its case sensitivity needs, toolmanager adapts
|
|
677
|
+
2. **AI Compatibility**: Text-based format enables natural integration with LLM function calling
|
|
678
|
+
3. **Consistency**: Standardized structure across all toolboxes improves maintainability
|
|
679
|
+
4. **Extensibility**: Supports both simple functions and complex API wrappers
|
|
680
|
+
5. **Type Safety**: Explicit type definitions help with parameter validation and conversion
|
|
681
|
+
6. **Production Tested**: Based on real-world implementations in production systems
|
|
682
|
+
|
|
683
|
+
### Reference Implementation
|
|
684
|
+
|
|
685
|
+
The `atfunc` translator is included as a built-in standard translator. You can use it directly with:
|
|
686
|
+
|
|
687
|
+
```javascript
|
|
688
|
+
import { setFunctionTranslator, TRANSLATOR_ATFUNC } from '@semantictools/ai-toolbox';
|
|
689
|
+
|
|
690
|
+
setFunctionTranslator(TRANSLATOR_ATFUNC);
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
This production-ready translator supports:
|
|
694
|
+
- Both `function` and `api-wrapper` types
|
|
695
|
+
- Type conversion (string, number, boolean, object)
|
|
696
|
+
- Quote and escape sequence handling
|
|
697
|
+
- Multi-line request bodies with `with_body [[ ]]` syntax
|
|
698
|
+
- Path parameters, query parameters, and request bodies
|
|
699
|
+
|
|
700
|
+
The complete interface specification is documented in this README. The reference implementation is available as a built-in translator accessible via `TRANSLATOR_ATFUNC`.
|
|
701
|
+
|
|
702
|
+
## Migration Guide
|
|
703
|
+
|
|
704
|
+
If you have existing code using the old interface format, here's how to migrate:
|
|
705
|
+
|
|
706
|
+
### Old Format (deprecated)
|
|
707
|
+
```javascript
|
|
708
|
+
interface: {
|
|
709
|
+
name: 'getCurrentWeather',
|
|
710
|
+
description: 'Get current weather',
|
|
711
|
+
parameters: {
|
|
712
|
+
location: {
|
|
713
|
+
type: 'string',
|
|
714
|
+
required: true,
|
|
715
|
+
description: 'City name'
|
|
716
|
+
}
|
|
717
|
+
},
|
|
718
|
+
returns: 'object'
|
|
719
|
+
}
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
### New Format (standardized)
|
|
723
|
+
```javascript
|
|
724
|
+
interface: {
|
|
725
|
+
domain: 'weather', // ← Add domain (must match toolbox name)
|
|
726
|
+
name: 'get_current_weather', // ← Lowercase with underscores
|
|
727
|
+
type: 'function', // ← Add type
|
|
728
|
+
description: 'Get current weather',
|
|
729
|
+
params: { // ← Changed from 'parameters'
|
|
730
|
+
location: {
|
|
731
|
+
type: 'string',
|
|
732
|
+
isRequired: true, // ← Changed from 'required'
|
|
733
|
+
description: 'City name'
|
|
734
|
+
}
|
|
735
|
+
},
|
|
736
|
+
returns: 'object'
|
|
737
|
+
}
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
**Key Changes:**
|
|
741
|
+
1. Add `domain` field matching your toolbox name
|
|
742
|
+
2. Add `type` field (`'function'` or `'api-wrapper'`)
|
|
743
|
+
3. Convert function names to lowercase snake_case
|
|
744
|
+
4. Rename `parameters` to `params`
|
|
745
|
+
5. Rename `required` to `isRequired`
|
|
746
|
+
|
|
747
|
+
## Examples
|
|
748
|
+
|
|
749
|
+
See the [examples](./examples) directory for complete working examples using the standardized interface:
|
|
750
|
+
|
|
751
|
+
- [Basic Usage](./examples/basic.mjs) - Simple toolbox registration and function calls
|
|
752
|
+
- [Multiple Toolboxes](./examples/multiple-toolboxes.mjs) - Working with multiple toolboxes
|
|
753
|
+
- [AI Integration](./examples/ai-integration.mjs) - Full AI integration with translator
|
|
754
|
+
- [Simple Translator](./examples/simple-translator.mjs) - Basic translator implementation
|
|
755
|
+
|
|
756
|
+
**Built-in Translator:**
|
|
757
|
+
The `atfunc` translator is included as a built-in and can be used via the `TRANSLATOR_ATFUNC` constant or by name (`'atfunc'`). See the source at [src/translators/atfunc.mjs](./src/translators/atfunc.mjs).
|
|
758
|
+
|
|
759
|
+
## Use Cases
|
|
760
|
+
|
|
761
|
+
- **AI Function Calling**: Provide tools for Claude, GPT, or other AI models
|
|
762
|
+
- **Plugin Systems**: Create extensible plugin architectures
|
|
763
|
+
- **Service Orchestration**: Manage and call multiple service APIs
|
|
764
|
+
- **Workflow Automation**: Build flexible automation toolchains
|
|
765
|
+
|
|
766
|
+
## License
|
|
767
|
+
|
|
768
|
+
Apache-2.0
|
|
769
|
+
|
|
770
|
+
Copyright 2026 Dusty Wilhelm Murray / Semantic Tools
|
|
771
|
+
|
|
772
|
+
## Contributing
|
|
773
|
+
|
|
774
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
775
|
+
|
|
776
|
+
## Author
|
|
777
|
+
|
|
778
|
+
Dusty Wilhelm Murray / Semantic Tools
|