agentool 0.0.1 → 1.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 +627 -52
- package/dist/ask-user/index.cjs +8 -0
- package/dist/ask-user/index.d.cts +68 -0
- package/dist/ask-user/index.d.ts +68 -0
- package/dist/ask-user/index.js +8 -0
- package/dist/bash/index.cjs +8 -0
- package/dist/bash/index.d.cts +63 -0
- package/dist/bash/index.d.ts +63 -0
- package/dist/bash/index.js +8 -0
- package/dist/chunk-3EPGFWZV.cjs +30 -0
- package/dist/chunk-3VO6NETR.cjs +79 -0
- package/dist/chunk-4YI2H55A.js +142 -0
- package/dist/chunk-5NW4OGRI.cjs +99 -0
- package/dist/chunk-6MDPYALY.js +196 -0
- package/dist/chunk-6PQLFDGT.js +117 -0
- package/dist/chunk-7QL4BQCH.js +40 -0
- package/dist/chunk-CAEVLIQB.cjs +117 -0
- package/dist/chunk-CGTPF6IS.js +90 -0
- package/dist/chunk-EA3YV7ZG.js +79 -0
- package/dist/chunk-FAEGCFTO.js +136 -0
- package/dist/chunk-FV2R5FFQ.cjs +102 -0
- package/dist/chunk-FW3UJ622.cjs +59 -0
- package/dist/chunk-G3ITTPGX.js +99 -0
- package/dist/chunk-HDKXSKMO.js +30 -0
- package/dist/chunk-HZAQRHBT.js +99 -0
- package/dist/chunk-I3ONDY7P.js +46 -0
- package/dist/chunk-I6KFFQPV.cjs +58 -0
- package/dist/chunk-IMZQ7ELK.cjs +196 -0
- package/dist/chunk-JCTBB7H2.cjs +40 -0
- package/dist/chunk-K77GC2QI.js +59 -0
- package/dist/chunk-LPV5CN2K.js +58 -0
- package/dist/chunk-MF7CJVIZ.js +40 -0
- package/dist/chunk-MIYA7TNR.cjs +123 -0
- package/dist/chunk-MJCAXASI.js +123 -0
- package/dist/chunk-MXFW3XY6.cjs +73 -0
- package/dist/chunk-ONBH74ZV.cjs +90 -0
- package/dist/chunk-OXLQ7QVL.cjs +40 -0
- package/dist/chunk-QEJV2KZ4.cjs +159 -0
- package/dist/chunk-QZ5GS6HW.cjs +46 -0
- package/dist/chunk-S6QEY7UY.js +73 -0
- package/dist/chunk-SUSAPI5W.cjs +142 -0
- package/dist/chunk-TBVHHF3H.cjs +47 -0
- package/dist/chunk-U2YMJM25.cjs +115 -0
- package/dist/chunk-VLNDEVKS.js +102 -0
- package/dist/chunk-XKG2A3EW.js +159 -0
- package/dist/chunk-XLD2Y3SS.cjs +136 -0
- package/dist/chunk-Y7KOKDFP.js +115 -0
- package/dist/chunk-YPPPGGLA.cjs +99 -0
- package/dist/chunk-ZHCMEQJJ.js +47 -0
- package/dist/context-compaction/index.cjs +8 -0
- package/dist/context-compaction/index.d.cts +77 -0
- package/dist/context-compaction/index.d.ts +77 -0
- package/dist/context-compaction/index.js +8 -0
- package/dist/diff/index.cjs +9 -0
- package/dist/diff/index.d.cts +72 -0
- package/dist/diff/index.d.ts +72 -0
- package/dist/diff/index.js +9 -0
- package/dist/edit/index.cjs +10 -0
- package/dist/edit/index.d.cts +53 -0
- package/dist/edit/index.d.ts +53 -0
- package/dist/edit/index.js +10 -0
- package/dist/glob/index.cjs +10 -0
- package/dist/glob/index.d.cts +47 -0
- package/dist/glob/index.d.ts +47 -0
- package/dist/glob/index.js +10 -0
- package/dist/grep/index.cjs +10 -0
- package/dist/grep/index.d.cts +50 -0
- package/dist/grep/index.d.ts +50 -0
- package/dist/grep/index.js +10 -0
- package/dist/http-request/index.cjs +8 -0
- package/dist/http-request/index.d.cts +60 -0
- package/dist/http-request/index.d.ts +60 -0
- package/dist/http-request/index.js +8 -0
- package/dist/index.cjs +102 -0
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +102 -0
- package/dist/lsp/index.cjs +10 -0
- package/dist/lsp/index.d.cts +38 -0
- package/dist/lsp/index.d.ts +38 -0
- package/dist/lsp/index.js +10 -0
- package/dist/memory/index.cjs +9 -0
- package/dist/memory/index.d.cts +63 -0
- package/dist/memory/index.d.ts +63 -0
- package/dist/memory/index.js +9 -0
- package/dist/multi-edit/index.cjs +11 -0
- package/dist/multi-edit/index.d.cts +72 -0
- package/dist/multi-edit/index.d.ts +72 -0
- package/dist/multi-edit/index.js +11 -0
- package/dist/read/index.cjs +10 -0
- package/dist/read/index.d.cts +67 -0
- package/dist/read/index.d.ts +67 -0
- package/dist/read/index.js +10 -0
- package/dist/sleep/index.cjs +8 -0
- package/dist/sleep/index.d.cts +60 -0
- package/dist/sleep/index.d.ts +60 -0
- package/dist/sleep/index.js +8 -0
- package/dist/task/index.cjs +8 -0
- package/dist/task/index.d.cts +67 -0
- package/dist/task/index.d.ts +67 -0
- package/dist/task/index.js +8 -0
- package/dist/types-3QPDuCXN.d.cts +45 -0
- package/dist/types-3QPDuCXN.d.ts +45 -0
- package/dist/web-fetch/index.cjs +8 -0
- package/dist/web-fetch/index.d.cts +56 -0
- package/dist/web-fetch/index.d.ts +56 -0
- package/dist/web-fetch/index.js +8 -0
- package/dist/write/index.cjs +10 -0
- package/dist/write/index.d.cts +47 -0
- package/dist/write/index.d.ts +47 -0
- package/dist/write/index.js +10 -0
- package/package.json +145 -20
- package/dist/core/index.d.ts +0 -20
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,80 +1,655 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# agentool
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
**16 AI agent tools as standalone [Vercel AI SDK](https://sdk.vercel.ai/) modules.**
|
|
6
|
+
|
|
7
|
+
<p>
|
|
8
|
+
<a href="https://www.npmjs.com/package/agentool"><img src="https://img.shields.io/npm/v/agentool?style=flat-square&color=cb3837&logo=npm" alt="npm version" /></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/agentool"><img src="https://img.shields.io/npm/dm/agentool?style=flat-square&color=cb3837&logo=npm" alt="npm downloads" /></a>
|
|
10
|
+
<a href="https://github.com/Z-M-Huang/agentool"><img src="https://img.shields.io/github/stars/Z-M-Huang/agentool?style=flat-square&logo=github" alt="GitHub stars" /></a>
|
|
11
|
+
<a href="https://github.com/Z-M-Huang/agentool/issues"><img src="https://img.shields.io/github/issues/Z-M-Huang/agentool?style=flat-square&logo=github" alt="GitHub issues" /></a>
|
|
12
|
+
<a href="https://github.com/Z-M-Huang/agentool/blob/main/LICENSE"><img src="https://img.shields.io/github/license/Z-M-Huang/agentool?style=flat-square" alt="License" /></a>
|
|
13
|
+
</p>
|
|
14
|
+
<p>
|
|
15
|
+
<img src="https://img.shields.io/badge/node-%3E%3D18.0.0-339933?style=flat-square&logo=node.js&logoColor=white" alt="Node.js" />
|
|
16
|
+
<img src="https://img.shields.io/badge/TypeScript-5.7+-3178c6?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript" />
|
|
17
|
+
<img src="https://img.shields.io/badge/Vercel%20AI%20SDK-v4%2B-000000?style=flat-square&logo=vercel&logoColor=white" alt="Vercel AI SDK" />
|
|
18
|
+
<img src="https://img.shields.io/badge/ESM%20%2B%20CJS-supported-22c55e?style=flat-square" alt="ESM + CJS" />
|
|
19
|
+
<img src="https://img.shields.io/badge/coverage-96%25-brightgreen?style=flat-square" alt="Test Coverage" />
|
|
20
|
+
<img src="https://visitor-badge.laobi.icu/badge?page_id=Z-M-Huang.agentool&style=flat-square" alt="Visitors" />
|
|
21
|
+
</p>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
File operations, shell execution, code search, web fetching, and more -- everything an AI agent needs to interact with a codebase and system.
|
|
25
|
+
|
|
26
|
+
---
|
|
4
27
|
|
|
5
|
-
##
|
|
28
|
+
## Features
|
|
6
29
|
|
|
7
|
-
|
|
30
|
+
- **16 production-ready tools** -- bash, grep, glob, read, edit, write, web-fetch, memory, multi-edit, diff, task, lsp, http-request, context-compaction, ask-user, sleep
|
|
31
|
+
- **Vercel AI SDK compatible** -- works with `generateText()`, `streamText()`, and any AI SDK provider (OpenAI, Anthropic, Google, etc.)
|
|
32
|
+
- **Factory + default pattern** -- `createBash({ cwd: '/my/project' })` for custom config, or just use `bash` with zero config
|
|
33
|
+
- **Dual ESM/CJS** -- works everywhere with proper `exports` map
|
|
34
|
+
- **TypeScript-first** -- full type declarations, strict mode, no `any`
|
|
35
|
+
- **Never throws** -- every `execute()` returns a descriptive error string instead of throwing
|
|
36
|
+
- **Tree-shakeable** -- 17 subpath exports, only import what you need
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install agentool ai zod
|
|
42
|
+
```
|
|
8
43
|
|
|
9
|
-
|
|
44
|
+
> `ai` and `zod` are peer dependencies. You also need an AI SDK provider like `@ai-sdk/openai`, `@ai-sdk/anthropic`, etc.
|
|
10
45
|
|
|
11
|
-
|
|
46
|
+
### Prerequisites
|
|
12
47
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
- AI SDK: Vercel AI SDK v6 (`ai`) as peer dependency
|
|
16
|
-
- Testing: vitest
|
|
17
|
-
- Package manager: pnpm
|
|
18
|
-
- License: Apache-2.0
|
|
48
|
+
- **Node.js >= 18**
|
|
49
|
+
- **[ripgrep](https://github.com/BurntSushi/ripgrep#installation)** (`rg`) -- required for `grep` and `glob` tools
|
|
19
50
|
|
|
20
|
-
|
|
51
|
+
```bash
|
|
52
|
+
# macOS
|
|
53
|
+
brew install ripgrep
|
|
21
54
|
|
|
22
|
-
|
|
55
|
+
# Ubuntu/Debian
|
|
56
|
+
sudo apt install ripgrep
|
|
57
|
+
|
|
58
|
+
# Windows
|
|
59
|
+
choco install ripgrep
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Quick Start
|
|
23
63
|
|
|
24
64
|
```typescript
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
65
|
+
import { generateText } from 'ai';
|
|
66
|
+
import { openai } from '@ai-sdk/openai';
|
|
67
|
+
import { bash, read, edit, glob, grep } from 'agentool';
|
|
68
|
+
|
|
69
|
+
const { text } = await generateText({
|
|
70
|
+
model: openai('gpt-4o'),
|
|
71
|
+
tools: { bash, read, edit, glob, grep },
|
|
72
|
+
maxSteps: 10,
|
|
73
|
+
prompt: 'Find all TypeScript files with TODO comments and list them',
|
|
74
|
+
});
|
|
28
75
|
```
|
|
29
76
|
|
|
30
|
-
|
|
77
|
+
### Tree-shake with subpath imports
|
|
31
78
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
79
|
+
```typescript
|
|
80
|
+
// Only import what you need -- no unused code loaded
|
|
81
|
+
import { bash } from 'agentool/bash';
|
|
82
|
+
import { grep } from 'agentool/grep';
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Custom configuration
|
|
86
|
+
|
|
87
|
+
Use factory functions when you need to configure tools (custom `cwd`, timeouts, etc.):
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { createBash } from 'agentool/bash';
|
|
91
|
+
import { createRead } from 'agentool/read';
|
|
92
|
+
|
|
93
|
+
const myBash = createBash({ cwd: '/my/project', timeout: 60000 });
|
|
94
|
+
const myRead = createRead({ cwd: '/my/project' });
|
|
43
95
|
|
|
44
|
-
|
|
45
|
-
|
|
96
|
+
// Use them like any other tool
|
|
97
|
+
const { text } = await generateText({
|
|
98
|
+
model: openai('gpt-4o'),
|
|
99
|
+
tools: { bash: myBash, read: myRead },
|
|
100
|
+
maxSteps: 10,
|
|
101
|
+
prompt: 'List all files and read package.json',
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Tools Reference
|
|
46
106
|
|
|
47
|
-
|
|
48
|
-
- Generic test runner with structured output parsing (jest, vitest, pytest)
|
|
107
|
+
### bash
|
|
49
108
|
|
|
50
|
-
|
|
51
|
-
- jq, yq, csv parsing
|
|
109
|
+
Execute shell commands with timeout and signal handling.
|
|
52
110
|
|
|
53
|
-
|
|
54
|
-
|
|
111
|
+
```typescript
|
|
112
|
+
import { bash } from 'agentool/bash';
|
|
55
113
|
|
|
56
|
-
|
|
57
|
-
|
|
114
|
+
const result = await bash.execute(
|
|
115
|
+
{ command: 'echo hello && ls -la' },
|
|
116
|
+
{ toolCallId: 'id', messages: [] },
|
|
117
|
+
);
|
|
118
|
+
```
|
|
58
119
|
|
|
59
|
-
|
|
120
|
+
With custom config:
|
|
60
121
|
|
|
61
122
|
```typescript
|
|
62
|
-
import {
|
|
123
|
+
import { createBash } from 'agentool/bash';
|
|
63
124
|
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
//
|
|
67
|
-
|
|
125
|
+
const bash = createBash({
|
|
126
|
+
cwd: '/my/project',
|
|
127
|
+
timeout: 60000, // 60s timeout (default: 120s)
|
|
128
|
+
shell: '/bin/zsh', // custom shell
|
|
68
129
|
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Parameters:** `command` (string), `timeout?` (number), `description?` (string)
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
### read
|
|
137
|
+
|
|
138
|
+
Read files with line numbers, offset/limit pagination, and dual-path reading (fast for <10MB, streaming for larger).
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { read } from 'agentool/read';
|
|
142
|
+
|
|
143
|
+
// Read entire file
|
|
144
|
+
const content = await read.execute(
|
|
145
|
+
{ file_path: '/app/src/index.ts' },
|
|
146
|
+
{ toolCallId: 'id', messages: [] },
|
|
147
|
+
);
|
|
148
|
+
// Returns: "1\texport function hello() {\n2\t return 'world';\n3\t}"
|
|
149
|
+
|
|
150
|
+
// Read specific range
|
|
151
|
+
const range = await read.execute(
|
|
152
|
+
{ file_path: '/app/src/index.ts', offset: 10, limit: 20 },
|
|
153
|
+
{ toolCallId: 'id', messages: [] },
|
|
154
|
+
);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Parameters:** `file_path` (string), `offset?` (number), `limit?` (number)
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
### edit
|
|
162
|
+
|
|
163
|
+
Exact string replacement with curly-quote normalization fallback.
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { edit } from 'agentool/edit';
|
|
167
|
+
|
|
168
|
+
const result = await edit.execute(
|
|
169
|
+
{
|
|
170
|
+
file_path: '/app/src/config.ts',
|
|
171
|
+
old_string: 'const PORT = 3000;',
|
|
172
|
+
new_string: 'const PORT = 8080;',
|
|
173
|
+
},
|
|
174
|
+
{ toolCallId: 'id', messages: [] },
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
// Replace all occurrences
|
|
178
|
+
const resultAll = await edit.execute(
|
|
179
|
+
{
|
|
180
|
+
file_path: '/app/src/config.ts',
|
|
181
|
+
old_string: 'localhost',
|
|
182
|
+
new_string: '0.0.0.0',
|
|
183
|
+
replace_all: true,
|
|
184
|
+
},
|
|
185
|
+
{ toolCallId: 'id', messages: [] },
|
|
186
|
+
);
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Parameters:** `file_path` (string), `old_string` (string), `new_string` (string), `replace_all?` (boolean)
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
### write
|
|
194
|
+
|
|
195
|
+
Write files with automatic parent directory creation.
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import { write } from 'agentool/write';
|
|
199
|
+
|
|
200
|
+
const result = await write.execute(
|
|
201
|
+
{
|
|
202
|
+
file_path: '/app/src/utils/helpers.ts',
|
|
203
|
+
content: 'export function add(a: number, b: number) {\n return a + b;\n}\n',
|
|
204
|
+
},
|
|
205
|
+
{ toolCallId: 'id', messages: [] },
|
|
206
|
+
);
|
|
207
|
+
// Returns: "Created file: /app/src/utils/helpers.ts (62 bytes)"
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Parameters:** `file_path` (string), `content` (string)
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
### grep
|
|
215
|
+
|
|
216
|
+
Search file contents with ripgrep. Three output modes, context lines, pagination.
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
import { grep } from 'agentool/grep';
|
|
220
|
+
|
|
221
|
+
// Find matching lines with context
|
|
222
|
+
const content = await grep.execute(
|
|
223
|
+
{ pattern: 'TODO|FIXME', output_mode: 'content', '-C': 2 },
|
|
224
|
+
{ toolCallId: 'id', messages: [] },
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
// List files containing matches (sorted by mtime)
|
|
228
|
+
const files = await grep.execute(
|
|
229
|
+
{ pattern: 'import.*react', output_mode: 'files_with_matches', glob: '*.tsx' },
|
|
230
|
+
{ toolCallId: 'id', messages: [] },
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
// Count matches per file
|
|
234
|
+
const counts = await grep.execute(
|
|
235
|
+
{ pattern: 'console\\.log', output_mode: 'count' },
|
|
236
|
+
{ toolCallId: 'id', messages: [] },
|
|
237
|
+
);
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Parameters:** `pattern` (string), `path?` (string), `output_mode?` (`'content'` | `'files_with_matches'` | `'count'`), `glob?` (string), `type?` (string), `-i?` (boolean), `-n?` (boolean), `-A?` (number), `-B?` (number), `-C?` / `context?` (number), `head_limit?` (number), `offset?` (number), `multiline?` (boolean)
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
### glob
|
|
245
|
+
|
|
246
|
+
Find files by pattern with ripgrep, sorted by modification time.
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
import { glob } from 'agentool/glob';
|
|
250
|
+
|
|
251
|
+
const result = await glob.execute(
|
|
252
|
+
{ pattern: '**/*.test.ts' },
|
|
253
|
+
{ toolCallId: 'id', messages: [] },
|
|
254
|
+
);
|
|
255
|
+
// Returns: "Found 27 files\n/app/tests/unit/bash.test.ts\n..."
|
|
256
|
+
|
|
257
|
+
// Search in specific directory
|
|
258
|
+
const result2 = await glob.execute(
|
|
259
|
+
{ pattern: '*.json', path: '/app/config' },
|
|
260
|
+
{ toolCallId: 'id', messages: [] },
|
|
261
|
+
);
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**Parameters:** `pattern` (string), `path?` (string)
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
### multi-edit
|
|
269
|
+
|
|
270
|
+
Atomically apply multiple edits to a single file. All succeed or none are applied.
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
import { multiEdit } from 'agentool/multi-edit';
|
|
69
274
|
|
|
70
|
-
const result = await
|
|
275
|
+
const result = await multiEdit.execute(
|
|
276
|
+
{
|
|
277
|
+
file_path: '/app/src/config.ts',
|
|
278
|
+
edits: [
|
|
279
|
+
{ old_string: 'const PORT = 3000;', new_string: 'const PORT = 8080;' },
|
|
280
|
+
{ old_string: "const HOST = 'localhost';", new_string: "const HOST = '0.0.0.0';" },
|
|
281
|
+
],
|
|
282
|
+
},
|
|
283
|
+
{ toolCallId: 'id', messages: [] },
|
|
284
|
+
);
|
|
71
285
|
```
|
|
72
286
|
|
|
73
|
-
|
|
287
|
+
**Parameters:** `file_path` (string), `edits` (array of `{ old_string, new_string }`)
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
### diff
|
|
292
|
+
|
|
293
|
+
Generate unified diffs between files or strings.
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
import { diff } from 'agentool/diff';
|
|
297
|
+
|
|
298
|
+
// Compare two files
|
|
299
|
+
const fileDiff = await diff.execute(
|
|
300
|
+
{ file_path: '/app/old.ts', other_file_path: '/app/new.ts' },
|
|
301
|
+
{ toolCallId: 'id', messages: [] },
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
// Compare strings
|
|
305
|
+
const stringDiff = await diff.execute(
|
|
306
|
+
{ old_content: 'hello world', new_content: 'hello universe' },
|
|
307
|
+
{ toolCallId: 'id', messages: [] },
|
|
308
|
+
);
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**Parameters:** `file_path?` (string), `other_file_path?` (string), `old_content?` (string), `new_content?` (string)
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
### web-fetch
|
|
316
|
+
|
|
317
|
+
Fetch URLs with automatic HTML-to-markdown conversion.
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import { webFetch } from 'agentool/web-fetch';
|
|
321
|
+
|
|
322
|
+
const result = await webFetch.execute(
|
|
323
|
+
{ url: 'https://example.com' },
|
|
324
|
+
{ toolCallId: 'id', messages: [] },
|
|
325
|
+
);
|
|
326
|
+
// Returns markdown content (HTML converted via Turndown, truncated at 100K chars)
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**Parameters:** `url` (string), `prompt?` (string)
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
### http-request
|
|
334
|
+
|
|
335
|
+
Make raw HTTP requests without markdown conversion.
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
import { httpRequest } from 'agentool/http-request';
|
|
339
|
+
|
|
340
|
+
const result = await httpRequest.execute(
|
|
341
|
+
{
|
|
342
|
+
method: 'POST',
|
|
343
|
+
url: 'https://api.example.com/data',
|
|
344
|
+
headers: { 'Content-Type': 'application/json' },
|
|
345
|
+
body: JSON.stringify({ key: 'value' }),
|
|
346
|
+
timeout: 5000,
|
|
347
|
+
},
|
|
348
|
+
{ toolCallId: 'id', messages: [] },
|
|
349
|
+
);
|
|
350
|
+
// Returns JSON: { status, statusText, headers, body }
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Parameters:** `method` (`'GET'` | `'POST'` | `'PUT'` | `'PATCH'` | `'DELETE'` | `'HEAD'`), `url` (string), `headers?` (object), `body?` (string), `timeout?` (number)
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
### memory
|
|
358
|
+
|
|
359
|
+
File-based key-value store for persistent agent memory.
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
import { memory } from 'agentool/memory';
|
|
363
|
+
|
|
364
|
+
// Write
|
|
365
|
+
await memory.execute(
|
|
366
|
+
{ action: 'write', key: 'user-prefs', content: 'Prefers dark mode' },
|
|
367
|
+
{ toolCallId: 'id', messages: [] },
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
// Read
|
|
371
|
+
const data = await memory.execute(
|
|
372
|
+
{ action: 'read', key: 'user-prefs' },
|
|
373
|
+
{ toolCallId: 'id', messages: [] },
|
|
374
|
+
);
|
|
375
|
+
|
|
376
|
+
// List all keys
|
|
377
|
+
const keys = await memory.execute(
|
|
378
|
+
{ action: 'list' },
|
|
379
|
+
{ toolCallId: 'id', messages: [] },
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
// Delete
|
|
383
|
+
await memory.execute(
|
|
384
|
+
{ action: 'delete', key: 'user-prefs' },
|
|
385
|
+
{ toolCallId: 'id', messages: [] },
|
|
386
|
+
);
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
**Parameters:** `action` (`'read'` | `'write'` | `'list'` | `'delete'`), `key?` (string), `content?` (string)
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
### task
|
|
394
|
+
|
|
395
|
+
JSON file-based task tracker for agent workflows.
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
import { task } from 'agentool/task';
|
|
399
|
+
|
|
400
|
+
// Create
|
|
401
|
+
const created = await task.execute(
|
|
402
|
+
{ action: 'create', subject: 'Fix login bug', description: 'Auth fails on refresh' },
|
|
403
|
+
{ toolCallId: 'id', messages: [] },
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
// List all
|
|
407
|
+
const list = await task.execute(
|
|
408
|
+
{ action: 'list' },
|
|
409
|
+
{ toolCallId: 'id', messages: [] },
|
|
410
|
+
);
|
|
411
|
+
|
|
412
|
+
// Update status
|
|
413
|
+
await task.execute(
|
|
414
|
+
{ action: 'update', id: 'abc123', status: 'completed' },
|
|
415
|
+
{ toolCallId: 'id', messages: [] },
|
|
416
|
+
);
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
**Parameters:** `action` (`'create'` | `'get'` | `'update'` | `'list'` | `'delete'`), `id?` (string), `subject?` (string), `description?` (string), `status?` (`'pending'` | `'in_progress'` | `'completed'`)
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
### lsp
|
|
424
|
+
|
|
425
|
+
Language Server Protocol operations for code intelligence.
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
import { createLsp } from 'agentool/lsp';
|
|
429
|
+
|
|
430
|
+
const lsp = createLsp({
|
|
431
|
+
servers: {
|
|
432
|
+
'.ts': { command: 'typescript-language-server', args: ['--stdio'] },
|
|
433
|
+
'.py': { command: 'pylsp' },
|
|
434
|
+
},
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
const result = await lsp.execute(
|
|
438
|
+
{ operation: 'goToDefinition', filePath: 'src/index.ts', line: 10, character: 5 },
|
|
439
|
+
{ toolCallId: 'id', messages: [] },
|
|
440
|
+
);
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Parameters:** `operation` (`'goToDefinition'` | `'findReferences'` | `'hover'` | `'documentSymbol'` | `'workspaceSymbol'` | `'goToImplementation'` | `'incomingCalls'` | `'outgoingCalls'`), `filePath` (string), `line?` (number), `character?` (number), `query?` (string)
|
|
444
|
+
|
|
445
|
+
---
|
|
446
|
+
|
|
447
|
+
### context-compaction
|
|
448
|
+
|
|
449
|
+
Compact conversation history to fit within token budgets.
|
|
450
|
+
|
|
451
|
+
```typescript
|
|
452
|
+
import { createContextCompaction } from 'agentool/context-compaction';
|
|
453
|
+
|
|
454
|
+
const compact = createContextCompaction({
|
|
455
|
+
maxTokens: 4096,
|
|
456
|
+
summarize: async (messages) => {
|
|
457
|
+
// Call your LLM to summarize
|
|
458
|
+
return 'Summary of previous conversation...';
|
|
459
|
+
},
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
const result = await compact.execute(
|
|
463
|
+
{
|
|
464
|
+
messages: [
|
|
465
|
+
{ role: 'user', content: 'Long conversation...' },
|
|
466
|
+
{ role: 'assistant', content: 'Long response...' },
|
|
467
|
+
],
|
|
468
|
+
},
|
|
469
|
+
{ toolCallId: 'id', messages: [] },
|
|
470
|
+
);
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Parameters:** `messages` (array of `{ role, content }`), `maxTokens?` (number)
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
### ask-user
|
|
478
|
+
|
|
479
|
+
Prompt the user for input during agent execution.
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
import { createAskUser } from 'agentool/ask-user';
|
|
483
|
+
|
|
484
|
+
const askUser = createAskUser({
|
|
485
|
+
onQuestion: async (question, options) => {
|
|
486
|
+
// Your UI logic to prompt the user
|
|
487
|
+
return 'User response here';
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
const answer = await askUser.execute(
|
|
492
|
+
{ question: 'Which database should I use?', options: ['PostgreSQL', 'MySQL', 'SQLite'] },
|
|
493
|
+
{ toolCallId: 'id', messages: [] },
|
|
494
|
+
);
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
**Parameters:** `question` (string), `options?` (string[])
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
### sleep
|
|
502
|
+
|
|
503
|
+
Pause execution for rate limiting or polling intervals.
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
import { sleep } from 'agentool/sleep';
|
|
507
|
+
|
|
508
|
+
const result = await sleep.execute(
|
|
509
|
+
{ durationMs: 2000, reason: 'Waiting for deployment' },
|
|
510
|
+
{ toolCallId: 'id', messages: [] },
|
|
511
|
+
);
|
|
512
|
+
// Returns: "Slept for 2001ms. Reason: Waiting for deployment"
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
**Parameters:** `durationMs` (number, max 300000), `reason?` (string)
|
|
516
|
+
|
|
517
|
+
## Configuration
|
|
518
|
+
|
|
519
|
+
Every tool follows the **factory + default** pattern:
|
|
520
|
+
|
|
521
|
+
```typescript
|
|
522
|
+
// Default instance -- uses process.cwd(), default timeouts
|
|
523
|
+
import { bash } from 'agentool/bash';
|
|
524
|
+
|
|
525
|
+
// Custom instance -- configure cwd, timeouts, and tool-specific options
|
|
526
|
+
import { createBash } from 'agentool/bash';
|
|
527
|
+
const myBash = createBash({
|
|
528
|
+
cwd: '/my/project',
|
|
529
|
+
timeout: 60000,
|
|
530
|
+
shell: '/bin/zsh',
|
|
531
|
+
});
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Base configuration
|
|
535
|
+
|
|
536
|
+
All tools accept `BaseToolConfig`:
|
|
537
|
+
|
|
538
|
+
| Option | Type | Default | Description |
|
|
539
|
+
|--------|------|---------|-------------|
|
|
540
|
+
| `cwd` | `string` | `process.cwd()` | Working directory for file operations |
|
|
541
|
+
|
|
542
|
+
Tools that support timeouts extend `TimeoutConfig`:
|
|
543
|
+
|
|
544
|
+
| Option | Type | Default | Description |
|
|
545
|
+
|--------|------|---------|-------------|
|
|
546
|
+
| `timeout` | `number` | varies | Timeout in milliseconds |
|
|
547
|
+
|
|
548
|
+
### Tool-specific configuration
|
|
549
|
+
|
|
550
|
+
| Tool | Extra Config |
|
|
551
|
+
|------|-------------|
|
|
552
|
+
| `bash` | `shell?: string` -- shell binary path |
|
|
553
|
+
| `read` | `maxLines?: number` -- max lines to return (default: 2000) |
|
|
554
|
+
| `memory` | `memoryDir?: string` -- storage directory |
|
|
555
|
+
| `task` | `tasksFile?: string` -- JSON file path |
|
|
556
|
+
| `lsp` | `servers?: Record<string, LspServerConfig>` -- LSP servers by file extension |
|
|
557
|
+
| `http-request` | `defaultHeaders?: Record<string, string>` -- headers merged into every request |
|
|
558
|
+
| `web-fetch` | `maxContentLength?: number`, `userAgent?: string` |
|
|
559
|
+
| `context-compaction` | `summarize?: (messages) => Promise<string>`, `maxTokens?: number` |
|
|
560
|
+
| `ask-user` | `onQuestion?: (question, options?) => Promise<string>` |
|
|
561
|
+
| `sleep` | `maxDuration?: number` -- cap in ms (default: 300000) |
|
|
562
|
+
|
|
563
|
+
## Error Handling
|
|
564
|
+
|
|
565
|
+
Every tool's `execute()` catches errors internally and returns a descriptive string -- **it never throws**:
|
|
566
|
+
|
|
567
|
+
```typescript
|
|
568
|
+
const result = await read.execute(
|
|
569
|
+
{ file_path: '/nonexistent/file.ts' },
|
|
570
|
+
{ toolCallId: 'id', messages: [] },
|
|
571
|
+
);
|
|
572
|
+
// Returns: "Error [read]: Failed to read file: ENOENT: no such file or directory..."
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
Error strings follow the format: `Error [tool-name]: {description}` with actionable context to help the AI model recover.
|
|
576
|
+
|
|
577
|
+
## Imports
|
|
578
|
+
|
|
579
|
+
### Barrel import (all tools)
|
|
580
|
+
|
|
581
|
+
```typescript
|
|
582
|
+
import {
|
|
583
|
+
bash, createBash,
|
|
584
|
+
read, createRead,
|
|
585
|
+
edit, createEdit,
|
|
586
|
+
write, createWrite,
|
|
587
|
+
grep, createGrep,
|
|
588
|
+
glob, createGlob,
|
|
589
|
+
webFetch, createWebFetch,
|
|
590
|
+
httpRequest, createHttpRequest,
|
|
591
|
+
memory, createMemory,
|
|
592
|
+
multiEdit, createMultiEdit,
|
|
593
|
+
diff, createDiff,
|
|
594
|
+
task, createTask,
|
|
595
|
+
lsp, createLsp,
|
|
596
|
+
contextCompaction, createContextCompaction,
|
|
597
|
+
askUser, createAskUser,
|
|
598
|
+
sleep, createSleep,
|
|
599
|
+
} from 'agentool';
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### Subpath imports (tree-shakeable)
|
|
603
|
+
|
|
604
|
+
```typescript
|
|
605
|
+
import { bash } from 'agentool/bash';
|
|
606
|
+
import { grep } from 'agentool/grep';
|
|
607
|
+
import { glob } from 'agentool/glob';
|
|
608
|
+
import { read } from 'agentool/read';
|
|
609
|
+
import { edit } from 'agentool/edit';
|
|
610
|
+
import { write } from 'agentool/write';
|
|
611
|
+
import { webFetch } from 'agentool/web-fetch';
|
|
612
|
+
import { httpRequest } from 'agentool/http-request';
|
|
613
|
+
import { memory } from 'agentool/memory';
|
|
614
|
+
import { multiEdit } from 'agentool/multi-edit';
|
|
615
|
+
import { diff } from 'agentool/diff';
|
|
616
|
+
import { task } from 'agentool/task';
|
|
617
|
+
import { lsp } from 'agentool/lsp';
|
|
618
|
+
import { contextCompaction } from 'agentool/context-compaction';
|
|
619
|
+
import { askUser } from 'agentool/ask-user';
|
|
620
|
+
import { sleep } from 'agentool/sleep';
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
## Full Example: AI Coding Agent
|
|
624
|
+
|
|
625
|
+
```typescript
|
|
626
|
+
import { generateText } from 'ai';
|
|
627
|
+
import { openai } from '@ai-sdk/openai';
|
|
628
|
+
import { bash, read, edit, write, glob, grep, diff } from 'agentool';
|
|
629
|
+
|
|
630
|
+
const { text, steps } = await generateText({
|
|
631
|
+
model: openai('gpt-4o'),
|
|
632
|
+
tools: { bash, read, edit, write, glob, grep, diff },
|
|
633
|
+
maxSteps: 20,
|
|
634
|
+
system: `You are a coding assistant. You can read, search, edit, and write files.
|
|
635
|
+
Always read a file before editing it. Use grep to search for patterns.
|
|
636
|
+
Use glob to find files. Use bash for git, build, and test commands.`,
|
|
637
|
+
prompt: 'Find all console.log statements in src/ and replace them with proper logger calls',
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
console.log(`Completed in ${steps.length} steps`);
|
|
641
|
+
console.log(text);
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
## Requirements
|
|
645
|
+
|
|
646
|
+
| Dependency | Version | Required |
|
|
647
|
+
|-----------|---------|----------|
|
|
648
|
+
| Node.js | >= 18 | Yes |
|
|
649
|
+
| `ai` (Vercel AI SDK) | >= 4.0.0 | Peer dependency |
|
|
650
|
+
| `zod` | >= 3.23.0 | Peer dependency |
|
|
651
|
+
| `ripgrep` (`rg`) | any | For grep/glob tools |
|
|
652
|
+
|
|
653
|
+
## License
|
|
74
654
|
|
|
75
|
-
|
|
76
|
-
2. Core tools (bash, read_file, write_file, edit, grep, find, git, gh, http)
|
|
77
|
-
3. createAgent runner
|
|
78
|
-
4. System prompt auto-assembly
|
|
79
|
-
5. Add-on modules (docker, test-runner, data-parse, code-intel, mcp)
|
|
80
|
-
6. Tests for each tool
|
|
655
|
+
[Apache-2.0](LICENSE)
|