Skip to content

Commit 52d5fa9

Browse files
authored
feat: add toolkit create reasoning tools (#41)
* feat: add toolkit and createReasoningTools * chore: add issue number * refactor: update agent and tool management methods * refactor: rename addTools to addItems and update hook execution syntax * fix: update link to VoltAgent Developer Console in reasoning-tool documentation * feat: enhance agent responses with automatic Markdown formatting and update response handling * refactor: update tool and agent types to use createTool for consistency and improve type handling * test: enhance MCPClient tests to validate tool IDs and improve object matching
1 parent 930c1e9 commit 52d5fa9

File tree

34 files changed

+1743
-230
lines changed

34 files changed

+1743
-230
lines changed

.changeset/great-foxes-see.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
---
2+
"@voltagent/core": minor
3+
---
4+
5+
## Introducing Toolkits for Better Tool Management
6+
7+
Managing related tools and their instructions is now simpler with `Toolkit`s.
8+
9+
**Motivation:**
10+
11+
- Defining shared instructions for multiple related tools was cumbersome.
12+
- The logic for deciding which instructions to add to the agent's system prompt could become complex.
13+
- We wanted a cleaner way to group tools logically.
14+
15+
**What's New: The `Toolkit`**
16+
17+
A `Toolkit` bundles related tools and allows defining shared `instructions` and an `addInstructions` flag _at the toolkit level_.
18+
19+
```typescript
20+
// packages/core/src/tool/toolkit.ts
21+
export type Toolkit = {
22+
/**
23+
* Unique identifier name for the toolkit.
24+
*/
25+
name: string;
26+
/**
27+
* A brief description of what the toolkit does. Optional.
28+
*/
29+
description?: string;
30+
/**
31+
* Shared instructions for the LLM on how to use the tools within this toolkit.
32+
* Optional.
33+
*/
34+
instructions?: string;
35+
/**
36+
* Whether to automatically add the toolkit's `instructions` to the agent's system prompt.
37+
* Defaults to false.
38+
*/
39+
addInstructions?: boolean;
40+
/**
41+
* An array of Tool instances that belong to this toolkit.
42+
*/
43+
tools: Tool<any>[];
44+
};
45+
```
46+
47+
**Key Changes to Core:**
48+
49+
1. **`ToolManager` Upgrade:** Now manages both `Tool` and `Toolkit` objects.
50+
2. **`AgentOptions` Update:** The `tools` option accepts `(Tool<any> | Toolkit)[]`.
51+
3. **Simplified Instruction Handling:** `Agent` now only adds instructions from `Toolkit`s where `addInstructions` is true.
52+
53+
This change leads to a clearer separation of concerns, simplifies the agent's internal logic, and makes managing tool instructions more predictable and powerful.
54+
55+
### New `createToolkit` Helper
56+
57+
We've also added a helper function, `createToolkit`, to simplify the creation of toolkits. It provides default values and basic validation:
58+
59+
```typescript
60+
// packages/core/src/tool/toolkit.ts
61+
export const createToolkit = (options: Toolkit): Toolkit => {
62+
if (!options.name) {
63+
throw new Error("Toolkit name is required");
64+
}
65+
if (!options.tools || options.tools.length === 0) {
66+
console.warn(`Toolkit '${options.name}' created without any tools.`);
67+
}
68+
69+
return {
70+
name: options.name,
71+
description: options.description || "", // Default empty description
72+
instructions: options.instructions,
73+
addInstructions: options.addInstructions || false, // Default to false
74+
tools: options.tools || [], // Default to empty array
75+
};
76+
};
77+
```
78+
79+
**Example Usage:**
80+
81+
```typescript
82+
import { createTool, createToolkit } from "@voltagent/core";
83+
import { z } from "zod";
84+
85+
// Define some tools first
86+
const getWeather = createTool({
87+
name: "getWeather",
88+
description: "Gets the weather for a location.",
89+
schema: z.object({ location: z.string() }),
90+
run: async ({ location }) => ({ temperature: "25C", condition: "Sunny" }),
91+
});
92+
93+
const searchWeb = createTool({
94+
name: "searchWeb",
95+
description: "Searches the web for a query.",
96+
schema: z.object({ query: z.string() }),
97+
run: async ({ query }) => ({ results: ["Result 1", "Result 2"] }),
98+
});
99+
100+
// Create a toolkit using the helper
101+
const webInfoToolkit = createToolkit({
102+
name: "web_information",
103+
description: "Tools for getting information from the web.",
104+
instructions: "Use these tools to find current information online.",
105+
addInstructions: true, // Add the instructions to the system prompt
106+
tools: [getWeather, searchWeb],
107+
});
108+
109+
console.log(webInfoToolkit);
110+
/*
111+
Output:
112+
{
113+
name: 'web_information',
114+
description: 'Tools for getting information from the web.',
115+
instructions: 'Use these tools to find current information online.',
116+
addInstructions: true,
117+
tools: [ [Object Tool: getWeather], [Object Tool: searchWeb] ]
118+
}
119+
*/
120+
```

.changeset/young-moments-sink.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
"@voltagent/core": minor
3+
---
4+
5+
## Introducing Reasoning Tools Helper
6+
7+
This update introduces a new helper function, `createReasoningTools`, to easily add step-by-step reasoning capabilities to your agents. #24
8+
9+
### New `createReasoningTools` Helper
10+
11+
**Feature:** Easily add `think` and `analyze` tools for step-by-step reasoning.
12+
13+
We've added a new helper function, `createReasoningTools`, which makes it trivial to equip your agents with structured thinking capabilities, similar to patterns seen in advanced AI systems.
14+
15+
- **What it does:** Returns a pre-configured `Toolkit` named `reasoning_tools`.
16+
- **Tools included:** Contains the `think` tool (for internal monologue/planning) and the `analyze` tool (for evaluating results and deciding next steps).
17+
- **Instructions:** Includes detailed instructions explaining how the agent should use these tools iteratively to solve problems. You can choose whether these instructions are automatically added to the system prompt via the `addInstructions` option.
18+
19+
```typescript
20+
import { createReasoningTools, type Toolkit } from "@voltagent/core";
21+
22+
// Get the reasoning toolkit (with instructions included in the system prompt)
23+
const reasoningToolkit: Toolkit = createReasoningTools({ addInstructions: true });
24+
25+
// Get the toolkit without automatically adding instructions
26+
const reasoningToolkitManual: Toolkit = createReasoningTools({ addInstructions: false });
27+
```
28+
29+
### How to Use Reasoning Tools
30+
31+
Pass the `Toolkit` object returned by `createReasoningTools` directly to the agent's `tools` array.
32+
33+
```typescript
34+
// Example: Using the new reasoning tools helper
35+
import { Agent, createReasoningTools, type Toolkit } from "@voltagent/core";
36+
import { VercelAIProvider } from "@voltagent/vercel-ai";
37+
import { openai } from "@ai-sdk/openai";
38+
39+
const reasoningToolkit: Toolkit = createReasoningTools({
40+
addInstructions: true,
41+
});
42+
43+
const agent = new Agent({
44+
name: "MyThinkingAgent",
45+
description: "An agent equipped with reasoning tools.",
46+
llm: new VercelAIProvider(),
47+
model: openai("gpt-4o-mini"),
48+
tools: [reasoningToolkit], // Pass the toolkit
49+
});
50+
51+
// Agent's system message will include reasoning instructions.
52+
```
53+
54+
This change simplifies adding reasoning capabilities to your agents.

examples/base/src/index.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
1-
import { VoltAgent, Agent } from "@voltagent/core";
1+
import { openai } from "@ai-sdk/openai";
2+
import { Agent, MCPConfiguration } from "@voltagent/core";
23
import { VercelAIProvider } from "@voltagent/vercel-ai";
34

4-
import { openai } from "@ai-sdk/openai";
5+
const mcpConfig = new MCPConfiguration({
6+
servers: {
7+
github: {
8+
type: "http",
9+
url: "https://mcp.composio.dev/github/mealy-few-wire-UfUhSQ?agent=cursor",
10+
},
11+
},
12+
});
513

614
const agent = new Agent({
7-
name: "Asistant",
8-
description: "A helpful assistant that answers questions without using tools",
15+
name: "GitHub Starrer Agent",
16+
description: "You help users star GitHub repositories",
917
llm: new VercelAIProvider(),
1018
model: openai("gpt-4o-mini"),
19+
tools: await mcpConfig.getTools(),
1120
});
1221

13-
new VoltAgent({
14-
agents: {
15-
agent,
16-
},
17-
});
22+
const result = await agent.streamText("Please star the repository 'composiohq/composio'");
23+
24+
for await (const chunk of result.textStream) {
25+
process.stdout.write(chunk);
26+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
dist
3+
.DS_Store
4+
.env
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<div align="center">
2+
<a href="https://voltagent.dev/">
3+
<img width="1800" alt="435380213-b6253409-8741-462b-a346-834cd18565a9" src="https://github.com/user-attachments/assets/452a03e7-eeda-4394-9ee7-0ffbcf37245c" />
4+
</a>
5+
6+
<br/>
7+
<br/>
8+
9+
<div align="center">
10+
<a href="https://voltagent.dev">Home Page</a> |
11+
<a href="https://voltagent.dev/docs/">Documentation</a> |
12+
<a href="https://github.com/voltagent/voltagent/tree/main/examples">Examples</a> |
13+
<a href="https://s.voltagent.dev/discord">Discord</a> |
14+
<a href="https://voltagent.dev/blog/">Blog</a>
15+
</div>
16+
</div>
17+
18+
<br/>
19+
20+
<div align="center">
21+
<strong>VoltAgent Example: Using Reasoning Tools (`think` & `analyze`)</strong><br>
22+
This example demonstrates how to equip a VoltAgent with `think` and `analyze` tools to enable step-by-step reasoning and analysis during task execution.
23+
<br />
24+
<br />
25+
</div>
26+
27+
<div align="center">
28+
29+
[![npm version](https://img.shields.io/npm/v/@voltagent/core.svg)](https://www.npmjs.com/package/@voltagent/core)
30+
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](CODE_OF_CONDUCT.md)
31+
[![Discord](https://img.shields.io/discord/1361559153780195478.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://s.voltagent.dev/discord)
32+
[![Twitter Follow](https://img.shields.io/twitter/follow/voltagent_dev?style=social)](https://twitter.com/voltagent_dev)
33+
34+
</div>
35+
36+
<br/>
37+
38+
## VoltAgent: With Thinking Tools Example
39+
40+
This example showcases how to integrate the `think` and `analyze` tools from `@voltagent/core` into an agent. These tools allow the agent to perform structured reasoning:
41+
42+
- **`think`**: Acts as a scratchpad for the agent to break down problems, plan steps, and explain its reasoning before taking action.
43+
- **`analyze`**: Allows the agent to evaluate the results of its actions or thoughts and decide on the next step (continue, validate, or provide a final answer).
44+
45+
By using these tools, agents can tackle more complex tasks, exhibit clearer thought processes, and potentially improve their accuracy and reliability.
46+
47+
This example sets up a basic agent, includes the reasoning tools, and logs the reasoning steps emitted by the agent during its interaction.
48+
49+
## Setup
50+
51+
1. **Clone the repository (if you haven't already):**
52+
```bash
53+
git clone https://github.com/voltagent/voltagent.git
54+
cd voltagent/examples/with-thinking-tool
55+
```
56+
2. **Install dependencies:**
57+
```bash
58+
npm install
59+
```
60+
3. **Set up environment variables:**
61+
Create a `.env` file in this directory (`examples/with-thinking-tool`) and add your OpenAI API key:
62+
```env
63+
OPENAI_API_KEY=your_openai_api_key_here
64+
```
65+
66+
## Run the Example
67+
68+
```bash
69+
npm run dev
70+
```
71+
72+
Observe the console output. You should see the agent's final response as well as the `ReasoningStep` objects logged whenever the agent uses the `think` or `analyze` tools.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "voltagent-example-with-thinking-tool",
3+
"private": true,
4+
"keywords": [
5+
"voltagent",
6+
"ai",
7+
"agent",
8+
"reasoning",
9+
"think",
10+
"analyze"
11+
],
12+
"license": "MIT",
13+
"author": "",
14+
"type": "module",
15+
"scripts": {
16+
"build": "tsc",
17+
"dev": "tsx watch --env-file=.env ./src",
18+
"start": "node dist/index.js",
19+
"volt": "volt"
20+
},
21+
"dependencies": {
22+
"@ai-sdk/openai": "^1.3.10",
23+
"@voltagent/cli": "^0.1.2",
24+
"@voltagent/core": "^0.1.5",
25+
"@voltagent/vercel-ai": "^0.1.2",
26+
"zod": "^3.24.2"
27+
},
28+
"devDependencies": {
29+
"@types/node": "^22.13.5",
30+
"tsx": "^4.19.3",
31+
"typescript": "^5.8.2"
32+
}
33+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { VoltAgent, Agent, createReasoningTools, type Toolkit } from "@voltagent/core";
2+
import { VercelAIProvider } from "@voltagent/vercel-ai";
3+
import { openai } from "@ai-sdk/openai";
4+
5+
const reasoningToolkit: Toolkit = createReasoningTools({
6+
addInstructions: true,
7+
});
8+
9+
const agent = new Agent({
10+
name: "ThinkingAssistant",
11+
description: `
12+
You are an AI assistant designed for complex problem-solving and structured reasoning.
13+
You leverage internal 'think' and 'analyze' tools to methodically work through challenges.
14+
15+
Your process involves:
16+
1. **Understanding:** Using 'think' to clarify the goal, constraints, and break down the problem.
17+
2. **Planning:** Again using 'think', outlining sequential steps, identifying information needs, or exploring potential strategies before taking action (like calling other tools).
18+
3. **Analyzing:** Employing 'analyze' after gathering information or completing steps to evaluate progress, check if results meet requirements, and decide the next logical move (e.g., continue the plan, revise the plan, conclude).
19+
20+
Your aim is to provide well-reasoned, accurate, and complete answers by thinking through the process internally.
21+
`,
22+
llm: new VercelAIProvider(),
23+
model: openai("gpt-4o-mini"),
24+
tools: [reasoningToolkit],
25+
markdown: true,
26+
});
27+
28+
new VoltAgent({
29+
agents: {
30+
agent,
31+
},
32+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2022",
4+
"module": "NodeNext",
5+
"moduleResolution": "NodeNext",
6+
"esModuleInterop": true,
7+
"forceConsistentCasingInFileNames": true,
8+
"strict": true,
9+
"outDir": "dist",
10+
"skipLibCheck": true
11+
},
12+
"include": ["src"],
13+
"exclude": ["node_modules", "dist"]
14+
}

0 commit comments

Comments
 (0)