@ai-sdk-tool/parser 2.1.1 → 2.1.3
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 +129 -0
- package/dist/index.cjs +1688 -963
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -14
- package/dist/index.d.ts +15 -14
- package/dist/index.js +1687 -958
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# AI SDK - tool call parser middleware
|
|
2
|
+
|
|
3
|
+
▲ Also available in the Vercel AI SDK official documentation: [Custom tool call parser](https://ai-sdk.dev/docs/ai-sdk-core/middleware#custom-tool-call-parser)
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@ai-sdk-tool/parser)
|
|
6
|
+
[](https://www.npmjs.com/package/@ai-sdk-tool/parser)
|
|
7
|
+
[](https://codecov.io/gh/minpeter/ai-sdk-tool-call-middleware)
|
|
8
|
+
|
|
9
|
+
> [!NOTE]
|
|
10
|
+
> Requires AI SDK v5. For AI SDK v4, pin `@ai-sdk-tool/parser@1.0.0`.
|
|
11
|
+
|
|
12
|
+
Middleware that enables tool calling with models that don’t natively support OpenAI‑style `tools`. Works with any provider (OpenRouter, vLLM, Ollama, etc.) via AI SDK middleware.
|
|
13
|
+
|
|
14
|
+
## Why This Exists
|
|
15
|
+
|
|
16
|
+
Many self‑hosted or third‑party model endpoints (vLLM, MLC‑LLM, Ollama, OpenRouter, etc.) don’t yet expose the OpenAI‑style `tools` parameter, forcing you to hack together tool parsing.
|
|
17
|
+
This project provides a flexible middleware that:
|
|
18
|
+
|
|
19
|
+
- Parses tool calls from streaming or batch responses
|
|
20
|
+
- Prebuilt protocols: JSON‑mix (Gemma/Hermes‑style) and Morph‑XML
|
|
21
|
+
- Full control over the tool call system prompt
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm add @ai-sdk-tool/parser
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quickstart (streaming)
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
|
|
33
|
+
import { wrapLanguageModel, stepCountIs, streamText } from "ai";
|
|
34
|
+
import { gemmaToolMiddleware } from "@ai-sdk-tool/parser";
|
|
35
|
+
|
|
36
|
+
const openrouter = createOpenAICompatible({
|
|
37
|
+
/* ... */
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
async function main() {
|
|
41
|
+
const result = streamText({
|
|
42
|
+
model: wrapLanguageModel({
|
|
43
|
+
model: openrouter("google/gemma-3-27b-it"),
|
|
44
|
+
middleware: gemmaToolMiddleware,
|
|
45
|
+
}),
|
|
46
|
+
system: "You are a helpful assistant.",
|
|
47
|
+
prompt: "What is the weather in my city?",
|
|
48
|
+
stopWhen: stepCountIs(4),
|
|
49
|
+
tools: {
|
|
50
|
+
get_location: {
|
|
51
|
+
/* ... */
|
|
52
|
+
},
|
|
53
|
+
get_weather: {
|
|
54
|
+
/* ... */
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
for await (const part of result.fullStream) {
|
|
60
|
+
// handle text/tool events
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
main().catch(console.error);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Quickstart (generate)
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
|
|
71
|
+
import { wrapLanguageModel, generateText } from "ai";
|
|
72
|
+
import { hermesToolMiddleware } from "@ai-sdk-tool/parser";
|
|
73
|
+
|
|
74
|
+
const openrouter = createOpenAICompatible({
|
|
75
|
+
/* ... */
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
async function main() {
|
|
79
|
+
const { text } = await generateText({
|
|
80
|
+
model: wrapLanguageModel({
|
|
81
|
+
model: openrouter("nousresearch/hermes-3-llama-3.1-70b"),
|
|
82
|
+
middleware: hermesToolMiddleware,
|
|
83
|
+
}),
|
|
84
|
+
prompt: "Find weather for Seoul today",
|
|
85
|
+
tools: {
|
|
86
|
+
get_weather: {
|
|
87
|
+
/* ... */
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
console.log(text);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
main().catch(console.error);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Prebuilt middlewares
|
|
99
|
+
|
|
100
|
+
- `gemmaToolMiddleware` — JSON‑mix format inside markdown fences (markdown code fences)
|
|
101
|
+
- `hermesToolMiddleware` — JSON‑mix format wrapped in `<tool_call>` XML tags.
|
|
102
|
+
- `xmlToolMiddleware` — XML format (Morph‑XML protocol).
|
|
103
|
+
|
|
104
|
+
## Protocols
|
|
105
|
+
|
|
106
|
+
- `jsonMixProtocol` — JSON function calls in flexible text wrappers.
|
|
107
|
+
- `morphXmlProtocol` — XML element per call, robust to streaming.
|
|
108
|
+
|
|
109
|
+
## Tool choice support
|
|
110
|
+
|
|
111
|
+
- `toolChoice: { type: "required" }`: forces one tool call. Middleware sets a JSON response schema to validate calls.
|
|
112
|
+
- `toolChoice: { type: "tool", toolName }`: forces a specific tool. Provider‑defined tools are not supported; pass only custom function tools.
|
|
113
|
+
- `toolChoice: { type: "none" }` is not supported and will throw.
|
|
114
|
+
|
|
115
|
+
## Examples
|
|
116
|
+
|
|
117
|
+
See `examples/parser-core/src/*` for runnable demos (streaming/non‑streaming, tool choice).
|
|
118
|
+
|
|
119
|
+
## [dev] Contributor notes
|
|
120
|
+
|
|
121
|
+
- Exported API: `createToolMiddleware`, `gemmaToolMiddleware`, `hermesToolMiddleware`, `xmlToolMiddleware`, `jsonMixProtocol`, `morphXmlProtocol`.
|
|
122
|
+
- Debugging:
|
|
123
|
+
- Set `DEBUG_PARSER_MW=stream` to log raw/parsed chunks during runs.
|
|
124
|
+
- Set `DEBUG_PARSER_MW=parse` to log original matched text and parsed summary.
|
|
125
|
+
- Optional `DEBUG_PARSER_MW_STYLE=bg|inverse|underline|bold` to change highlight style.
|
|
126
|
+
- Provider options passthrough: `providerOptions.toolCallMiddleware` fields are merged into protocol options. Internal fields used:
|
|
127
|
+
- `toolNames`: internal propagation of custom tool names.
|
|
128
|
+
- `toolChoice`: internal fast‑path activation for required/specific tool modes.
|
|
129
|
+
- Transform details: `transformParams` injects a system message built from protocol `formatTools` and clears `tools` since many providers strip/ignore them.
|