@aquiles-ai/ishikawa-toolkit 1.2.0 → 1.4.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/README.md +125 -3
- package/dist/modules/compiler.d.ts.map +1 -1
- package/dist/modules/compiler.js +5 -1
- package/dist/modules/compiler.js.map +1 -1
- package/dist/modules/module.d.ts.map +1 -1
- package/dist/modules/module.js +7 -3
- package/dist/modules/module.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ npm i @aquiles-ai/ishikawa-toolkit
|
|
|
20
20
|
Create a file `calculator.ts`:
|
|
21
21
|
|
|
22
22
|
```typescript
|
|
23
|
-
export default function calculator(a: number
|
|
23
|
+
export default function calculator({a, b, operation}: {a: number; b: number; operation: string}) {
|
|
24
24
|
switch(operation) {
|
|
25
25
|
case 'add': return a + b;
|
|
26
26
|
case 'subtract': return a - b;
|
|
@@ -82,14 +82,136 @@ console.log(tool.metadata.description);
|
|
|
82
82
|
// Output: "Performs basic mathematical operations"
|
|
83
83
|
|
|
84
84
|
// Execute the tool
|
|
85
|
-
const result = await tool.execute(10, 5, 'add');
|
|
85
|
+
const result = await tool.execute({a: 10, b: 5, operation:'add'});
|
|
86
86
|
console.log(result); // Output: 15
|
|
87
87
|
|
|
88
88
|
// Or use shortcut
|
|
89
|
-
const result2 = await manager.
|
|
89
|
+
const result2 = await manager.executeTool('calculator', {a: 20, b: 4, operation: 'divide'});
|
|
90
90
|
console.log(result2); // Output: 5
|
|
91
91
|
|
|
92
92
|
// List all registered tools
|
|
93
93
|
const tools = await manager.list();
|
|
94
94
|
console.log(tools); // Output: ['calculator', ...]
|
|
95
95
|
```
|
|
96
|
+
## Using with Local LLMs
|
|
97
|
+
|
|
98
|
+
Ishikawa-toolkit works seamlessly with local LLM servers like vLLM. Here's how to set up function calling with a local model:
|
|
99
|
+
|
|
100
|
+
### 1. Start vLLM Server
|
|
101
|
+
|
|
102
|
+
Start your vLLM server with tool calling enabled:
|
|
103
|
+
```bash
|
|
104
|
+
vllm serve openai/gpt-oss-20b \
|
|
105
|
+
--served-model-name gpt-oss-20b \
|
|
106
|
+
--host 0.0.0.0 \
|
|
107
|
+
--port 8000 \
|
|
108
|
+
--async-scheduling \
|
|
109
|
+
--enable-auto-tool-choice \
|
|
110
|
+
--tool-call-parser openai \
|
|
111
|
+
--api-key dummyapikey
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 2. Implement the Agent Loop
|
|
115
|
+
|
|
116
|
+
Here's a complete example using the `calculator` tool from the Quick Start section:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import OpenAI from "openai";
|
|
120
|
+
import { ToolManager } from "@aquiles-ai/ishikawa-toolkit";
|
|
121
|
+
|
|
122
|
+
const client = new OpenAI({
|
|
123
|
+
baseURL: "http://localhost:8000/v1",
|
|
124
|
+
apiKey: "dummyapikey"
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const tools = new ToolManager();
|
|
128
|
+
const namesTools = await tools.listTools();
|
|
129
|
+
|
|
130
|
+
const allToolsMetadata = await Promise.all(
|
|
131
|
+
namesTools.map(async (toolName) => {
|
|
132
|
+
try {
|
|
133
|
+
return await tools.getMetadataTool(toolName);
|
|
134
|
+
} catch (error) {
|
|
135
|
+
console.error(`X Error cargando ${toolName}:`, error);
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const toolsMetadata = allToolsMetadata.filter(m => m !== null).map(m => ({
|
|
142
|
+
type: m.type,
|
|
143
|
+
name: m.name,
|
|
144
|
+
description: m.description,
|
|
145
|
+
parameters: m.parameters
|
|
146
|
+
}));
|
|
147
|
+
|
|
148
|
+
let input = [
|
|
149
|
+
{
|
|
150
|
+
role: "user",
|
|
151
|
+
content: "Can you validate the basic operations using the tool (The tool you need to use is the 'calculator', always use it)?"
|
|
152
|
+
},
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
let response = await client.responses.create({
|
|
156
|
+
model: "gpt-oss-20b",
|
|
157
|
+
tools: toolsMetadata,
|
|
158
|
+
input,
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// console.log("Response 1:", response);
|
|
162
|
+
|
|
163
|
+
for (const item of response.output) {
|
|
164
|
+
if (item.type == "function_call") {
|
|
165
|
+
const cleanName = item.name.split('<|')[0].trim();
|
|
166
|
+
|
|
167
|
+
if (namesTools.includes(cleanName)) {
|
|
168
|
+
console.log("Running the tool: " + cleanName);
|
|
169
|
+
|
|
170
|
+
let parsedArgs = {};
|
|
171
|
+
try {
|
|
172
|
+
parsedArgs = typeof item.arguments === "string"
|
|
173
|
+
? JSON.parse(item.arguments)
|
|
174
|
+
: item.arguments ?? {};
|
|
175
|
+
} catch (e) {
|
|
176
|
+
console.error("X Error parsing function arguments:", e);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
const result = await tools.executeTool(cleanName, parsedArgs);
|
|
181
|
+
console.log(`Result: ${result}`);
|
|
182
|
+
|
|
183
|
+
input.push({
|
|
184
|
+
...item,
|
|
185
|
+
name: cleanName
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
input.push({
|
|
189
|
+
type: "function_call_output",
|
|
190
|
+
call_id: item.call_id,
|
|
191
|
+
output: String(result),
|
|
192
|
+
});
|
|
193
|
+
} catch (err) {
|
|
194
|
+
console.error("X Tool execution error:", err);
|
|
195
|
+
input.push(item);
|
|
196
|
+
input.push({
|
|
197
|
+
type: "function_call_output",
|
|
198
|
+
call_id: item.call_id,
|
|
199
|
+
output: JSON.stringify({ error: String(err) }),
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const response2 = await client.responses.create({
|
|
207
|
+
model: "gpt-oss-20b",
|
|
208
|
+
instructions: "Answer based on the results obtained from the tool. What inputs did you provide and what output did you obtain?",
|
|
209
|
+
tools: toolsMetadata,
|
|
210
|
+
input: input,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
console.log("Final output:");
|
|
214
|
+
console.log(response2.output_text);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
For more models and parser options, see the [vLLM documentation](https://docs.vllm.ai/en/latest/features/tool_calling/).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/modules/compiler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/modules/compiler.ts"],"names":[],"mappings":"AAKA,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,iBAkBlD"}
|
package/dist/modules/compiler.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { build } from 'esbuild';
|
|
2
|
+
import { mkdir } from 'fs/promises';
|
|
3
|
+
import { join } from 'path';
|
|
2
4
|
export async function ToolCompiler(toolPath) {
|
|
3
5
|
try {
|
|
6
|
+
const distPath = join(toolPath, 'dist');
|
|
7
|
+
await mkdir(distPath, { recursive: true });
|
|
4
8
|
await build({
|
|
5
9
|
entryPoints: [toolPath + '/index.ts'],
|
|
6
|
-
outfile: toolPath
|
|
10
|
+
outfile: join(toolPath, 'dist', 'index.js'),
|
|
7
11
|
platform: 'node',
|
|
8
12
|
format: 'esm',
|
|
9
13
|
target: 'node18',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../src/modules/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../src/modules/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAG5B,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IAC/C,IAAI,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACxC,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3C,MAAM,KAAK,CAAC;YACR,WAAW,EAAE,CAAC,QAAQ,GAAG,WAAW,CAAC;YACrC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC;YAC3C,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,KAAK;SAChB,CAAC,CAAC;IACP,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;QAChD,MAAM,KAAK,CAAC;IAChB,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/modules/module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/modules/module.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,GAAG,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,UAAU;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,YAAY,CAC9B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,OAAO,EACrB,QAAQ,EAAE,MAAM,iBAsBnB;AA6CD,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAyDlE;AAED,wBAAsB,QAAQ,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAclD"}
|
package/dist/modules/module.js
CHANGED
|
@@ -4,10 +4,14 @@ import { exec } from 'child_process';
|
|
|
4
4
|
import { promisify } from 'util';
|
|
5
5
|
import { join } from 'path';
|
|
6
6
|
import { pathToFileURL } from 'url';
|
|
7
|
+
import envPaths from 'env-paths';
|
|
7
8
|
const execAsync = promisify(exec);
|
|
9
|
+
const paths = envPaths('Ishikawa-Toolkit', { suffix: '' });
|
|
10
|
+
const TOOLS_BASE_DIR = paths.data;
|
|
11
|
+
await mkdir(TOOLS_BASE_DIR, { recursive: true });
|
|
8
12
|
export async function ToolRegister(name, code_path, auto_install, json_llm) {
|
|
9
13
|
const metadata = await parseJsonInput(json_llm);
|
|
10
|
-
const toolPath = join(
|
|
14
|
+
const toolPath = join(TOOLS_BASE_DIR, 'tools', name);
|
|
11
15
|
await mkdir(toolPath, { recursive: true });
|
|
12
16
|
const targetCodePath = join(toolPath, 'index.ts');
|
|
13
17
|
await copyFile(code_path, targetCodePath);
|
|
@@ -57,7 +61,7 @@ async function installDependencies(toolPath) {
|
|
|
57
61
|
}
|
|
58
62
|
}
|
|
59
63
|
export async function ToolLoader(name) {
|
|
60
|
-
const toolPath = join(
|
|
64
|
+
const toolPath = join(TOOLS_BASE_DIR, 'tools', name);
|
|
61
65
|
// Step 1: Verify tool exists
|
|
62
66
|
try {
|
|
63
67
|
await access(toolPath);
|
|
@@ -108,7 +112,7 @@ export async function ToolLoader(name) {
|
|
|
108
112
|
};
|
|
109
113
|
}
|
|
110
114
|
export async function ToolList() {
|
|
111
|
-
const toolsDir = join(
|
|
115
|
+
const toolsDir = join(TOOLS_BASE_DIR, 'tools');
|
|
112
116
|
try {
|
|
113
117
|
const entries = await readdir(toolsDir, { withFileTypes: true });
|
|
114
118
|
const tools = entries
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/modules/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/modules/module.ts"],"names":[],"mappings":"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"}
|