@sisu-ai/mw-tool-calling 2.0.0 → 3.0.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 +68 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.js +55 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -11,16 +11,76 @@ npm i @sisu-ai/mw-tool-calling
|
|
|
11
11
|
Discover what you can do through examples or documentation. Check it out at https://github.com/finger-gun/sisu
|
|
12
12
|
|
|
13
13
|
## Behavior
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
-
|
|
14
|
+
- `toolCalling`: single-round tool calling.
|
|
15
|
+
- First turn: calls `ctx.model.generate(messages, { tools, toolChoice:'auto' })`.
|
|
16
|
+
- If assistant returns `tool_calls`, appends the assistant message and executes each tool.
|
|
17
|
+
- Executes each unique `(name, args)` once and responds to every `tool_call_id`.
|
|
18
|
+
- Handles provider quirks by reusing last args for identical tool names with missing args.
|
|
19
|
+
- Second turn: asks for a pure completion (`toolChoice:'none'`).
|
|
20
|
+
```mermaid
|
|
21
|
+
sequenceDiagram
|
|
22
|
+
autonumber
|
|
23
|
+
participant A as Agent toolCalling
|
|
24
|
+
participant M as Model Adapter
|
|
25
|
+
participant R as Tools Registry
|
|
26
|
+
participant H as Tool Handler
|
|
27
|
+
|
|
28
|
+
A->>R: list
|
|
29
|
+
R-->>A: tools
|
|
30
|
+
A->>M: generate with tools auto
|
|
31
|
+
alt tool calls
|
|
32
|
+
M-->>A: assistant with tool calls
|
|
33
|
+
loop each unique name args
|
|
34
|
+
A->>R: resolve and validate
|
|
35
|
+
R-->>A: handler
|
|
36
|
+
A->>H: execute
|
|
37
|
+
H-->>A: append tool message
|
|
38
|
+
end
|
|
39
|
+
A->>M: generate finalize none
|
|
40
|
+
M-->>A: assistant completion
|
|
41
|
+
else no tool calls
|
|
42
|
+
M-->>A: assistant completion
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
- `iterativeToolCalling`: multi-round tool calling.
|
|
47
|
+
- Repeats calls with `toolChoice:'auto'` until the model returns a message with no `tool_calls` (max 12 iters).
|
|
48
|
+
|
|
49
|
+
```mermaid
|
|
50
|
+
sequenceDiagram
|
|
51
|
+
autonumber
|
|
52
|
+
participant A as Agent iterativeToolCalling
|
|
53
|
+
participant M as Model Adapter
|
|
54
|
+
participant R as Tools Registry
|
|
55
|
+
participant H as Tool Handler
|
|
56
|
+
|
|
57
|
+
A->>R: list
|
|
58
|
+
R-->>A: tools
|
|
59
|
+
loop max twelve iterations until no tool calls
|
|
60
|
+
A->>M: generate with tools auto
|
|
61
|
+
alt tool calls present
|
|
62
|
+
M-->>A: assistant with tool calls
|
|
63
|
+
loop each unique name args
|
|
64
|
+
A->>R: resolve and validate
|
|
65
|
+
R-->>A: handler
|
|
66
|
+
A->>H: execute
|
|
67
|
+
H-->>A: append tool message
|
|
68
|
+
end
|
|
69
|
+
else no tool calls
|
|
70
|
+
M-->>A: assistant no tools
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
A->>M: generate finalize none
|
|
74
|
+
M-->>A: assistant completion
|
|
75
|
+
```
|
|
19
76
|
|
|
20
77
|
## Usage
|
|
21
78
|
```ts
|
|
22
|
-
import { toolCalling } from '@sisu-ai/mw-tool-calling';
|
|
79
|
+
import { toolCalling, iterativeToolCalling } from '@sisu-ai/mw-tool-calling';
|
|
80
|
+
|
|
81
|
+
// Single-round
|
|
82
|
+
agent.use(toolCalling);
|
|
23
83
|
|
|
24
|
-
|
|
25
|
-
|
|
84
|
+
// OR multi-round
|
|
85
|
+
agent.use(iterativeToolCalling);
|
|
26
86
|
```
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -61,6 +61,61 @@ export const toolCalling = async (ctx, next) => {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
|
+
export const iterativeToolCalling = async (ctx, next) => {
|
|
65
|
+
await next();
|
|
66
|
+
const maxIters = 12;
|
|
67
|
+
for (let i = 0; i < maxIters; i++) {
|
|
68
|
+
ctx.log.debug?.('[iterative-tool-calling] iteration start', { i, messages: ctx.messages.length });
|
|
69
|
+
const toolList = ctx.tools.list();
|
|
70
|
+
const genOpts = { toolChoice: 'auto', tools: toolList, parallelToolCalls: false, signal: ctx.signal };
|
|
71
|
+
const out = await ctx.model.generate(ctx.messages, genOpts);
|
|
72
|
+
const msg = out.message;
|
|
73
|
+
const toolCalls = msg.tool_calls;
|
|
74
|
+
if (toolCalls && toolCalls.length > 0) {
|
|
75
|
+
// include the assistant message that requested tools
|
|
76
|
+
ctx.messages.push(msg);
|
|
77
|
+
ctx.log.info?.('[iterative-tool-calling] model requested tools', toolCalls.map(tc => ({ id: tc.id, name: tc.name, hasArgs: typeof tc.arguments !== 'undefined' })));
|
|
78
|
+
const cache = new Map();
|
|
79
|
+
const keyOf = (tc) => `${tc.name}:${safeStableStringify(tc.arguments)}`;
|
|
80
|
+
const lastArgsByName = new Map();
|
|
81
|
+
const resolvedCalls = toolCalls.map((tc) => {
|
|
82
|
+
if (typeof tc.arguments === 'undefined' && lastArgsByName.has(tc.name)) {
|
|
83
|
+
return { ...tc, arguments: lastArgsByName.get(tc.name) };
|
|
84
|
+
}
|
|
85
|
+
return tc;
|
|
86
|
+
});
|
|
87
|
+
for (const call of resolvedCalls) {
|
|
88
|
+
const tool = ctx.tools.get(call.name);
|
|
89
|
+
if (!tool)
|
|
90
|
+
throw new Error('Unknown tool: ' + call.name);
|
|
91
|
+
const key = keyOf(call);
|
|
92
|
+
let result = cache.get(key);
|
|
93
|
+
if (result === undefined) {
|
|
94
|
+
const args = tool.schema?.parse ? tool.schema.parse(call.arguments) : call.arguments;
|
|
95
|
+
ctx.log.debug?.('[iterative-tool-calling] invoking tool', { name: call.name, id: call.id, args });
|
|
96
|
+
result = await tool.handler(args, ctx);
|
|
97
|
+
cache.set(key, result);
|
|
98
|
+
lastArgsByName.set(call.name, args);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
ctx.log.debug?.('[iterative-tool-calling] reusing cached result', { name: call.name, id: call.id });
|
|
102
|
+
}
|
|
103
|
+
const toolMsg = { role: 'tool', content: JSON.stringify(result) };
|
|
104
|
+
if (call.id)
|
|
105
|
+
toolMsg.tool_call_id = call.id;
|
|
106
|
+
else
|
|
107
|
+
toolMsg.name = call.name;
|
|
108
|
+
ctx.messages.push(toolMsg);
|
|
109
|
+
}
|
|
110
|
+
continue; // next round may call more tools
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
ctx.log.info?.('[iterative-tool-calling] no tool calls; appending assistant message');
|
|
114
|
+
ctx.messages.push(msg);
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
64
119
|
function safeStableStringify(v) {
|
|
65
120
|
try {
|
|
66
121
|
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sisu-ai/mw-tool-calling",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"build": "tsc -b"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"@sisu-ai/core": "0.
|
|
17
|
+
"@sisu-ai/core": "1.0.0"
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|