@ai-sdk-tool/parser 2.1.1 → 2.1.2

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 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
+ [![npm](https://img.shields.io/npm/v/@ai-sdk-tool/parser)](https://www.npmjs.com/package/@ai-sdk-tool/parser)
6
+ [![npm](https://img.shields.io/npm/dt/@ai-sdk-tool/parser)](https://www.npmjs.com/package/@ai-sdk-tool/parser)
7
+ [![codecov](https://codecov.io/gh/minpeter/ai-sdk-tool-call-middleware/branch/main/graph/badge.svg)](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.