tune-basic-toolset 0.1.16 → 0.1.18
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
CHANGED
|
@@ -20,7 +20,8 @@ Basic toolset for [Tune](https://github.com/iovdin/tune).
|
|
|
20
20
|
- [list](#list) keep list of tasks todo (loops for LLM)
|
|
21
21
|
- [sqlite](#sqlite) execute sqlite queries
|
|
22
22
|
- [py](#py) run python code
|
|
23
|
-
- [
|
|
23
|
+
- [js_node](#js_node) run javascript code in node process
|
|
24
|
+
- [js_ctx](#js_ctx) run javascript code that shares context with LLM
|
|
24
25
|
- [turn](#turn) handoff based agent (shared context)
|
|
25
26
|
- [message](#message) talk to another chat/agent (separate context)
|
|
26
27
|
- [Processors](#processors)
|
|
@@ -350,10 +351,10 @@ tool_result:
|
|
|
350
351
|
5545
|
|
351
352
|
```
|
|
352
353
|
|
|
353
|
-
### `
|
|
354
|
-
execute javascript code
|
|
354
|
+
### `js_node`
|
|
355
|
+
execute javascript code in nodejs
|
|
355
356
|
```chat
|
|
356
|
-
user: @
|
|
357
|
+
user: @js_node
|
|
357
358
|
1234 + 4311
|
|
358
359
|
|
|
359
360
|
tool_call: js {"inputType":"commonjs"}
|
|
@@ -364,6 +365,90 @@ tool_result:
|
|
|
364
365
|
|
|
365
366
|
```
|
|
366
367
|
|
|
368
|
+
### `js_ctx`
|
|
369
|
+
execute javascript code but also call tools available to llm or trigger LLM response from code
|
|
370
|
+
It is useful when you need to trigger loops and ifs or chain few tool calls together
|
|
371
|
+
```chat
|
|
372
|
+
user:
|
|
373
|
+
@js_ctx @sh
|
|
374
|
+
|
|
375
|
+
what is in my current directory?
|
|
376
|
+
|
|
377
|
+
tool_call: sh
|
|
378
|
+
ls
|
|
379
|
+
tool_result:
|
|
380
|
+
__pycache__
|
|
381
|
+
append.schema.json
|
|
382
|
+
append.tool.js
|
|
383
|
+
... file list
|
|
384
|
+
|
|
385
|
+
user:
|
|
386
|
+
can you do the same using js_ctx tool?
|
|
387
|
+
|
|
388
|
+
assistant:
|
|
389
|
+
|
|
390
|
+
tool_call: js_ctx
|
|
391
|
+
|
|
392
|
+
const result = await ctx.exec("sh", { text: "ls" });
|
|
393
|
+
return result;
|
|
394
|
+
|
|
395
|
+
tool_result:
|
|
396
|
+
__pycache__
|
|
397
|
+
append.schema.json
|
|
398
|
+
append.tool.js
|
|
399
|
+
....
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
Now we can loop trough all the files and summarize its content
|
|
404
|
+
```
|
|
405
|
+
user:
|
|
406
|
+
can you loop throught the .js files and summarize its content using llm?
|
|
407
|
+
assistant:
|
|
408
|
+
|
|
409
|
+
tool_call: js_ctx
|
|
410
|
+
|
|
411
|
+
// Get all .js files (excluding .proc.js and .schema.json files)
|
|
412
|
+
const files = await ctx.exec("sh", { text: "ls *.js | grep -v '.proc.js'" });
|
|
413
|
+
const jsFiles = files.trim().split('\n').filter(f => f.endsWith('.js'));
|
|
414
|
+
|
|
415
|
+
const summaries = [];
|
|
416
|
+
|
|
417
|
+
// Loop through each .js file
|
|
418
|
+
for (const file of jsFiles) {
|
|
419
|
+
// Read the file content
|
|
420
|
+
const content = await ctx.exec("sh", { text: `cat ${file}` });
|
|
421
|
+
|
|
422
|
+
// Use LLM to summarize
|
|
423
|
+
const summary = await ctx.file2run({
|
|
424
|
+
system: "@mistral-tiny You are a code analyst. Provide a brief 1-2 sentence summary of what this JavaScript file does.",
|
|
425
|
+
user: "Summarize this code:\n\n@code"
|
|
426
|
+
}, {
|
|
427
|
+
code: content
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
summaries.push({
|
|
431
|
+
file: file,
|
|
432
|
+
summary: summary.trim()
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Format and return results
|
|
437
|
+
return summaries.map(s => `**${s.file}**\n${s.summary}\n`).join('\n');
|
|
438
|
+
|
|
439
|
+
tool_result:
|
|
440
|
+
**append.tool.js**
|
|
441
|
+
This JavaScript file exports an asynchronous function that appends the given text to the end of a specified file, and returns "done" once the operation is completed.
|
|
442
|
+
|
|
443
|
+
**cmd.tool.js**
|
|
444
|
+
This JavaScript file exports an asynchronous function `cmd` that executes a system command (Windows-specific, using 'cmd.exe' as the shell) passed as a string, and returns the command's output or an error message containing both stderr and stdout.
|
|
445
|
+
|
|
446
|
+
**grep.tool.js**
|
|
447
|
+
This JavaScript module exports an asynchronous function named `grep` that reads a file (if provided) or a provided text and searches for lines matching a given regular expression. It returns the lines that match, separated by newlines. If the file is not found or the content is empty, it returns appropriate error messages.
|
|
448
|
+
....
|
|
449
|
+
|
|
450
|
+
```
|
|
451
|
+
|
|
367
452
|
### `turn`
|
|
368
453
|
A way to switch roles when building multistep agents [read more](https://iovdin.github.io/tune/examples/multi-agent)
|
|
369
454
|
```chat
|
package/package.json
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "run js code",
|
|
3
|
+
"parameters": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"text": {
|
|
7
|
+
"type": "string",
|
|
8
|
+
"description": "js code to execute. You can use 'ctx' inside code to call tools available, e.g. await ctx.exec(\"tool_name\", { param: value }), it is also possible to call LLM from code: await ctx.file2run({ system: \"You are helpful assistant\" user: \"user request: @data \" }, { data: \"value of template variable\") to proper escape user input file2run template engine instead of javascripts ${}"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"required": ["text"]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const { parseScript } = require('esprima');
|
|
2
|
+
const { generate } = require('escodegen');
|
|
3
|
+
const vm = require('node:vm');
|
|
4
|
+
module.exports = async function js({ text }, ctx) {
|
|
5
|
+
|
|
6
|
+
let code = `(async () =>{\n${text}\n})()`
|
|
7
|
+
const ast = parseScript(code, { range: true });
|
|
8
|
+
|
|
9
|
+
const bodyAst = ast.body[ast.body.length - 1].expression.callee.body;
|
|
10
|
+
const lastNode = bodyAst.body[bodyAst.body.length - 1];
|
|
11
|
+
|
|
12
|
+
if (lastNode.type === 'ExpressionStatement') {
|
|
13
|
+
bodyAst.body[bodyAst.body.length - 1] = {
|
|
14
|
+
type: 'ReturnStatement',
|
|
15
|
+
argument: lastNode.expression
|
|
16
|
+
}
|
|
17
|
+
code = generate(ast);
|
|
18
|
+
}
|
|
19
|
+
if (bodyAst.length === 0) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let logs = [];
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
let result = vm.runInContext(code, vm.createContext({
|
|
27
|
+
ctx,
|
|
28
|
+
console: {
|
|
29
|
+
log: (...args) => logs.push(args),
|
|
30
|
+
error: (...args) => logs.push(args),
|
|
31
|
+
warn: (...args) => logs.push(args),
|
|
32
|
+
debug: (...args) => logs.push(args),
|
|
33
|
+
}
|
|
34
|
+
}))
|
|
35
|
+
result = await result
|
|
36
|
+
return result
|
|
37
|
+
if (typeof(result) === "object") {
|
|
38
|
+
result = JSON.stringify(result, null, " ")
|
|
39
|
+
} else {
|
|
40
|
+
result = String(result)
|
|
41
|
+
}
|
|
42
|
+
logs = logs.map(log => log.join(" ")).join("\n")
|
|
43
|
+
result = logs.trim() + "\n" + (result || "").trim()
|
|
44
|
+
return result.trim()
|
|
45
|
+
} catch (e) {
|
|
46
|
+
return e.stack
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/turn.schema.json
CHANGED
package/src/wf.tool.js
CHANGED
|
File without changes
|