@agentforge/tools 0.10.0 → 0.10.1
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 +80 -0
- package/dist/index.cjs +2105 -1524
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4527 -1044
- package/dist/index.d.ts +4527 -1044
- package/dist/index.js +1939 -1522
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { toolBuilder, ToolCategory, LogLevel, createLogger } from '@agentforge/core';
|
|
2
|
+
import axios12 from 'axios';
|
|
2
3
|
import { z } from 'zod';
|
|
3
|
-
import
|
|
4
|
-
import * as cheerio2 from 'cheerio';
|
|
4
|
+
import * as cheerio from 'cheerio';
|
|
5
5
|
import { WebClient } from '@slack/web-api';
|
|
6
6
|
import { parse } from 'csv-parse/sync';
|
|
7
7
|
import { stringify } from 'csv-stringify/sync';
|
|
8
8
|
import { XMLParser, XMLBuilder } from 'fast-xml-parser';
|
|
9
9
|
import { promises } from 'fs';
|
|
10
|
-
import * as
|
|
10
|
+
import * as path7 from 'path';
|
|
11
11
|
import { format, parse as parse$1, isValid, add, sub, differenceInDays, differenceInHours, differenceInMinutes, isAfter, isBefore } from 'date-fns';
|
|
12
12
|
import { randomUUID } from 'crypto';
|
|
13
13
|
|
|
14
|
-
// src/web/http-client.ts
|
|
14
|
+
// src/web/http/tools/http-client.ts
|
|
15
15
|
var HttpMethod = z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]);
|
|
16
16
|
var httpRequestSchema = z.object({
|
|
17
17
|
url: z.string().url().describe("The URL to make the request to"),
|
|
@@ -21,54 +21,79 @@ var httpRequestSchema = z.object({
|
|
|
21
21
|
timeout: z.number().default(3e4).describe("Request timeout in milliseconds"),
|
|
22
22
|
params: z.record(z.string()).optional().describe("Optional URL query parameters")
|
|
23
23
|
});
|
|
24
|
-
var
|
|
25
|
-
const config = {
|
|
26
|
-
method: input.method,
|
|
27
|
-
url: input.url,
|
|
28
|
-
headers: input.headers,
|
|
29
|
-
data: input.body,
|
|
30
|
-
timeout: input.timeout,
|
|
31
|
-
params: input.params,
|
|
32
|
-
validateStatus: () => true
|
|
33
|
-
// Don't throw on any status code
|
|
34
|
-
};
|
|
35
|
-
const response = await axios(config);
|
|
36
|
-
return {
|
|
37
|
-
status: response.status,
|
|
38
|
-
statusText: response.statusText,
|
|
39
|
-
headers: response.headers,
|
|
40
|
-
data: response.data,
|
|
41
|
-
url: input.url,
|
|
42
|
-
method: input.method ?? "GET"
|
|
43
|
-
};
|
|
44
|
-
}).build();
|
|
45
|
-
var httpGet = toolBuilder().name("http-get").description("Make a simple HTTP GET request to a URL and return the response data.").category(ToolCategory.WEB).tags(["http", "get", "fetch", "web"]).schema(z.object({
|
|
24
|
+
var httpGetSchema = z.object({
|
|
46
25
|
url: z.string().url().describe("The URL to fetch"),
|
|
47
26
|
headers: z.record(z.string()).optional().describe("Optional HTTP headers"),
|
|
48
27
|
params: z.record(z.string()).optional().describe("Optional URL query parameters")
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
headers: input.headers,
|
|
52
|
-
params: input.params,
|
|
53
|
-
timeout: 3e4
|
|
54
|
-
});
|
|
55
|
-
return response.data;
|
|
56
|
-
}).build();
|
|
57
|
-
var httpPost = toolBuilder().name("http-post").description("Make a simple HTTP POST request with JSON body and return the response data.").category(ToolCategory.WEB).tags(["http", "post", "api", "web"]).schema(z.object({
|
|
28
|
+
});
|
|
29
|
+
var httpPostSchema = z.object({
|
|
58
30
|
url: z.string().url().describe("The URL to post to"),
|
|
59
31
|
body: z.any().describe("The request body (will be sent as JSON)"),
|
|
60
32
|
headers: z.record(z.string()).optional().describe("Optional HTTP headers")
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// src/web/http/tools/http-client.ts
|
|
36
|
+
function createHttpClientTool(defaultTimeout = 3e4, defaultHeaders = {}) {
|
|
37
|
+
return toolBuilder().name("http-client").description("Make HTTP requests to web APIs and services. Supports GET, POST, PUT, DELETE, PATCH methods with custom headers and body.").category(ToolCategory.WEB).tags(["http", "api", "request", "web"]).schema(httpRequestSchema).implement(async (input) => {
|
|
38
|
+
const config = {
|
|
39
|
+
method: input.method,
|
|
40
|
+
url: input.url,
|
|
41
|
+
headers: { ...defaultHeaders, ...input.headers },
|
|
42
|
+
data: input.body,
|
|
43
|
+
timeout: input.timeout ?? defaultTimeout,
|
|
44
|
+
params: input.params,
|
|
45
|
+
validateStatus: () => true
|
|
46
|
+
// Don't throw on any status code
|
|
47
|
+
};
|
|
48
|
+
const response = await axios12(config);
|
|
49
|
+
return {
|
|
50
|
+
status: response.status,
|
|
51
|
+
statusText: response.statusText,
|
|
52
|
+
headers: response.headers,
|
|
53
|
+
data: response.data,
|
|
54
|
+
url: input.url,
|
|
55
|
+
method: input.method ?? "GET"
|
|
56
|
+
};
|
|
57
|
+
}).build();
|
|
58
|
+
}
|
|
59
|
+
function createHttpGetTool(defaultTimeout = 3e4, defaultHeaders = {}) {
|
|
60
|
+
return toolBuilder().name("http-get").description("Make a simple HTTP GET request to a URL and return the response data.").category(ToolCategory.WEB).tags(["http", "get", "fetch", "web"]).schema(httpGetSchema).implement(async (input) => {
|
|
61
|
+
const response = await axios12.get(input.url, {
|
|
62
|
+
headers: { ...defaultHeaders, ...input.headers },
|
|
63
|
+
params: input.params,
|
|
64
|
+
timeout: defaultTimeout
|
|
65
|
+
});
|
|
66
|
+
return response.data;
|
|
67
|
+
}).build();
|
|
68
|
+
}
|
|
69
|
+
function createHttpPostTool(defaultTimeout = 3e4, defaultHeaders = {}) {
|
|
70
|
+
return toolBuilder().name("http-post").description("Make a simple HTTP POST request with JSON body and return the response data.").category(ToolCategory.WEB).tags(["http", "post", "api", "web"]).schema(httpPostSchema).implement(async (input) => {
|
|
71
|
+
const response = await axios12.post(input.url, input.body, {
|
|
72
|
+
headers: {
|
|
73
|
+
"Content-Type": "application/json",
|
|
74
|
+
...defaultHeaders,
|
|
75
|
+
...input.headers
|
|
76
|
+
},
|
|
77
|
+
timeout: defaultTimeout
|
|
78
|
+
});
|
|
79
|
+
return response.data;
|
|
80
|
+
}).build();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/web/http/index.ts
|
|
84
|
+
var httpClient = createHttpClientTool();
|
|
85
|
+
var httpGet = createHttpGetTool();
|
|
86
|
+
var httpPost = createHttpPostTool();
|
|
87
|
+
var httpTools = [httpClient, httpGet, httpPost];
|
|
88
|
+
function createHttpTools(config = {}) {
|
|
89
|
+
const { defaultTimeout = 3e4, defaultHeaders = {} } = config;
|
|
90
|
+
return [
|
|
91
|
+
createHttpClientTool(defaultTimeout, defaultHeaders),
|
|
92
|
+
createHttpGetTool(defaultTimeout, defaultHeaders),
|
|
93
|
+
createHttpPostTool(defaultTimeout, defaultHeaders)
|
|
94
|
+
];
|
|
95
|
+
}
|
|
96
|
+
var webScraperSchema = z.object({
|
|
72
97
|
url: z.string().url().describe("The URL of the web page to scrape"),
|
|
73
98
|
selector: z.string().optional().describe("Optional CSS selector to extract specific elements"),
|
|
74
99
|
extractText: z.boolean().default(true).describe("Extract text content from the page"),
|
|
@@ -77,240 +102,295 @@ var webScraper = toolBuilder().name("web-scraper").description("Scrape and extra
|
|
|
77
102
|
extractImages: z.boolean().default(false).describe("Extract all image URLs from the page"),
|
|
78
103
|
extractMetadata: z.boolean().default(false).describe("Extract meta tags (title, description, etc.)"),
|
|
79
104
|
timeout: z.number().default(3e4).describe("Request timeout in milliseconds")
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const html = response.data;
|
|
88
|
-
const $ = cheerio2.load(html);
|
|
89
|
-
const result = {
|
|
90
|
-
url: input.url
|
|
91
|
-
};
|
|
92
|
-
const $selected = input.selector ? $(input.selector) : $("body");
|
|
93
|
-
if (input.extractText) {
|
|
94
|
-
result.text = $selected.text().trim();
|
|
95
|
-
}
|
|
96
|
-
if (input.extractHtml) {
|
|
97
|
-
result.html = $selected.html() || "";
|
|
98
|
-
}
|
|
99
|
-
if (input.extractLinks) {
|
|
100
|
-
result.links = [];
|
|
101
|
-
$("a[href]").each((_, el) => {
|
|
102
|
-
const href = $(el).attr("href");
|
|
103
|
-
if (href) {
|
|
104
|
-
try {
|
|
105
|
-
const absoluteUrl = new URL(href, input.url).href;
|
|
106
|
-
result.links.push(absoluteUrl);
|
|
107
|
-
} catch {
|
|
108
|
-
result.links.push(href);
|
|
109
|
-
}
|
|
105
|
+
});
|
|
106
|
+
function createWebScraperTool(defaultTimeout = 3e4, userAgent = "Mozilla/5.0 (compatible; AgentForge/1.0; +https://agentforge.dev)") {
|
|
107
|
+
return toolBuilder().name("web-scraper").description("Scrape and extract data from web pages. Can extract text, HTML, links, images, and use CSS selectors to target specific elements.").category(ToolCategory.WEB).tags(["scraper", "web", "html", "extract", "parse"]).schema(webScraperSchema).implement(async (input) => {
|
|
108
|
+
const response = await axios12.get(input.url, {
|
|
109
|
+
timeout: input.timeout || defaultTimeout,
|
|
110
|
+
headers: {
|
|
111
|
+
"User-Agent": userAgent
|
|
110
112
|
}
|
|
111
113
|
});
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
result
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
114
|
+
const html = response.data;
|
|
115
|
+
const $ = cheerio.load(html);
|
|
116
|
+
const result = {
|
|
117
|
+
url: input.url
|
|
118
|
+
};
|
|
119
|
+
const $selected = input.selector ? $(input.selector) : $("body");
|
|
120
|
+
if (input.extractText) {
|
|
121
|
+
result.text = $selected.text().trim();
|
|
122
|
+
}
|
|
123
|
+
if (input.extractHtml) {
|
|
124
|
+
result.html = $selected.html() || "";
|
|
125
|
+
}
|
|
126
|
+
if (input.extractLinks) {
|
|
127
|
+
result.links = [];
|
|
128
|
+
$("a[href]").each((_, el) => {
|
|
129
|
+
const href = $(el).attr("href");
|
|
130
|
+
if (href) {
|
|
131
|
+
try {
|
|
132
|
+
const absoluteUrl = new URL(href, input.url).href;
|
|
133
|
+
result.links.push(absoluteUrl);
|
|
134
|
+
} catch {
|
|
135
|
+
result.links.push(href);
|
|
136
|
+
}
|
|
123
137
|
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
if (input.extractImages) {
|
|
141
|
+
result.images = [];
|
|
142
|
+
$("img[src]").each((_, el) => {
|
|
143
|
+
const src = $(el).attr("src");
|
|
144
|
+
if (src) {
|
|
145
|
+
try {
|
|
146
|
+
const absoluteUrl = new URL(src, input.url).href;
|
|
147
|
+
result.images.push(absoluteUrl);
|
|
148
|
+
} catch {
|
|
149
|
+
result.images.push(src);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
if (input.extractMetadata) {
|
|
155
|
+
result.metadata = {};
|
|
156
|
+
const title = $("title").text() || $('meta[property="og:title"]').attr("content");
|
|
157
|
+
if (title) result.metadata.title = title;
|
|
158
|
+
const description = $('meta[name="description"]').attr("content") || $('meta[property="og:description"]').attr("content");
|
|
159
|
+
if (description) result.metadata.description = description;
|
|
160
|
+
$("meta[name], meta[property]").each((_, el) => {
|
|
161
|
+
const name = $(el).attr("name") || $(el).attr("property");
|
|
162
|
+
const content = $(el).attr("content");
|
|
163
|
+
if (name && content) {
|
|
164
|
+
result.metadata[name] = content;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
if (input.selector) {
|
|
169
|
+
result.selected = $selected.map((_, el) => ({
|
|
170
|
+
text: $(el).text().trim(),
|
|
171
|
+
html: $(el).html()
|
|
172
|
+
})).get();
|
|
173
|
+
}
|
|
174
|
+
return result;
|
|
175
|
+
}).build();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// src/web/scraper/index.ts
|
|
179
|
+
var webScraper = createWebScraperTool();
|
|
180
|
+
var scraperTools = [webScraper];
|
|
181
|
+
function createScraperTools(config = {}) {
|
|
182
|
+
const { defaultTimeout = 3e4, userAgent = "Mozilla/5.0 (compatible; AgentForge/1.0; +https://agentforge.dev)" } = config;
|
|
183
|
+
return [createWebScraperTool(defaultTimeout, userAgent)];
|
|
184
|
+
}
|
|
185
|
+
var htmlParserSchema = z.object({
|
|
150
186
|
html: z.string().describe("The HTML content to parse"),
|
|
151
187
|
selector: z.string().describe("CSS selector to find elements"),
|
|
152
188
|
extractText: z.boolean().default(true).describe("Extract text content from selected elements"),
|
|
153
189
|
extractHtml: z.boolean().default(false).describe("Extract inner HTML of selected elements"),
|
|
154
190
|
extractAttributes: z.array(z.string().describe("String value")).optional().describe('List of attributes to extract (e.g., ["href", "src", "class"])')
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
const $selected = $(input.selector);
|
|
158
|
-
const results = $selected.map((_, el) => {
|
|
159
|
-
const $el = $(el);
|
|
160
|
-
const item = {};
|
|
161
|
-
if (input.extractText) {
|
|
162
|
-
item.text = $el.text().trim();
|
|
163
|
-
}
|
|
164
|
-
if (input.extractHtml) {
|
|
165
|
-
item.html = $el.html();
|
|
166
|
-
}
|
|
167
|
-
if (input.extractAttributes && input.extractAttributes.length > 0) {
|
|
168
|
-
item.attributes = {};
|
|
169
|
-
for (const attr of input.extractAttributes) {
|
|
170
|
-
const value = $el.attr(attr);
|
|
171
|
-
if (value !== void 0) {
|
|
172
|
-
item.attributes[attr] = value;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
return item;
|
|
177
|
-
}).get();
|
|
178
|
-
return {
|
|
179
|
-
count: results.length,
|
|
180
|
-
results
|
|
181
|
-
};
|
|
182
|
-
}).build();
|
|
183
|
-
var extractLinks = toolBuilder().name("extract-links").description("Extract all links (anchor tags) from HTML content with their text and href attributes.").category(ToolCategory.WEB).tags(["html", "links", "extract", "anchor"]).schema(z.object({
|
|
191
|
+
});
|
|
192
|
+
var extractLinksSchema = z.object({
|
|
184
193
|
html: z.string().describe("The HTML content to extract links from"),
|
|
185
194
|
baseUrl: z.string().url().optional().describe("Optional base URL to resolve relative links")
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
const links = [];
|
|
189
|
-
$("a[href]").each((_, el) => {
|
|
190
|
-
const $el = $(el);
|
|
191
|
-
let href = $el.attr("href") || "";
|
|
192
|
-
if (input.baseUrl && href) {
|
|
193
|
-
try {
|
|
194
|
-
href = new URL(href, input.baseUrl).href;
|
|
195
|
-
} catch {
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
links.push({
|
|
199
|
-
text: $el.text().trim(),
|
|
200
|
-
href,
|
|
201
|
-
title: $el.attr("title")
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
return {
|
|
205
|
-
count: links.length,
|
|
206
|
-
links
|
|
207
|
-
};
|
|
208
|
-
}).build();
|
|
209
|
-
var extractImages = toolBuilder().name("extract-images").description("Extract all images from HTML content with their src, alt, and other attributes.").category(ToolCategory.WEB).tags(["html", "images", "extract", "img"]).schema(z.object({
|
|
195
|
+
});
|
|
196
|
+
var extractImagesSchema = z.object({
|
|
210
197
|
html: z.string().describe("The HTML content to extract images from"),
|
|
211
198
|
baseUrl: z.string().url().optional().describe("Optional base URL to resolve relative image URLs")
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const $
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
199
|
+
});
|
|
200
|
+
function createHtmlParserTool() {
|
|
201
|
+
return toolBuilder().name("html-parser").description("Parse HTML content and extract data using CSS selectors. Returns text, attributes, and structure of selected elements.").category(ToolCategory.WEB).tags(["html", "parser", "css", "selector", "extract"]).schema(htmlParserSchema).implement(async (input) => {
|
|
202
|
+
const $ = cheerio.load(input.html);
|
|
203
|
+
const $selected = $(input.selector);
|
|
204
|
+
const results = $selected.map((_, el) => {
|
|
205
|
+
const $el = $(el);
|
|
206
|
+
const item = {};
|
|
207
|
+
if (input.extractText) {
|
|
208
|
+
item.text = $el.text().trim();
|
|
222
209
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
210
|
+
if (input.extractHtml) {
|
|
211
|
+
item.html = $el.html();
|
|
212
|
+
}
|
|
213
|
+
if (input.extractAttributes && input.extractAttributes.length > 0) {
|
|
214
|
+
item.attributes = {};
|
|
215
|
+
for (const attr of input.extractAttributes) {
|
|
216
|
+
const value = $el.attr(attr);
|
|
217
|
+
if (value !== void 0) {
|
|
218
|
+
item.attributes[attr] = value;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return item;
|
|
223
|
+
}).get();
|
|
224
|
+
return {
|
|
225
|
+
count: results.length,
|
|
226
|
+
results
|
|
227
|
+
};
|
|
228
|
+
}).build();
|
|
229
|
+
}
|
|
230
|
+
function createExtractLinksTool() {
|
|
231
|
+
return toolBuilder().name("extract-links").description("Extract all links (anchor tags) from HTML content with their text and href attributes.").category(ToolCategory.WEB).tags(["html", "links", "extract", "anchor"]).schema(extractLinksSchema).implement(async (input) => {
|
|
232
|
+
const $ = cheerio.load(input.html);
|
|
233
|
+
const links = [];
|
|
234
|
+
$("a[href]").each((_, el) => {
|
|
235
|
+
const $el = $(el);
|
|
236
|
+
let href = $el.attr("href") || "";
|
|
237
|
+
if (input.baseUrl && href) {
|
|
238
|
+
try {
|
|
239
|
+
href = new URL(href, input.baseUrl).href;
|
|
240
|
+
} catch {
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
links.push({
|
|
244
|
+
text: $el.text().trim(),
|
|
245
|
+
href,
|
|
246
|
+
title: $el.attr("title")
|
|
247
|
+
});
|
|
230
248
|
});
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
|
|
249
|
+
return {
|
|
250
|
+
count: links.length,
|
|
251
|
+
links
|
|
252
|
+
};
|
|
253
|
+
}).build();
|
|
254
|
+
}
|
|
255
|
+
function createExtractImagesTool() {
|
|
256
|
+
return toolBuilder().name("extract-images").description("Extract all images from HTML content with their src, alt, and other attributes.").category(ToolCategory.WEB).tags(["html", "images", "extract", "img"]).schema(extractImagesSchema).implement(async (input) => {
|
|
257
|
+
const $ = cheerio.load(input.html);
|
|
258
|
+
const images = [];
|
|
259
|
+
$("img[src]").each((_, el) => {
|
|
260
|
+
const $el = $(el);
|
|
261
|
+
let src = $el.attr("src") || "";
|
|
262
|
+
if (input.baseUrl && src) {
|
|
263
|
+
try {
|
|
264
|
+
src = new URL(src, input.baseUrl).href;
|
|
265
|
+
} catch {
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
images.push({
|
|
269
|
+
src,
|
|
270
|
+
alt: $el.attr("alt"),
|
|
271
|
+
title: $el.attr("title"),
|
|
272
|
+
width: $el.attr("width"),
|
|
273
|
+
height: $el.attr("height")
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
return {
|
|
277
|
+
count: images.length,
|
|
278
|
+
images
|
|
279
|
+
};
|
|
280
|
+
}).build();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// src/web/html-parser/index.ts
|
|
284
|
+
var htmlParser = createHtmlParserTool();
|
|
285
|
+
var extractLinks = createExtractLinksTool();
|
|
286
|
+
var extractImages = createExtractImagesTool();
|
|
287
|
+
var htmlParserTools = [htmlParser, extractLinks, extractImages];
|
|
288
|
+
function createHtmlParserTools(config = {}) {
|
|
289
|
+
return [
|
|
290
|
+
createHtmlParserTool(),
|
|
291
|
+
createExtractLinksTool(),
|
|
292
|
+
createExtractImagesTool()
|
|
293
|
+
];
|
|
294
|
+
}
|
|
295
|
+
var urlValidatorSchema = z.object({
|
|
238
296
|
url: z.string().describe("The URL to validate and parse")
|
|
239
|
-
})
|
|
240
|
-
|
|
241
|
-
return {
|
|
242
|
-
url: parsed.href,
|
|
243
|
-
protocol: parsed.protocol,
|
|
244
|
-
hostname: parsed.hostname,
|
|
245
|
-
port: parsed.port,
|
|
246
|
-
pathname: parsed.pathname,
|
|
247
|
-
search: parsed.search,
|
|
248
|
-
hash: parsed.hash,
|
|
249
|
-
origin: parsed.origin
|
|
250
|
-
};
|
|
251
|
-
}).build();
|
|
252
|
-
var urlBuilder = toolBuilder().name("url-builder").description("Build a URL from components (protocol, hostname, path, query parameters, hash).").category(ToolCategory.WEB).tags(["url", "builder", "construct"]).schema(z.object({
|
|
297
|
+
});
|
|
298
|
+
var urlBuilderSchema = z.object({
|
|
253
299
|
protocol: z.string().default("https").describe("Protocol (http, https, etc.)"),
|
|
254
300
|
hostname: z.string().describe("Hostname or domain name"),
|
|
255
301
|
port: z.string().optional().describe("Optional port number"),
|
|
256
302
|
pathname: z.string().default("/").describe("URL path"),
|
|
257
303
|
query: z.record(z.string()).optional().describe("Query parameters as key-value pairs"),
|
|
258
304
|
hash: z.string().optional().describe("URL hash/fragment")
|
|
259
|
-
})
|
|
260
|
-
|
|
261
|
-
if (input.port) {
|
|
262
|
-
url.port = input.port;
|
|
263
|
-
}
|
|
264
|
-
url.pathname = input.pathname ?? "/";
|
|
265
|
-
if (input.query) {
|
|
266
|
-
Object.entries(input.query).forEach(([key, value]) => {
|
|
267
|
-
url.searchParams.append(key, value);
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
if (input.hash) {
|
|
271
|
-
url.hash = input.hash;
|
|
272
|
-
}
|
|
273
|
-
return {
|
|
274
|
-
url: url.href,
|
|
275
|
-
components: {
|
|
276
|
-
protocol: url.protocol,
|
|
277
|
-
hostname: url.hostname,
|
|
278
|
-
port: url.port,
|
|
279
|
-
pathname: url.pathname,
|
|
280
|
-
search: url.search,
|
|
281
|
-
hash: url.hash,
|
|
282
|
-
origin: url.origin
|
|
283
|
-
}
|
|
284
|
-
};
|
|
285
|
-
}).build();
|
|
286
|
-
var urlQueryParser = toolBuilder().name("url-query-parser").description("Parse query parameters from a URL or query string into a key-value object.").category(ToolCategory.WEB).tags(["url", "query", "parse", "params"]).schema(z.object({
|
|
305
|
+
});
|
|
306
|
+
var urlQueryParserSchema = z.object({
|
|
287
307
|
input: z.string().describe('URL or query string to parse (e.g., "?foo=bar&baz=qux" or full URL)')
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
308
|
+
});
|
|
309
|
+
function createUrlValidatorTool() {
|
|
310
|
+
return toolBuilder().name("url-validator").description("Validate and parse URLs. Returns detailed information about the URL structure including protocol, hostname, path, query parameters, and hash.").category(ToolCategory.WEB).tags(["url", "validator", "parse", "validate"]).schema(urlValidatorSchema).implementSafe(async (input) => {
|
|
311
|
+
const parsed = new URL(input.url);
|
|
312
|
+
return {
|
|
313
|
+
url: parsed.href,
|
|
314
|
+
protocol: parsed.protocol,
|
|
315
|
+
hostname: parsed.hostname,
|
|
316
|
+
port: parsed.port,
|
|
317
|
+
pathname: parsed.pathname,
|
|
318
|
+
search: parsed.search,
|
|
319
|
+
hash: parsed.hash,
|
|
320
|
+
origin: parsed.origin
|
|
321
|
+
};
|
|
322
|
+
}).build();
|
|
323
|
+
}
|
|
324
|
+
function createUrlBuilderTool() {
|
|
325
|
+
return toolBuilder().name("url-builder").description("Build a URL from components (protocol, hostname, path, query parameters, hash).").category(ToolCategory.WEB).tags(["url", "builder", "construct"]).schema(urlBuilderSchema).implement(async (input) => {
|
|
326
|
+
const url = new URL(`${input.protocol}://${input.hostname}`);
|
|
327
|
+
if (input.port) {
|
|
328
|
+
url.port = input.port;
|
|
329
|
+
}
|
|
330
|
+
url.pathname = input.pathname ?? "/";
|
|
331
|
+
if (input.query) {
|
|
332
|
+
Object.entries(input.query).forEach(([key, value]) => {
|
|
333
|
+
url.searchParams.append(key, value);
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
if (input.hash) {
|
|
337
|
+
url.hash = input.hash;
|
|
338
|
+
}
|
|
339
|
+
return {
|
|
340
|
+
url: url.href,
|
|
341
|
+
components: {
|
|
342
|
+
protocol: url.protocol,
|
|
343
|
+
hostname: url.hostname,
|
|
344
|
+
port: url.port,
|
|
345
|
+
pathname: url.pathname,
|
|
346
|
+
search: url.search,
|
|
347
|
+
hash: url.hash,
|
|
348
|
+
origin: url.origin
|
|
304
349
|
}
|
|
305
|
-
}
|
|
306
|
-
|
|
350
|
+
};
|
|
351
|
+
}).build();
|
|
352
|
+
}
|
|
353
|
+
function createUrlQueryParserTool() {
|
|
354
|
+
return toolBuilder().name("url-query-parser").description("Parse query parameters from a URL or query string into a key-value object.").category(ToolCategory.WEB).tags(["url", "query", "parse", "params"]).schema(urlQueryParserSchema).implement(async (input) => {
|
|
355
|
+
let searchParams;
|
|
356
|
+
try {
|
|
357
|
+
const url = new URL(input.input);
|
|
358
|
+
searchParams = url.searchParams;
|
|
359
|
+
} catch {
|
|
360
|
+
const queryString = input.input.startsWith("?") ? input.input.slice(1) : input.input;
|
|
361
|
+
searchParams = new URLSearchParams(queryString);
|
|
307
362
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
}
|
|
363
|
+
const params = {};
|
|
364
|
+
searchParams.forEach((value, key) => {
|
|
365
|
+
if (params[key]) {
|
|
366
|
+
if (Array.isArray(params[key])) {
|
|
367
|
+
params[key].push(value);
|
|
368
|
+
} else {
|
|
369
|
+
params[key] = [params[key], value];
|
|
370
|
+
}
|
|
371
|
+
} else {
|
|
372
|
+
params[key] = value;
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
return {
|
|
376
|
+
params,
|
|
377
|
+
count: Object.keys(params).length
|
|
378
|
+
};
|
|
379
|
+
}).build();
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// src/web/url-validator/index.ts
|
|
383
|
+
var urlValidator = createUrlValidatorTool();
|
|
384
|
+
var urlBuilder = createUrlBuilderTool();
|
|
385
|
+
var urlQueryParser = createUrlQueryParserTool();
|
|
386
|
+
var urlValidatorTools = [urlValidator, urlBuilder, urlQueryParser];
|
|
387
|
+
function createUrlValidatorTools(config = {}) {
|
|
388
|
+
return [
|
|
389
|
+
createUrlValidatorTool(),
|
|
390
|
+
createUrlBuilderTool(),
|
|
391
|
+
createUrlQueryParserTool()
|
|
392
|
+
];
|
|
393
|
+
}
|
|
314
394
|
var webSearchSchema = z.object({
|
|
315
395
|
query: z.string().min(1).describe("The search query"),
|
|
316
396
|
maxResults: z.number().min(1).max(50).default(10).describe("Maximum number of results to return (1-50)"),
|
|
@@ -415,7 +495,7 @@ var DuckDuckGoProvider = class {
|
|
|
415
495
|
async search(query, maxResults, timeout = DEFAULT_TIMEOUT) {
|
|
416
496
|
return retryWithBackoff(async () => {
|
|
417
497
|
try {
|
|
418
|
-
const response = await
|
|
498
|
+
const response = await axios12.get(
|
|
419
499
|
"https://api.duckduckgo.com/",
|
|
420
500
|
{
|
|
421
501
|
params: {
|
|
@@ -519,7 +599,7 @@ var SerperProvider = class {
|
|
|
519
599
|
}
|
|
520
600
|
return retryWithBackoff(async () => {
|
|
521
601
|
try {
|
|
522
|
-
const response = await
|
|
602
|
+
const response = await axios12.post(
|
|
523
603
|
"https://google.serper.dev/search",
|
|
524
604
|
{
|
|
525
605
|
q: query,
|
|
@@ -657,8 +737,28 @@ var webSearch = toolBuilder().name("web-search").description(
|
|
|
657
737
|
};
|
|
658
738
|
}
|
|
659
739
|
}).build();
|
|
660
|
-
|
|
661
|
-
|
|
740
|
+
function createGetConfiguredSlackClient(token, botName = "AgentForge Bot", botIcon = ":robot_face:") {
|
|
741
|
+
let configuredClient = null;
|
|
742
|
+
return function getConfiguredSlackClient() {
|
|
743
|
+
if (!configuredClient) {
|
|
744
|
+
const slackToken = token || process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN;
|
|
745
|
+
if (!slackToken) {
|
|
746
|
+
throw new Error(
|
|
747
|
+
"Slack token not configured. Please provide a token in config or set SLACK_USER_TOKEN or SLACK_BOT_TOKEN environment variable."
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
configuredClient = new WebClient(slackToken);
|
|
751
|
+
}
|
|
752
|
+
return {
|
|
753
|
+
client: configuredClient,
|
|
754
|
+
config: {
|
|
755
|
+
token: token || process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN || "",
|
|
756
|
+
botName,
|
|
757
|
+
botIcon
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
};
|
|
761
|
+
}
|
|
662
762
|
var defaultSlackClient = null;
|
|
663
763
|
function getDefaultSlackClient() {
|
|
664
764
|
if (!defaultSlackClient) {
|
|
@@ -670,196 +770,17 @@ function getDefaultSlackClient() {
|
|
|
670
770
|
}
|
|
671
771
|
defaultSlackClient = new WebClient(token);
|
|
672
772
|
}
|
|
673
|
-
return defaultSlackClient;
|
|
674
|
-
}
|
|
675
|
-
var sendSlackMessage = toolBuilder().name("send-slack-message").description("Send a message to a Slack channel for team communication and notifications").category(ToolCategory.WEB).tags(["slack", "messaging", "communication"]).usageNotes(
|
|
676
|
-
"Use this for general team communication. For notifications with @mentions, consider using notify-slack instead. Use get-slack-channels first if you need to find the right channel."
|
|
677
|
-
).suggests(["get-slack-channels"]).schema(
|
|
678
|
-
z.object({
|
|
679
|
-
channel: z.string().describe("Channel name (e.g., 'general') or ID (e.g., 'C123456')"),
|
|
680
|
-
message: z.string().describe("Message content to send")
|
|
681
|
-
})
|
|
682
|
-
).implementSafe(async ({ channel, message }) => {
|
|
683
|
-
logger.info("send-slack-message called", { channel, messageLength: message.length });
|
|
684
|
-
try {
|
|
685
|
-
const slack = getDefaultSlackClient();
|
|
686
|
-
const result = await slack.chat.postMessage({
|
|
687
|
-
channel,
|
|
688
|
-
text: message,
|
|
689
|
-
username: "AgentForge Bot",
|
|
690
|
-
icon_emoji: ":robot_face:"
|
|
691
|
-
});
|
|
692
|
-
logger.info("send-slack-message result", {
|
|
693
|
-
channel: result.channel,
|
|
694
|
-
timestamp: result.ts,
|
|
695
|
-
messageLength: message.length,
|
|
696
|
-
success: true
|
|
697
|
-
});
|
|
698
|
-
return {
|
|
699
|
-
channel: result.channel,
|
|
700
|
-
message,
|
|
701
|
-
timestamp: result.ts,
|
|
702
|
-
message_id: result.ts
|
|
703
|
-
};
|
|
704
|
-
} catch (error) {
|
|
705
|
-
logger.error("send-slack-message failed", {
|
|
706
|
-
channel,
|
|
707
|
-
error: error.message,
|
|
708
|
-
data: error.data
|
|
709
|
-
});
|
|
710
|
-
throw error;
|
|
711
|
-
}
|
|
712
|
-
}).build();
|
|
713
|
-
var notifySlack = toolBuilder().name("notify-slack").description("Send a notification to a Slack channel with optional @mentions for urgent alerts").category(ToolCategory.WEB).tags(["slack", "notification", "alert"]).usageNotes(
|
|
714
|
-
"Use this for urgent notifications that require @mentions. For general messages without mentions, use send-slack-message instead."
|
|
715
|
-
).suggests(["get-slack-channels"]).schema(
|
|
716
|
-
z.object({
|
|
717
|
-
channel: z.string().describe("Channel name or ID"),
|
|
718
|
-
message: z.string().describe("Notification message"),
|
|
719
|
-
mentions: z.array(z.string()).optional().describe("List of usernames to mention (without @)")
|
|
720
|
-
})
|
|
721
|
-
).implementSafe(async ({ channel, message, mentions = [] }) => {
|
|
722
|
-
logger.info("notify-slack called", {
|
|
723
|
-
channel,
|
|
724
|
-
messageLength: message.length,
|
|
725
|
-
mentionCount: mentions.length
|
|
726
|
-
});
|
|
727
|
-
const slack = getDefaultSlackClient();
|
|
728
|
-
const mentionText = mentions.length > 0 ? mentions.map((m) => `<@${m}>`).join(" ") + " " : "";
|
|
729
|
-
const fullMessage = `${mentionText}${message}`;
|
|
730
|
-
const result = await slack.chat.postMessage({
|
|
731
|
-
channel,
|
|
732
|
-
text: fullMessage,
|
|
733
|
-
username: "AgentForge Bot",
|
|
734
|
-
icon_emoji: ":robot_face:"
|
|
735
|
-
});
|
|
736
|
-
logger.info("notify-slack result", {
|
|
737
|
-
channel: result.channel,
|
|
738
|
-
timestamp: result.ts,
|
|
739
|
-
mentions: mentions.length
|
|
740
|
-
});
|
|
741
|
-
return {
|
|
742
|
-
channel: result.channel,
|
|
743
|
-
message: fullMessage,
|
|
744
|
-
mentions,
|
|
745
|
-
timestamp: result.ts,
|
|
746
|
-
notification_id: result.ts
|
|
747
|
-
};
|
|
748
|
-
}).build();
|
|
749
|
-
var getSlackChannels = toolBuilder().name("get-slack-channels").description("Get a list of available Slack channels to find the right channel for messaging").category(ToolCategory.WEB).tags(["slack", "channels", "list"]).usageNotes(
|
|
750
|
-
"Use this first to discover available channels before sending messages. Helps ensure you are sending to the correct channel."
|
|
751
|
-
).follows(["send-slack-message", "notify-slack"]).schema(
|
|
752
|
-
z.object({
|
|
753
|
-
include_private: z.boolean().optional().describe("Include private channels (default: false)")
|
|
754
|
-
})
|
|
755
|
-
).implementSafe(async ({ include_private = false }) => {
|
|
756
|
-
logger.info("get-slack-channels called", { include_private });
|
|
757
|
-
const slack = getDefaultSlackClient();
|
|
758
|
-
const publicChannels = await slack.conversations.list({
|
|
759
|
-
types: "public_channel",
|
|
760
|
-
exclude_archived: true
|
|
761
|
-
});
|
|
762
|
-
let allChannels = publicChannels.channels || [];
|
|
763
|
-
if (include_private) {
|
|
764
|
-
const privateChannels = await slack.conversations.list({
|
|
765
|
-
types: "private_channel",
|
|
766
|
-
exclude_archived: true
|
|
767
|
-
});
|
|
768
|
-
allChannels = [...allChannels, ...privateChannels.channels || []];
|
|
769
|
-
}
|
|
770
|
-
logger.info("get-slack-channels result", {
|
|
771
|
-
channelCount: allChannels.length,
|
|
772
|
-
includePrivate: include_private
|
|
773
|
-
});
|
|
774
773
|
return {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
num_members: c.num_members || 0
|
|
781
|
-
}))
|
|
782
|
-
};
|
|
783
|
-
}).build();
|
|
784
|
-
var getSlackMessages = toolBuilder().name("get-slack-messages").description("Retrieve message history from a Slack channel to read recent conversations").category(ToolCategory.WEB).tags(["slack", "messages", "history", "read"]).usageNotes(
|
|
785
|
-
"Use this to read recent messages from a channel. Use get-slack-channels first if you need to find the channel ID. Returns messages in reverse chronological order (newest first)."
|
|
786
|
-
).suggests(["get-slack-channels"]).schema(
|
|
787
|
-
z.object({
|
|
788
|
-
channel: z.string().describe("Channel name (e.g., 'general') or ID (e.g., 'C123456')"),
|
|
789
|
-
limit: z.number().int().min(1).max(100).optional().describe("Number of messages to retrieve (default: 20, max: 100)")
|
|
790
|
-
})
|
|
791
|
-
).implementSafe(async ({ channel, limit = 20 }) => {
|
|
792
|
-
logger.info("get-slack-messages called", { channel, limit });
|
|
793
|
-
try {
|
|
794
|
-
const slack = getDefaultSlackClient();
|
|
795
|
-
let channelId = channel;
|
|
796
|
-
if (!channel.startsWith("C") && !channel.startsWith("D")) {
|
|
797
|
-
const channels = await slack.conversations.list({
|
|
798
|
-
types: "public_channel,private_channel",
|
|
799
|
-
exclude_archived: true
|
|
800
|
-
});
|
|
801
|
-
const found = channels.channels?.find((c) => c.name === channel);
|
|
802
|
-
if (!found) {
|
|
803
|
-
logger.error("get-slack-messages: channel not found", { channel });
|
|
804
|
-
throw new Error(
|
|
805
|
-
`Channel '${channel}' not found. Use get-slack-channels to see available channels.`
|
|
806
|
-
);
|
|
807
|
-
}
|
|
808
|
-
channelId = found.id;
|
|
809
|
-
}
|
|
810
|
-
const result = await slack.conversations.history({
|
|
811
|
-
channel: channelId,
|
|
812
|
-
limit: Math.min(limit, 100)
|
|
813
|
-
// Cap at 100 for performance
|
|
814
|
-
});
|
|
815
|
-
logger.info("get-slack-messages result", {
|
|
816
|
-
channel: channelId,
|
|
817
|
-
messageCount: result.messages?.length || 0,
|
|
818
|
-
limit
|
|
819
|
-
});
|
|
820
|
-
return {
|
|
821
|
-
channel: channelId,
|
|
822
|
-
count: result.messages?.length || 0,
|
|
823
|
-
messages: result.messages?.map((m) => ({
|
|
824
|
-
user: m.user || "unknown",
|
|
825
|
-
text: m.text || "",
|
|
826
|
-
timestamp: m.ts,
|
|
827
|
-
thread_ts: m.thread_ts,
|
|
828
|
-
type: m.type,
|
|
829
|
-
subtype: m.subtype
|
|
830
|
-
})) || []
|
|
831
|
-
};
|
|
832
|
-
} catch (error) {
|
|
833
|
-
logger.error("get-slack-messages failed", {
|
|
834
|
-
channel,
|
|
835
|
-
error: error.message,
|
|
836
|
-
data: error.data
|
|
837
|
-
});
|
|
838
|
-
throw error;
|
|
839
|
-
}
|
|
840
|
-
}).build();
|
|
841
|
-
function createSlackTools(config = {}) {
|
|
842
|
-
const {
|
|
843
|
-
token,
|
|
844
|
-
botName = "AgentForge Bot",
|
|
845
|
-
botIcon = ":robot_face:",
|
|
846
|
-
logLevel: customLogLevel
|
|
847
|
-
} = config;
|
|
848
|
-
let configuredClient = null;
|
|
849
|
-
function getConfiguredSlackClient() {
|
|
850
|
-
if (!configuredClient) {
|
|
851
|
-
const slackToken = token || process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN;
|
|
852
|
-
if (!slackToken) {
|
|
853
|
-
throw new Error(
|
|
854
|
-
"Slack token not configured. Please provide a token in config or set SLACK_USER_TOKEN or SLACK_BOT_TOKEN environment variable."
|
|
855
|
-
);
|
|
856
|
-
}
|
|
857
|
-
configuredClient = new WebClient(slackToken);
|
|
774
|
+
client: defaultSlackClient,
|
|
775
|
+
config: {
|
|
776
|
+
token: process.env.SLACK_USER_TOKEN || process.env.SLACK_BOT_TOKEN || "",
|
|
777
|
+
botName: "AgentForge Bot",
|
|
778
|
+
botIcon: ":robot_face:"
|
|
858
779
|
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
function createSendSlackMessageTool(getSlackClient, logger4) {
|
|
783
|
+
return toolBuilder().name("send-slack-message").description("Send a message to a Slack channel for team communication and notifications").category(ToolCategory.WEB).tags(["slack", "messaging", "communication"]).usageNotes(
|
|
863
784
|
"Use this for general team communication. For notifications with @mentions, consider using notify-slack instead. Use get-slack-channels first if you need to find the right channel."
|
|
864
785
|
).suggests(["get-slack-channels"]).schema(
|
|
865
786
|
z.object({
|
|
@@ -867,16 +788,16 @@ function createSlackTools(config = {}) {
|
|
|
867
788
|
message: z.string().describe("Message content to send")
|
|
868
789
|
})
|
|
869
790
|
).implementSafe(async ({ channel, message }) => {
|
|
870
|
-
|
|
791
|
+
logger4.info("send-slack-message called", { channel, messageLength: message.length });
|
|
871
792
|
try {
|
|
872
|
-
const slack =
|
|
793
|
+
const { client: slack, config } = getSlackClient();
|
|
873
794
|
const result = await slack.chat.postMessage({
|
|
874
795
|
channel,
|
|
875
796
|
text: message,
|
|
876
|
-
username: botName,
|
|
877
|
-
icon_emoji: botIcon
|
|
797
|
+
username: config.botName,
|
|
798
|
+
icon_emoji: config.botIcon
|
|
878
799
|
});
|
|
879
|
-
|
|
800
|
+
logger4.info("send-slack-message result", {
|
|
880
801
|
channel: result.channel,
|
|
881
802
|
timestamp: result.ts,
|
|
882
803
|
messageLength: message.length,
|
|
@@ -889,7 +810,7 @@ function createSlackTools(config = {}) {
|
|
|
889
810
|
message_id: result.ts
|
|
890
811
|
};
|
|
891
812
|
} catch (error) {
|
|
892
|
-
|
|
813
|
+
logger4.error("send-slack-message failed", {
|
|
893
814
|
channel,
|
|
894
815
|
error: error.message,
|
|
895
816
|
data: error.data
|
|
@@ -897,7 +818,9 @@ function createSlackTools(config = {}) {
|
|
|
897
818
|
throw error;
|
|
898
819
|
}
|
|
899
820
|
}).build();
|
|
900
|
-
|
|
821
|
+
}
|
|
822
|
+
function createNotifySlackTool(getSlackClient, logger4) {
|
|
823
|
+
return toolBuilder().name("notify-slack").description("Send a notification to a Slack channel with optional @mentions for urgent alerts").category(ToolCategory.WEB).tags(["slack", "notification", "alert"]).usageNotes(
|
|
901
824
|
"Use this for urgent notifications that require @mentions. For general messages without mentions, use send-slack-message instead."
|
|
902
825
|
).suggests(["get-slack-channels"]).schema(
|
|
903
826
|
z.object({
|
|
@@ -906,21 +829,21 @@ function createSlackTools(config = {}) {
|
|
|
906
829
|
mentions: z.array(z.string()).optional().describe("List of usernames to mention (without @)")
|
|
907
830
|
})
|
|
908
831
|
).implementSafe(async ({ channel, message, mentions = [] }) => {
|
|
909
|
-
|
|
832
|
+
logger4.info("notify-slack called", {
|
|
910
833
|
channel,
|
|
911
834
|
messageLength: message.length,
|
|
912
835
|
mentionCount: mentions.length
|
|
913
836
|
});
|
|
914
|
-
const slack =
|
|
837
|
+
const { client: slack, config } = getSlackClient();
|
|
915
838
|
const mentionText = mentions.length > 0 ? mentions.map((m) => `<@${m}>`).join(" ") + " " : "";
|
|
916
839
|
const fullMessage = `${mentionText}${message}`;
|
|
917
840
|
const result = await slack.chat.postMessage({
|
|
918
841
|
channel,
|
|
919
842
|
text: fullMessage,
|
|
920
|
-
username: botName,
|
|
921
|
-
icon_emoji: botIcon
|
|
843
|
+
username: config.botName,
|
|
844
|
+
icon_emoji: config.botIcon
|
|
922
845
|
});
|
|
923
|
-
|
|
846
|
+
logger4.info("notify-slack result", {
|
|
924
847
|
channel: result.channel,
|
|
925
848
|
timestamp: result.ts,
|
|
926
849
|
mentions: mentions.length
|
|
@@ -933,15 +856,17 @@ function createSlackTools(config = {}) {
|
|
|
933
856
|
notification_id: result.ts
|
|
934
857
|
};
|
|
935
858
|
}).build();
|
|
936
|
-
|
|
859
|
+
}
|
|
860
|
+
function createGetSlackChannelsTool(getSlackClient, logger4) {
|
|
861
|
+
return toolBuilder().name("get-slack-channels").description("Get a list of available Slack channels to find the right channel for messaging").category(ToolCategory.WEB).tags(["slack", "channels", "list"]).usageNotes(
|
|
937
862
|
"Use this first to discover available channels before sending messages. Helps ensure you are sending to the correct channel."
|
|
938
863
|
).follows(["send-slack-message", "notify-slack"]).schema(
|
|
939
864
|
z.object({
|
|
940
865
|
include_private: z.boolean().optional().describe("Include private channels (default: false)")
|
|
941
866
|
})
|
|
942
867
|
).implementSafe(async ({ include_private = false }) => {
|
|
943
|
-
|
|
944
|
-
const slack =
|
|
868
|
+
logger4.info("get-slack-channels called", { include_private });
|
|
869
|
+
const { client: slack } = getSlackClient();
|
|
945
870
|
const publicChannels = await slack.conversations.list({
|
|
946
871
|
types: "public_channel",
|
|
947
872
|
exclude_archived: true
|
|
@@ -954,7 +879,7 @@ function createSlackTools(config = {}) {
|
|
|
954
879
|
});
|
|
955
880
|
allChannels = [...allChannels, ...privateChannels.channels || []];
|
|
956
881
|
}
|
|
957
|
-
|
|
882
|
+
logger4.info("get-slack-channels result", {
|
|
958
883
|
channelCount: allChannels.length,
|
|
959
884
|
includePrivate: include_private
|
|
960
885
|
});
|
|
@@ -968,7 +893,9 @@ function createSlackTools(config = {}) {
|
|
|
968
893
|
}))
|
|
969
894
|
};
|
|
970
895
|
}).build();
|
|
971
|
-
|
|
896
|
+
}
|
|
897
|
+
function createGetSlackMessagesTool(getSlackClient, logger4) {
|
|
898
|
+
return toolBuilder().name("get-slack-messages").description("Retrieve message history from a Slack channel to read recent conversations").category(ToolCategory.WEB).tags(["slack", "messages", "history", "read"]).usageNotes(
|
|
972
899
|
"Use this to read recent messages from a channel. Use get-slack-channels first if you need to find the channel ID. Returns messages in reverse chronological order (newest first)."
|
|
973
900
|
).suggests(["get-slack-channels"]).schema(
|
|
974
901
|
z.object({
|
|
@@ -976,9 +903,9 @@ function createSlackTools(config = {}) {
|
|
|
976
903
|
limit: z.number().int().min(1).max(100).optional().describe("Number of messages to retrieve (default: 20, max: 100)")
|
|
977
904
|
})
|
|
978
905
|
).implementSafe(async ({ channel, limit = 20 }) => {
|
|
979
|
-
|
|
906
|
+
logger4.info("get-slack-messages called", { channel, limit });
|
|
980
907
|
try {
|
|
981
|
-
const slack =
|
|
908
|
+
const { client: slack } = getSlackClient();
|
|
982
909
|
let channelId = channel;
|
|
983
910
|
if (!channel.startsWith("C") && !channel.startsWith("D")) {
|
|
984
911
|
const channels = await slack.conversations.list({
|
|
@@ -987,7 +914,7 @@ function createSlackTools(config = {}) {
|
|
|
987
914
|
});
|
|
988
915
|
const found = channels.channels?.find((c) => c.name === channel);
|
|
989
916
|
if (!found) {
|
|
990
|
-
|
|
917
|
+
logger4.error("get-slack-messages: channel not found", { channel });
|
|
991
918
|
throw new Error(
|
|
992
919
|
`Channel '${channel}' not found. Use get-slack-channels to see available channels.`
|
|
993
920
|
);
|
|
@@ -997,8 +924,9 @@ function createSlackTools(config = {}) {
|
|
|
997
924
|
const result = await slack.conversations.history({
|
|
998
925
|
channel: channelId,
|
|
999
926
|
limit: Math.min(limit, 100)
|
|
927
|
+
// Cap at 100 for performance
|
|
1000
928
|
});
|
|
1001
|
-
|
|
929
|
+
logger4.info("get-slack-messages result", {
|
|
1002
930
|
channel: channelId,
|
|
1003
931
|
messageCount: result.messages?.length || 0,
|
|
1004
932
|
limit
|
|
@@ -1016,7 +944,7 @@ function createSlackTools(config = {}) {
|
|
|
1016
944
|
})) || []
|
|
1017
945
|
};
|
|
1018
946
|
} catch (error) {
|
|
1019
|
-
|
|
947
|
+
logger4.error("get-slack-messages failed", {
|
|
1020
948
|
channel,
|
|
1021
949
|
error: error.message,
|
|
1022
950
|
data: error.data
|
|
@@ -1024,21 +952,50 @@ function createSlackTools(config = {}) {
|
|
|
1024
952
|
throw error;
|
|
1025
953
|
}
|
|
1026
954
|
}).build();
|
|
1027
|
-
return {
|
|
1028
|
-
sendMessage,
|
|
1029
|
-
notify,
|
|
1030
|
-
getChannels,
|
|
1031
|
-
getMessages
|
|
1032
|
-
};
|
|
1033
955
|
}
|
|
1034
|
-
var slackTools = [sendSlackMessage, notifySlack, getSlackChannels, getSlackMessages];
|
|
1035
956
|
|
|
1036
|
-
// src/web/
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
957
|
+
// src/web/slack/index.ts
|
|
958
|
+
var logLevel = process.env.LOG_LEVEL?.toLowerCase() || LogLevel.INFO;
|
|
959
|
+
var logger = createLogger("[tools:slack]", { level: logLevel });
|
|
960
|
+
var sendSlackMessage = createSendSlackMessageTool(getDefaultSlackClient, logger);
|
|
961
|
+
var notifySlack = createNotifySlackTool(getDefaultSlackClient, logger);
|
|
962
|
+
var getSlackChannels = createGetSlackChannelsTool(getDefaultSlackClient, logger);
|
|
963
|
+
var getSlackMessages = createGetSlackMessagesTool(getDefaultSlackClient, logger);
|
|
964
|
+
var slackTools = [
|
|
965
|
+
// Write tools
|
|
966
|
+
sendSlackMessage,
|
|
967
|
+
notifySlack,
|
|
968
|
+
// Read tools
|
|
969
|
+
getSlackChannels,
|
|
970
|
+
getSlackMessages
|
|
971
|
+
];
|
|
972
|
+
function createSlackTools(config = {}) {
|
|
973
|
+
const {
|
|
974
|
+
token,
|
|
975
|
+
botName = "AgentForge Bot",
|
|
976
|
+
botIcon = ":robot_face:",
|
|
977
|
+
logLevel: customLogLevel
|
|
978
|
+
} = config;
|
|
979
|
+
const getConfiguredSlackClient = createGetConfiguredSlackClient(token, botName, botIcon);
|
|
980
|
+
const toolLogger = customLogLevel ? createLogger("[tools:slack]", { level: customLogLevel }) : logger;
|
|
981
|
+
const sendMessage = createSendSlackMessageTool(getConfiguredSlackClient, toolLogger);
|
|
982
|
+
const notify = createNotifySlackTool(getConfiguredSlackClient, toolLogger);
|
|
983
|
+
const getChannels = createGetSlackChannelsTool(getConfiguredSlackClient, toolLogger);
|
|
984
|
+
const getMessages = createGetSlackMessagesTool(getConfiguredSlackClient, toolLogger);
|
|
985
|
+
return {
|
|
986
|
+
sendMessage,
|
|
987
|
+
notify,
|
|
988
|
+
getChannels,
|
|
989
|
+
getMessages
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
// src/web/confluence/auth.ts
|
|
994
|
+
function createGetConfiguredAuth(apiKey, email, siteUrl) {
|
|
995
|
+
return function getConfiguredAuth() {
|
|
996
|
+
const ATLASSIAN_API_KEY = apiKey || process.env.ATLASSIAN_API_KEY || "";
|
|
997
|
+
const ATLASSIAN_EMAIL = email || process.env.ATLASSIAN_EMAIL || "";
|
|
998
|
+
const ATLASSIAN_SITE_URL = (siteUrl || process.env.ATLASSIAN_SITE_URL || "").replace(/\/$/, "");
|
|
1042
999
|
if (!ATLASSIAN_API_KEY || !ATLASSIAN_EMAIL || !ATLASSIAN_SITE_URL) {
|
|
1043
1000
|
throw new Error(
|
|
1044
1001
|
"Confluence credentials not configured. Set ATLASSIAN_API_KEY, ATLASSIAN_EMAIL, and ATLASSIAN_SITE_URL in config or environment variables."
|
|
@@ -1076,7 +1033,7 @@ function createSearchConfluenceTool(getAuth, getAuthHeader2, logger4) {
|
|
|
1076
1033
|
logger4.info("search-confluence called", { query, limit });
|
|
1077
1034
|
try {
|
|
1078
1035
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1079
|
-
const response = await
|
|
1036
|
+
const response = await axios12.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/search`, {
|
|
1080
1037
|
headers: {
|
|
1081
1038
|
Authorization: getAuthHeader2(),
|
|
1082
1039
|
Accept: "application/json"
|
|
@@ -1138,7 +1095,7 @@ function createGetConfluencePageTool(getAuth, getAuthHeader2, logger4) {
|
|
|
1138
1095
|
logger4.info("get-confluence-page called", { page_id });
|
|
1139
1096
|
try {
|
|
1140
1097
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1141
|
-
const response = await
|
|
1098
|
+
const response = await axios12.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`, {
|
|
1142
1099
|
headers: {
|
|
1143
1100
|
Authorization: getAuthHeader2(),
|
|
1144
1101
|
Accept: "application/json"
|
|
@@ -1189,7 +1146,7 @@ function createListConfluenceSpacesTool(getAuth, getAuthHeader2, logger4) {
|
|
|
1189
1146
|
logger4.info("list-confluence-spaces called", { limit });
|
|
1190
1147
|
try {
|
|
1191
1148
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1192
|
-
const response = await
|
|
1149
|
+
const response = await axios12.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/space`, {
|
|
1193
1150
|
headers: {
|
|
1194
1151
|
Authorization: getAuthHeader2(),
|
|
1195
1152
|
Accept: "application/json"
|
|
@@ -1235,7 +1192,7 @@ function createGetSpacePagesTool(getAuth, getAuthHeader2, logger4) {
|
|
|
1235
1192
|
logger4.info("get-space-pages called", { space_key, limit });
|
|
1236
1193
|
try {
|
|
1237
1194
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1238
|
-
const response = await
|
|
1195
|
+
const response = await axios12.get(`${ATLASSIAN_SITE_URL}/wiki/rest/api/content`, {
|
|
1239
1196
|
headers: {
|
|
1240
1197
|
Authorization: getAuthHeader2(),
|
|
1241
1198
|
Accept: "application/json"
|
|
@@ -1309,7 +1266,7 @@ function createCreateConfluencePageTool(getAuth, getAuthHeader2, logger4) {
|
|
|
1309
1266
|
if (parent_page_id) {
|
|
1310
1267
|
pageData.ancestors = [{ id: parent_page_id }];
|
|
1311
1268
|
}
|
|
1312
|
-
const response = await
|
|
1269
|
+
const response = await axios12.post(
|
|
1313
1270
|
`${ATLASSIAN_SITE_URL}/wiki/rest/api/content`,
|
|
1314
1271
|
pageData,
|
|
1315
1272
|
{
|
|
@@ -1357,7 +1314,7 @@ function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger4) {
|
|
|
1357
1314
|
logger4.info("update-confluence-page called", { page_id, title });
|
|
1358
1315
|
try {
|
|
1359
1316
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1360
|
-
const getResponse = await
|
|
1317
|
+
const getResponse = await axios12.get(
|
|
1361
1318
|
`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`,
|
|
1362
1319
|
{
|
|
1363
1320
|
headers: {
|
|
@@ -1367,7 +1324,7 @@ function createUpdateConfluencePageTool(getAuth, getAuthHeader2, logger4) {
|
|
|
1367
1324
|
}
|
|
1368
1325
|
);
|
|
1369
1326
|
const currentVersion = getResponse.data.version.number;
|
|
1370
|
-
const updateResponse = await
|
|
1327
|
+
const updateResponse = await axios12.put(
|
|
1371
1328
|
`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`,
|
|
1372
1329
|
{
|
|
1373
1330
|
type: "page",
|
|
@@ -1425,7 +1382,7 @@ function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger4) {
|
|
|
1425
1382
|
logger4.info("archive-confluence-page called", { page_id, reason });
|
|
1426
1383
|
try {
|
|
1427
1384
|
const { ATLASSIAN_SITE_URL } = getAuth();
|
|
1428
|
-
const getResponse = await
|
|
1385
|
+
const getResponse = await axios12.get(
|
|
1429
1386
|
`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`,
|
|
1430
1387
|
{
|
|
1431
1388
|
headers: {
|
|
@@ -1436,7 +1393,7 @@ function createArchiveConfluencePageTool(getAuth, getAuthHeader2, logger4) {
|
|
|
1436
1393
|
);
|
|
1437
1394
|
const currentVersion = getResponse.data.version.number;
|
|
1438
1395
|
const pageData = getResponse.data;
|
|
1439
|
-
await
|
|
1396
|
+
await axios12.put(
|
|
1440
1397
|
`${ATLASSIAN_SITE_URL}/wiki/rest/api/content/${page_id}`,
|
|
1441
1398
|
{
|
|
1442
1399
|
version: { number: currentVersion + 1 },
|
|
@@ -1532,1204 +1489,1664 @@ function createConfluenceTools(config = {}) {
|
|
|
1532
1489
|
archiveConfluencePage: archiveConfluencePage2
|
|
1533
1490
|
};
|
|
1534
1491
|
}
|
|
1535
|
-
var
|
|
1536
|
-
json: z.string().describe("JSON string to parse"),
|
|
1537
|
-
strict: z.boolean().default(true).describe("Use strict JSON parsing (no trailing commas, etc.)")
|
|
1538
|
-
})).implementSafe(async (input) => {
|
|
1539
|
-
const parsed = JSON.parse(input.json);
|
|
1540
|
-
return {
|
|
1541
|
-
data: parsed,
|
|
1542
|
-
type: Array.isArray(parsed) ? "array" : typeof parsed
|
|
1543
|
-
};
|
|
1544
|
-
}).build();
|
|
1545
|
-
var jsonStringify = toolBuilder().name("json-stringify").description("Convert an object to a JSON string with optional formatting (pretty print).").category(ToolCategory.UTILITY).tags(["json", "stringify", "format", "data"]).schema(z.object({
|
|
1546
|
-
data: z.any().describe("Data to convert to JSON string"),
|
|
1547
|
-
pretty: z.boolean().default(false).describe("Format with indentation for readability"),
|
|
1548
|
-
indent: z.number().default(2).describe("Number of spaces for indentation (when pretty is true)")
|
|
1549
|
-
})).implementSafe(async (input) => {
|
|
1550
|
-
const json = input.pretty ? JSON.stringify(input.data, null, input.indent) : JSON.stringify(input.data);
|
|
1551
|
-
return {
|
|
1552
|
-
json,
|
|
1553
|
-
length: json.length
|
|
1554
|
-
};
|
|
1555
|
-
}).build();
|
|
1556
|
-
var jsonQuery = toolBuilder().name("json-query").description('Query JSON data using dot notation path (e.g., "user.address.city"). Supports array indexing.').category(ToolCategory.UTILITY).tags(["json", "query", "path", "data"]).schema(z.object({
|
|
1557
|
-
data: z.any().describe("JSON data to query"),
|
|
1558
|
-
path: z.string().describe('Dot notation path to query (e.g., "user.name" or "items[0].id")')
|
|
1559
|
-
})).implementSafe(async (input) => {
|
|
1560
|
-
const parts = input.path.split(".");
|
|
1561
|
-
let current = input.data;
|
|
1562
|
-
for (const part of parts) {
|
|
1563
|
-
const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
|
|
1564
|
-
if (arrayMatch) {
|
|
1565
|
-
const [, key, index] = arrayMatch;
|
|
1566
|
-
current = current[key][parseInt(index, 10)];
|
|
1567
|
-
} else {
|
|
1568
|
-
current = current[part];
|
|
1569
|
-
}
|
|
1570
|
-
if (current === void 0) {
|
|
1571
|
-
throw new Error(`Path not found: ${input.path}`);
|
|
1572
|
-
}
|
|
1573
|
-
}
|
|
1574
|
-
return {
|
|
1575
|
-
value: current,
|
|
1576
|
-
type: Array.isArray(current) ? "array" : typeof current
|
|
1577
|
-
};
|
|
1578
|
-
}).build();
|
|
1579
|
-
var jsonValidator = toolBuilder().name("json-validator").description("Validate JSON string syntax without parsing. Returns whether the JSON is valid and any error details.").category(ToolCategory.UTILITY).tags(["json", "validate", "check", "data"]).schema(z.object({
|
|
1580
|
-
json: z.string().describe("JSON string to validate")
|
|
1581
|
-
})).implementSafe(async (input) => {
|
|
1582
|
-
JSON.parse(input.json);
|
|
1583
|
-
return {
|
|
1584
|
-
valid: true,
|
|
1585
|
-
message: "Valid JSON"
|
|
1586
|
-
};
|
|
1587
|
-
}).build();
|
|
1588
|
-
var jsonMerge = toolBuilder().name("json-merge").description("Merge two or more JSON objects. Later objects override earlier ones for conflicting keys.").category(ToolCategory.UTILITY).tags(["json", "merge", "combine", "data"]).schema(z.object({
|
|
1589
|
-
objects: z.array(z.any().describe("Object to merge")).describe("Array of objects to merge"),
|
|
1590
|
-
deep: z.boolean().default(false).describe("Perform deep merge (nested objects)")
|
|
1591
|
-
})).implement(async (input) => {
|
|
1592
|
-
if (input.deep) {
|
|
1593
|
-
const deepMerge = (target, source) => {
|
|
1594
|
-
const output = { ...target };
|
|
1595
|
-
for (const key in source) {
|
|
1596
|
-
if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
1597
|
-
output[key] = deepMerge(output[key] || {}, source[key]);
|
|
1598
|
-
} else {
|
|
1599
|
-
output[key] = source[key];
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
return output;
|
|
1603
|
-
};
|
|
1604
|
-
return input.objects.reduce((acc, obj) => deepMerge(acc, obj), {});
|
|
1605
|
-
} else {
|
|
1606
|
-
return Object.assign({}, ...input.objects);
|
|
1607
|
-
}
|
|
1608
|
-
}).build();
|
|
1609
|
-
var csvParser = toolBuilder().name("csv-parser").description("Parse CSV string into an array of objects. Supports custom delimiters, headers, and options.").category(ToolCategory.UTILITY).tags(["csv", "parse", "data", "table"]).schema(z.object({
|
|
1492
|
+
var csvParserSchema = z.object({
|
|
1610
1493
|
csv: z.string().describe("CSV string to parse"),
|
|
1611
1494
|
delimiter: z.string().default(",").describe("Column delimiter character"),
|
|
1612
1495
|
hasHeaders: z.boolean().default(true).describe("First row contains column headers"),
|
|
1613
1496
|
skipEmptyLines: z.boolean().default(true).describe("Skip empty lines in the CSV"),
|
|
1614
1497
|
trim: z.boolean().default(true).describe("Trim whitespace from values")
|
|
1615
|
-
})
|
|
1616
|
-
|
|
1617
|
-
const records = parse(input.csv, {
|
|
1618
|
-
delimiter: input.delimiter,
|
|
1619
|
-
columns: input.hasHeaders,
|
|
1620
|
-
skip_empty_lines: input.skipEmptyLines,
|
|
1621
|
-
trim: input.trim,
|
|
1622
|
-
relax_column_count: true
|
|
1623
|
-
});
|
|
1624
|
-
return {
|
|
1625
|
-
success: true,
|
|
1626
|
-
data: records,
|
|
1627
|
-
rowCount: records.length,
|
|
1628
|
-
columnCount: records.length > 0 ? Object.keys(records[0]).length : 0
|
|
1629
|
-
};
|
|
1630
|
-
} catch (error) {
|
|
1631
|
-
return {
|
|
1632
|
-
success: false,
|
|
1633
|
-
error: error instanceof Error ? error.message : "Failed to parse CSV"
|
|
1634
|
-
};
|
|
1635
|
-
}
|
|
1636
|
-
}).build();
|
|
1637
|
-
var csvGenerator = toolBuilder().name("csv-generator").description("Convert an array of objects to CSV string. Automatically extracts headers from object keys.").category(ToolCategory.UTILITY).tags(["csv", "generate", "stringify", "data"]).schema(z.object({
|
|
1498
|
+
});
|
|
1499
|
+
var csvGeneratorSchema = z.object({
|
|
1638
1500
|
data: z.array(z.record(z.any().describe("Column value"))).describe("Array of objects to convert to CSV"),
|
|
1639
1501
|
delimiter: z.string().default(",").describe("Column delimiter character"),
|
|
1640
1502
|
includeHeaders: z.boolean().default(true).describe("Include header row with column names"),
|
|
1641
1503
|
columns: z.array(z.string().describe("String value")).optional().describe("Optional list of columns to include (in order)")
|
|
1642
|
-
})
|
|
1643
|
-
|
|
1644
|
-
const csv = stringify(input.data, {
|
|
1645
|
-
delimiter: input.delimiter,
|
|
1646
|
-
header: input.includeHeaders,
|
|
1647
|
-
columns: input.columns
|
|
1648
|
-
});
|
|
1649
|
-
return {
|
|
1650
|
-
success: true,
|
|
1651
|
-
csv,
|
|
1652
|
-
rowCount: input.data.length
|
|
1653
|
-
};
|
|
1654
|
-
} catch (error) {
|
|
1655
|
-
return {
|
|
1656
|
-
success: false,
|
|
1657
|
-
error: error instanceof Error ? error.message : "Failed to generate CSV"
|
|
1658
|
-
};
|
|
1659
|
-
}
|
|
1660
|
-
}).build();
|
|
1661
|
-
var csvToJson = toolBuilder().name("csv-to-json").description("Convert CSV string to JSON array. Each row becomes an object with column headers as keys.").category(ToolCategory.UTILITY).tags(["csv", "json", "convert", "data"]).schema(z.object({
|
|
1504
|
+
});
|
|
1505
|
+
var csvToJsonSchema = z.object({
|
|
1662
1506
|
csv: z.string().describe("CSV string to convert"),
|
|
1663
1507
|
delimiter: z.string().default(",").describe("Column delimiter character"),
|
|
1664
1508
|
pretty: z.boolean().default(false).describe("Format JSON with indentation")
|
|
1665
|
-
})
|
|
1666
|
-
|
|
1667
|
-
const records = parse(input.csv, {
|
|
1668
|
-
delimiter: input.delimiter,
|
|
1669
|
-
columns: true,
|
|
1670
|
-
skip_empty_lines: true,
|
|
1671
|
-
trim: true
|
|
1672
|
-
});
|
|
1673
|
-
const json = input.pretty ? JSON.stringify(records, null, 2) : JSON.stringify(records);
|
|
1674
|
-
return {
|
|
1675
|
-
success: true,
|
|
1676
|
-
json,
|
|
1677
|
-
recordCount: records.length
|
|
1678
|
-
};
|
|
1679
|
-
} catch (error) {
|
|
1680
|
-
return {
|
|
1681
|
-
success: false,
|
|
1682
|
-
error: error instanceof Error ? error.message : "Failed to convert CSV to JSON"
|
|
1683
|
-
};
|
|
1684
|
-
}
|
|
1685
|
-
}).build();
|
|
1686
|
-
var jsonToCsv = toolBuilder().name("json-to-csv").description("Convert JSON array to CSV string. Each object becomes a row with keys as column headers.").category(ToolCategory.UTILITY).tags(["json", "csv", "convert", "data"]).schema(z.object({
|
|
1509
|
+
});
|
|
1510
|
+
var jsonToCsvSchema = z.object({
|
|
1687
1511
|
json: z.string().describe("JSON array string to convert"),
|
|
1688
1512
|
delimiter: z.string().default(",").describe("Column delimiter character")
|
|
1689
|
-
})
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1513
|
+
});
|
|
1514
|
+
function createCsvParserTool(defaultDelimiter = ",", defaultHasHeaders = true, defaultSkipEmptyLines = true, defaultTrim = true) {
|
|
1515
|
+
return toolBuilder().name("csv-parser").description("Parse CSV string into an array of objects. Supports custom delimiters, headers, and options.").category(ToolCategory.UTILITY).tags(["csv", "parse", "data", "table"]).schema(csvParserSchema).implement(async (input) => {
|
|
1516
|
+
try {
|
|
1517
|
+
const records = parse(input.csv, {
|
|
1518
|
+
delimiter: input.delimiter ?? defaultDelimiter,
|
|
1519
|
+
columns: input.hasHeaders ?? defaultHasHeaders,
|
|
1520
|
+
skip_empty_lines: input.skipEmptyLines ?? defaultSkipEmptyLines,
|
|
1521
|
+
trim: input.trim ?? defaultTrim,
|
|
1522
|
+
relax_column_count: true
|
|
1523
|
+
});
|
|
1524
|
+
return {
|
|
1525
|
+
success: true,
|
|
1526
|
+
data: records,
|
|
1527
|
+
rowCount: records.length,
|
|
1528
|
+
columnCount: records.length > 0 ? Object.keys(records[0]).length : 0
|
|
1529
|
+
};
|
|
1530
|
+
} catch (error) {
|
|
1693
1531
|
return {
|
|
1694
1532
|
success: false,
|
|
1695
|
-
error:
|
|
1533
|
+
error: error instanceof Error ? error.message : "Failed to parse CSV"
|
|
1696
1534
|
};
|
|
1697
1535
|
}
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1536
|
+
}).build();
|
|
1537
|
+
}
|
|
1538
|
+
function createCsvGeneratorTool(defaultDelimiter = ",") {
|
|
1539
|
+
return toolBuilder().name("csv-generator").description("Convert an array of objects to CSV string. Automatically extracts headers from object keys.").category(ToolCategory.UTILITY).tags(["csv", "generate", "stringify", "data"]).schema(csvGeneratorSchema).implement(async (input) => {
|
|
1540
|
+
try {
|
|
1541
|
+
const csv = stringify(input.data, {
|
|
1542
|
+
delimiter: input.delimiter ?? defaultDelimiter,
|
|
1543
|
+
header: input.includeHeaders,
|
|
1544
|
+
columns: input.columns
|
|
1545
|
+
});
|
|
1546
|
+
return {
|
|
1547
|
+
success: true,
|
|
1548
|
+
csv,
|
|
1549
|
+
rowCount: input.data.length
|
|
1550
|
+
};
|
|
1551
|
+
} catch (error) {
|
|
1552
|
+
return {
|
|
1553
|
+
success: false,
|
|
1554
|
+
error: error instanceof Error ? error.message : "Failed to generate CSV"
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
}).build();
|
|
1558
|
+
}
|
|
1559
|
+
function createCsvToJsonTool(defaultDelimiter = ",") {
|
|
1560
|
+
return toolBuilder().name("csv-to-json").description("Convert CSV string to JSON array. Each row becomes an object with column headers as keys.").category(ToolCategory.UTILITY).tags(["csv", "json", "convert", "data"]).schema(csvToJsonSchema).implement(async (input) => {
|
|
1561
|
+
try {
|
|
1562
|
+
const records = parse(input.csv, {
|
|
1563
|
+
delimiter: input.delimiter ?? defaultDelimiter,
|
|
1564
|
+
columns: true,
|
|
1565
|
+
skip_empty_lines: true,
|
|
1566
|
+
trim: true
|
|
1567
|
+
});
|
|
1568
|
+
const json = input.pretty ? JSON.stringify(records, null, 2) : JSON.stringify(records);
|
|
1569
|
+
return {
|
|
1570
|
+
success: true,
|
|
1571
|
+
json,
|
|
1572
|
+
recordCount: records.length
|
|
1573
|
+
};
|
|
1574
|
+
} catch (error) {
|
|
1575
|
+
return {
|
|
1576
|
+
success: false,
|
|
1577
|
+
error: error instanceof Error ? error.message : "Failed to convert CSV to JSON"
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
}).build();
|
|
1581
|
+
}
|
|
1582
|
+
function createJsonToCsvTool(defaultDelimiter = ",") {
|
|
1583
|
+
return toolBuilder().name("json-to-csv").description("Convert JSON array to CSV string. Each object becomes a row with keys as column headers.").category(ToolCategory.UTILITY).tags(["json", "csv", "convert", "data"]).schema(jsonToCsvSchema).implement(async (input) => {
|
|
1584
|
+
try {
|
|
1585
|
+
const data = JSON.parse(input.json);
|
|
1586
|
+
if (!Array.isArray(data)) {
|
|
1587
|
+
return {
|
|
1588
|
+
success: false,
|
|
1589
|
+
error: "Input must be a JSON array"
|
|
1590
|
+
};
|
|
1591
|
+
}
|
|
1592
|
+
const csv = stringify(data, {
|
|
1593
|
+
delimiter: input.delimiter ?? defaultDelimiter,
|
|
1594
|
+
header: true
|
|
1595
|
+
});
|
|
1596
|
+
return {
|
|
1597
|
+
success: true,
|
|
1598
|
+
csv,
|
|
1599
|
+
rowCount: data.length
|
|
1600
|
+
};
|
|
1601
|
+
} catch (error) {
|
|
1602
|
+
return {
|
|
1603
|
+
success: false,
|
|
1604
|
+
error: error instanceof Error ? error.message : "Failed to convert JSON to CSV"
|
|
1605
|
+
};
|
|
1606
|
+
}
|
|
1607
|
+
}).build();
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
// src/data/csv/index.ts
|
|
1611
|
+
var csvParser = createCsvParserTool();
|
|
1612
|
+
var csvGenerator = createCsvGeneratorTool();
|
|
1613
|
+
var csvToJson = createCsvToJsonTool();
|
|
1614
|
+
var jsonToCsv = createJsonToCsvTool();
|
|
1615
|
+
var csvTools = [csvParser, csvGenerator, csvToJson, jsonToCsv];
|
|
1616
|
+
function createCsvTools(config = {}) {
|
|
1617
|
+
const {
|
|
1618
|
+
defaultDelimiter = ",",
|
|
1619
|
+
defaultHasHeaders = true,
|
|
1620
|
+
defaultSkipEmptyLines = true,
|
|
1621
|
+
defaultTrim = true
|
|
1622
|
+
} = config;
|
|
1623
|
+
return [
|
|
1624
|
+
createCsvParserTool(defaultDelimiter, defaultHasHeaders, defaultSkipEmptyLines, defaultTrim),
|
|
1625
|
+
createCsvGeneratorTool(defaultDelimiter),
|
|
1626
|
+
createCsvToJsonTool(defaultDelimiter),
|
|
1627
|
+
createJsonToCsvTool(defaultDelimiter)
|
|
1628
|
+
];
|
|
1629
|
+
}
|
|
1630
|
+
var jsonParserSchema = z.object({
|
|
1631
|
+
json: z.string().describe("JSON string to parse"),
|
|
1632
|
+
strict: z.boolean().default(true).describe("Use strict JSON parsing (no trailing commas, etc.)")
|
|
1633
|
+
});
|
|
1634
|
+
var jsonStringifySchema = z.object({
|
|
1635
|
+
data: z.any().describe("Data to convert to JSON string"),
|
|
1636
|
+
pretty: z.boolean().default(false).describe("Format with indentation for readability"),
|
|
1637
|
+
indent: z.number().default(2).describe("Number of spaces for indentation (when pretty is true)")
|
|
1638
|
+
});
|
|
1639
|
+
var jsonQuerySchema = z.object({
|
|
1640
|
+
data: z.any().describe("JSON data to query"),
|
|
1641
|
+
path: z.string().describe('Dot notation path to query (e.g., "user.name" or "items[0].id")')
|
|
1642
|
+
});
|
|
1643
|
+
var jsonValidatorSchema = z.object({
|
|
1644
|
+
json: z.string().describe("JSON string to validate")
|
|
1645
|
+
});
|
|
1646
|
+
var jsonMergeSchema = z.object({
|
|
1647
|
+
objects: z.array(z.any().describe("Object to merge")).describe("Array of objects to merge"),
|
|
1648
|
+
deep: z.boolean().default(false).describe("Perform deep merge (nested objects)")
|
|
1649
|
+
});
|
|
1650
|
+
function createJsonParserTool() {
|
|
1651
|
+
return toolBuilder().name("json-parser").description("Parse JSON string into an object. Validates JSON syntax and returns parsed data or error details.").category(ToolCategory.UTILITY).tags(["json", "parse", "data"]).schema(jsonParserSchema).implementSafe(async (input) => {
|
|
1652
|
+
const parsed = JSON.parse(input.json);
|
|
1702
1653
|
return {
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
rowCount: data.length
|
|
1654
|
+
data: parsed,
|
|
1655
|
+
type: Array.isArray(parsed) ? "array" : typeof parsed
|
|
1706
1656
|
};
|
|
1707
|
-
}
|
|
1657
|
+
}).build();
|
|
1658
|
+
}
|
|
1659
|
+
function createJsonStringifyTool(defaultIndent = 2, defaultPretty = false) {
|
|
1660
|
+
return toolBuilder().name("json-stringify").description("Convert an object to a JSON string with optional formatting (pretty print).").category(ToolCategory.UTILITY).tags(["json", "stringify", "format", "data"]).schema(jsonStringifySchema).implementSafe(async (input) => {
|
|
1661
|
+
const pretty = input.pretty ?? defaultPretty;
|
|
1662
|
+
const indent = input.indent ?? defaultIndent;
|
|
1663
|
+
const json = pretty ? JSON.stringify(input.data, null, indent) : JSON.stringify(input.data);
|
|
1708
1664
|
return {
|
|
1709
|
-
|
|
1710
|
-
|
|
1665
|
+
json,
|
|
1666
|
+
length: json.length
|
|
1711
1667
|
};
|
|
1712
|
-
}
|
|
1713
|
-
}
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1668
|
+
}).build();
|
|
1669
|
+
}
|
|
1670
|
+
function createJsonQueryTool() {
|
|
1671
|
+
return toolBuilder().name("json-query").description('Query JSON data using dot notation path (e.g., "user.address.city"). Supports array indexing.').category(ToolCategory.UTILITY).tags(["json", "query", "path", "data"]).schema(jsonQuerySchema).implementSafe(async (input) => {
|
|
1672
|
+
const parts = input.path.split(".");
|
|
1673
|
+
let current = input.data;
|
|
1674
|
+
for (const part of parts) {
|
|
1675
|
+
const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
|
|
1676
|
+
if (arrayMatch) {
|
|
1677
|
+
const [, key, index] = arrayMatch;
|
|
1678
|
+
current = current[key][parseInt(index, 10)];
|
|
1679
|
+
} else {
|
|
1680
|
+
current = current[part];
|
|
1681
|
+
}
|
|
1682
|
+
if (current === void 0) {
|
|
1683
|
+
throw new Error(`Path not found: ${input.path}`);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1728
1686
|
return {
|
|
1729
|
-
|
|
1730
|
-
|
|
1687
|
+
value: current,
|
|
1688
|
+
type: Array.isArray(current) ? "array" : typeof current
|
|
1731
1689
|
};
|
|
1732
|
-
}
|
|
1690
|
+
}).build();
|
|
1691
|
+
}
|
|
1692
|
+
function createJsonValidatorTool() {
|
|
1693
|
+
return toolBuilder().name("json-validator").description("Validate JSON string syntax without parsing. Returns whether the JSON is valid and any error details.").category(ToolCategory.UTILITY).tags(["json", "validate", "check", "data"]).schema(jsonValidatorSchema).implementSafe(async (input) => {
|
|
1694
|
+
JSON.parse(input.json);
|
|
1733
1695
|
return {
|
|
1734
|
-
|
|
1735
|
-
|
|
1696
|
+
valid: true,
|
|
1697
|
+
message: "Valid JSON"
|
|
1736
1698
|
};
|
|
1737
|
-
}
|
|
1738
|
-
}
|
|
1739
|
-
|
|
1699
|
+
}).build();
|
|
1700
|
+
}
|
|
1701
|
+
function createJsonMergeTool() {
|
|
1702
|
+
return toolBuilder().name("json-merge").description("Merge two or more JSON objects. Later objects override earlier ones for conflicting keys.").category(ToolCategory.UTILITY).tags(["json", "merge", "combine", "data"]).schema(jsonMergeSchema).implement(async (input) => {
|
|
1703
|
+
if (input.deep) {
|
|
1704
|
+
const deepMerge = (target, source) => {
|
|
1705
|
+
const output = { ...target };
|
|
1706
|
+
for (const key in source) {
|
|
1707
|
+
if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
1708
|
+
output[key] = deepMerge(output[key] || {}, source[key]);
|
|
1709
|
+
} else {
|
|
1710
|
+
output[key] = source[key];
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
return output;
|
|
1714
|
+
};
|
|
1715
|
+
return input.objects.reduce((acc, obj) => deepMerge(acc, obj), {});
|
|
1716
|
+
} else {
|
|
1717
|
+
return Object.assign({}, ...input.objects);
|
|
1718
|
+
}
|
|
1719
|
+
}).build();
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
// src/data/json/index.ts
|
|
1723
|
+
var jsonParser = createJsonParserTool();
|
|
1724
|
+
var jsonStringify = createJsonStringifyTool();
|
|
1725
|
+
var jsonQuery = createJsonQueryTool();
|
|
1726
|
+
var jsonValidator = createJsonValidatorTool();
|
|
1727
|
+
var jsonMerge = createJsonMergeTool();
|
|
1728
|
+
var jsonTools = [jsonParser, jsonStringify, jsonQuery, jsonValidator, jsonMerge];
|
|
1729
|
+
function createJsonTools(config = {}) {
|
|
1730
|
+
const {
|
|
1731
|
+
defaultIndent = 2,
|
|
1732
|
+
defaultPretty = false
|
|
1733
|
+
} = config;
|
|
1734
|
+
return [
|
|
1735
|
+
createJsonParserTool(),
|
|
1736
|
+
createJsonStringifyTool(defaultIndent, defaultPretty),
|
|
1737
|
+
createJsonQueryTool(),
|
|
1738
|
+
createJsonValidatorTool(),
|
|
1739
|
+
createJsonMergeTool()
|
|
1740
|
+
];
|
|
1741
|
+
}
|
|
1742
|
+
var xmlParserSchema = z.object({
|
|
1743
|
+
xml: z.string().describe("XML string to parse"),
|
|
1744
|
+
ignoreAttributes: z.boolean().default(false).describe("Ignore XML attributes"),
|
|
1745
|
+
parseAttributeValue: z.boolean().default(true).describe("Parse attribute values (numbers, booleans)"),
|
|
1746
|
+
trimValues: z.boolean().default(true).describe("Trim whitespace from text values")
|
|
1747
|
+
});
|
|
1748
|
+
var xmlGeneratorSchema = z.object({
|
|
1740
1749
|
data: z.any().describe("Object to convert to XML"),
|
|
1741
1750
|
rootName: z.string().default("root").describe("Name of the root XML element"),
|
|
1742
1751
|
format: z.boolean().default(false).describe("Format XML with indentation"),
|
|
1743
1752
|
indentSize: z.number().default(2).describe("Number of spaces for indentation (when format is true)")
|
|
1744
|
-
})
|
|
1745
|
-
|
|
1746
|
-
const indentSize = input.indentSize ?? 2;
|
|
1747
|
-
const rootName = input.rootName ?? "root";
|
|
1748
|
-
const builder = new XMLBuilder({
|
|
1749
|
-
format: input.format ?? false,
|
|
1750
|
-
indentBy: " ".repeat(indentSize),
|
|
1751
|
-
ignoreAttributes: false
|
|
1752
|
-
});
|
|
1753
|
-
const dataToConvert = input.data[rootName] ? input.data : { [rootName]: input.data };
|
|
1754
|
-
const xml = builder.build(dataToConvert);
|
|
1755
|
-
return {
|
|
1756
|
-
success: true,
|
|
1757
|
-
xml
|
|
1758
|
-
};
|
|
1759
|
-
} catch (error) {
|
|
1760
|
-
return {
|
|
1761
|
-
success: false,
|
|
1762
|
-
error: error instanceof Error ? error.message : "Failed to generate XML"
|
|
1763
|
-
};
|
|
1764
|
-
}
|
|
1765
|
-
}).build();
|
|
1766
|
-
var xmlToJson = toolBuilder().name("xml-to-json").description("Convert XML string to JSON. Preserves structure and can include or exclude attributes.").category(ToolCategory.UTILITY).tags(["xml", "json", "convert", "data"]).schema(z.object({
|
|
1753
|
+
});
|
|
1754
|
+
var xmlToJsonSchema = z.object({
|
|
1767
1755
|
xml: z.string().describe("XML string to convert"),
|
|
1768
1756
|
ignoreAttributes: z.boolean().default(false).describe("Ignore XML attributes in conversion"),
|
|
1769
1757
|
pretty: z.boolean().default(false).describe("Format JSON with indentation")
|
|
1770
|
-
})
|
|
1771
|
-
|
|
1772
|
-
const parser = new XMLParser({
|
|
1773
|
-
ignoreAttributes: input.ignoreAttributes,
|
|
1774
|
-
parseAttributeValue: true,
|
|
1775
|
-
trimValues: true
|
|
1776
|
-
});
|
|
1777
|
-
const result = parser.parse(input.xml);
|
|
1778
|
-
const json = input.pretty ? JSON.stringify(result, null, 2) : JSON.stringify(result);
|
|
1779
|
-
return {
|
|
1780
|
-
success: true,
|
|
1781
|
-
json
|
|
1782
|
-
};
|
|
1783
|
-
} catch (error) {
|
|
1784
|
-
return {
|
|
1785
|
-
success: false,
|
|
1786
|
-
error: error instanceof Error ? error.message : "Failed to convert XML to JSON"
|
|
1787
|
-
};
|
|
1788
|
-
}
|
|
1789
|
-
}).build();
|
|
1790
|
-
var jsonToXml = toolBuilder().name("json-to-xml").description("Convert JSON string to XML. Each object key becomes an XML element.").category(ToolCategory.UTILITY).tags(["json", "xml", "convert", "data"]).schema(z.object({
|
|
1758
|
+
});
|
|
1759
|
+
var jsonToXmlSchema = z.object({
|
|
1791
1760
|
json: z.string().describe("JSON string to convert"),
|
|
1792
1761
|
rootName: z.string().default("root").describe("Name of the root XML element"),
|
|
1793
1762
|
format: z.boolean().default(false).describe("Format XML with indentation")
|
|
1794
|
-
})
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
}).build();
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1763
|
+
});
|
|
1764
|
+
function createXmlParserTool() {
|
|
1765
|
+
return toolBuilder().name("xml-parser").description("Parse XML string into a JavaScript object. Supports attributes, CDATA, and nested elements.").category(ToolCategory.UTILITY).tags(["xml", "parse", "data"]).schema(xmlParserSchema).implement(async (input) => {
|
|
1766
|
+
try {
|
|
1767
|
+
const parser = new XMLParser({
|
|
1768
|
+
ignoreAttributes: input.ignoreAttributes,
|
|
1769
|
+
parseAttributeValue: input.parseAttributeValue,
|
|
1770
|
+
trimValues: input.trimValues,
|
|
1771
|
+
parseTagValue: true
|
|
1772
|
+
});
|
|
1773
|
+
const result = parser.parse(input.xml);
|
|
1774
|
+
return {
|
|
1775
|
+
success: true,
|
|
1776
|
+
data: result
|
|
1777
|
+
};
|
|
1778
|
+
} catch (error) {
|
|
1779
|
+
return {
|
|
1780
|
+
success: false,
|
|
1781
|
+
error: error instanceof Error ? error.message : "Failed to parse XML"
|
|
1782
|
+
};
|
|
1783
|
+
}
|
|
1784
|
+
}).build();
|
|
1785
|
+
}
|
|
1786
|
+
function createXmlGeneratorTool(defaultRootName = "root", defaultFormat = false, defaultIndentSize = 2) {
|
|
1787
|
+
return toolBuilder().name("xml-generator").description("Convert a JavaScript object to XML string. Supports attributes, CDATA, and nested elements.").category(ToolCategory.UTILITY).tags(["xml", "generate", "stringify", "data"]).schema(xmlGeneratorSchema).implement(async (input) => {
|
|
1788
|
+
try {
|
|
1789
|
+
const indentSize = input.indentSize ?? defaultIndentSize;
|
|
1790
|
+
const rootName = input.rootName ?? defaultRootName;
|
|
1791
|
+
const format3 = input.format ?? defaultFormat;
|
|
1792
|
+
const builder = new XMLBuilder({
|
|
1793
|
+
format: format3,
|
|
1794
|
+
indentBy: " ".repeat(indentSize),
|
|
1795
|
+
ignoreAttributes: false
|
|
1796
|
+
});
|
|
1797
|
+
const dataToConvert = input.data[rootName] ? input.data : { [rootName]: input.data };
|
|
1798
|
+
const xml = builder.build(dataToConvert);
|
|
1799
|
+
return {
|
|
1800
|
+
success: true,
|
|
1801
|
+
xml
|
|
1802
|
+
};
|
|
1803
|
+
} catch (error) {
|
|
1804
|
+
return {
|
|
1805
|
+
success: false,
|
|
1806
|
+
error: error instanceof Error ? error.message : "Failed to generate XML"
|
|
1807
|
+
};
|
|
1808
|
+
}
|
|
1809
|
+
}).build();
|
|
1810
|
+
}
|
|
1811
|
+
function createXmlToJsonTool() {
|
|
1812
|
+
return toolBuilder().name("xml-to-json").description("Convert XML string to JSON. Preserves structure and can include or exclude attributes.").category(ToolCategory.UTILITY).tags(["xml", "json", "convert", "data"]).schema(xmlToJsonSchema).implement(async (input) => {
|
|
1813
|
+
try {
|
|
1814
|
+
const parser = new XMLParser({
|
|
1815
|
+
ignoreAttributes: input.ignoreAttributes,
|
|
1816
|
+
parseAttributeValue: true,
|
|
1817
|
+
trimValues: true
|
|
1818
|
+
});
|
|
1819
|
+
const result = parser.parse(input.xml);
|
|
1820
|
+
const json = input.pretty ? JSON.stringify(result, null, 2) : JSON.stringify(result);
|
|
1821
|
+
return {
|
|
1822
|
+
success: true,
|
|
1823
|
+
json
|
|
1824
|
+
};
|
|
1825
|
+
} catch (error) {
|
|
1826
|
+
return {
|
|
1827
|
+
success: false,
|
|
1828
|
+
error: error instanceof Error ? error.message : "Failed to convert XML to JSON"
|
|
1829
|
+
};
|
|
1830
|
+
}
|
|
1831
|
+
}).build();
|
|
1832
|
+
}
|
|
1833
|
+
function createJsonToXmlTool(defaultRootName = "root", defaultFormat = false) {
|
|
1834
|
+
return toolBuilder().name("json-to-xml").description("Convert JSON string to XML. Each object key becomes an XML element.").category(ToolCategory.UTILITY).tags(["json", "xml", "convert", "data"]).schema(jsonToXmlSchema).implement(async (input) => {
|
|
1835
|
+
try {
|
|
1836
|
+
const data = JSON.parse(input.json);
|
|
1837
|
+
const rootName = input.rootName ?? defaultRootName;
|
|
1838
|
+
const format3 = input.format ?? defaultFormat;
|
|
1839
|
+
const builder = new XMLBuilder({
|
|
1840
|
+
format: format3,
|
|
1841
|
+
indentBy: " ",
|
|
1842
|
+
ignoreAttributes: false
|
|
1843
|
+
});
|
|
1844
|
+
const dataToConvert = data[rootName] ? data : { [rootName]: data };
|
|
1845
|
+
const xml = builder.build(dataToConvert);
|
|
1846
|
+
return {
|
|
1847
|
+
success: true,
|
|
1848
|
+
xml
|
|
1849
|
+
};
|
|
1850
|
+
} catch (error) {
|
|
1851
|
+
return {
|
|
1852
|
+
success: false,
|
|
1853
|
+
error: error instanceof Error ? error.message : "Failed to convert JSON to XML"
|
|
1854
|
+
};
|
|
1855
|
+
}
|
|
1856
|
+
}).build();
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
// src/data/xml/index.ts
|
|
1860
|
+
var xmlParser = createXmlParserTool();
|
|
1861
|
+
var xmlGenerator = createXmlGeneratorTool();
|
|
1862
|
+
var xmlToJson = createXmlToJsonTool();
|
|
1863
|
+
var jsonToXml = createJsonToXmlTool();
|
|
1864
|
+
var xmlTools = [xmlParser, xmlGenerator, xmlToJson, jsonToXml];
|
|
1865
|
+
function createXmlTools(config = {}) {
|
|
1866
|
+
const {
|
|
1867
|
+
defaultRootName = "root",
|
|
1868
|
+
defaultFormat = false,
|
|
1869
|
+
defaultIndentSize = 2
|
|
1870
|
+
} = config;
|
|
1871
|
+
return [
|
|
1872
|
+
createXmlParserTool(),
|
|
1873
|
+
createXmlGeneratorTool(defaultRootName, defaultFormat, defaultIndentSize),
|
|
1874
|
+
createXmlToJsonTool(),
|
|
1875
|
+
createJsonToXmlTool(defaultRootName, defaultFormat)
|
|
1876
|
+
];
|
|
1877
|
+
}
|
|
1878
|
+
var arrayFilterSchema = z.object({
|
|
1879
|
+
array: z.array(z.any().describe("Array element")).describe("Array to filter"),
|
|
1880
|
+
property: z.string().describe("Property name to filter by (use dot notation for nested properties)"),
|
|
1881
|
+
operator: z.enum(["equals", "not-equals", "greater-than", "less-than", "contains", "starts-with", "ends-with"]).describe("Comparison operator"),
|
|
1882
|
+
value: z.any().describe("Value to compare against")
|
|
1883
|
+
});
|
|
1884
|
+
var arrayMapSchema = z.object({
|
|
1853
1885
|
array: z.array(z.any().describe("Array element")).describe("Array to map"),
|
|
1854
1886
|
properties: z.array(z.string().describe("String value")).describe("List of property names to extract from each object")
|
|
1855
|
-
})
|
|
1856
|
-
|
|
1857
|
-
const result = {};
|
|
1858
|
-
for (const prop of input.properties) {
|
|
1859
|
-
const value = prop.split(".").reduce((current, key) => current?.[key], item);
|
|
1860
|
-
result[prop] = value;
|
|
1861
|
-
}
|
|
1862
|
-
return result;
|
|
1863
|
-
});
|
|
1864
|
-
return {
|
|
1865
|
-
mapped,
|
|
1866
|
-
count: mapped.length
|
|
1867
|
-
};
|
|
1868
|
-
}).build();
|
|
1869
|
-
var arraySort = toolBuilder().name("array-sort").description("Sort an array by a property value. Supports ascending and descending order.").category(ToolCategory.UTILITY).tags(["array", "sort", "data", "transform"]).schema(z.object({
|
|
1887
|
+
});
|
|
1888
|
+
var arraySortSchema = z.object({
|
|
1870
1889
|
array: z.array(z.any().describe("Array element")).describe("Array to sort"),
|
|
1871
1890
|
property: z.string().describe("Property name to sort by (use dot notation for nested properties)"),
|
|
1872
1891
|
order: z.enum(["asc", "desc"]).default("asc").describe("Sort order: ascending or descending")
|
|
1873
|
-
})
|
|
1874
|
-
|
|
1875
|
-
return path4.split(".").reduce((current, key) => current?.[key], obj);
|
|
1876
|
-
};
|
|
1877
|
-
const sorted = [...input.array].sort((a, b) => {
|
|
1878
|
-
const aValue = getNestedValue(a, input.property);
|
|
1879
|
-
const bValue = getNestedValue(b, input.property);
|
|
1880
|
-
if (aValue < bValue) return input.order === "asc" ? -1 : 1;
|
|
1881
|
-
if (aValue > bValue) return input.order === "asc" ? 1 : -1;
|
|
1882
|
-
return 0;
|
|
1883
|
-
});
|
|
1884
|
-
return {
|
|
1885
|
-
sorted,
|
|
1886
|
-
count: sorted.length
|
|
1887
|
-
};
|
|
1888
|
-
}).build();
|
|
1889
|
-
var arrayGroupBy = toolBuilder().name("array-group-by").description("Group an array of objects by a property value. Returns an object with groups as keys.").category(ToolCategory.UTILITY).tags(["array", "group", "data", "transform"]).schema(z.object({
|
|
1892
|
+
});
|
|
1893
|
+
var arrayGroupBySchema = z.object({
|
|
1890
1894
|
array: z.array(z.any().describe("Array element")).describe("Array to group"),
|
|
1891
1895
|
property: z.string().describe("Property name to group by")
|
|
1892
|
-
})
|
|
1893
|
-
|
|
1894
|
-
for (const item of input.array) {
|
|
1895
|
-
const key = String(item[input.property]);
|
|
1896
|
-
if (!groups[key]) {
|
|
1897
|
-
groups[key] = [];
|
|
1898
|
-
}
|
|
1899
|
-
groups[key].push(item);
|
|
1900
|
-
}
|
|
1901
|
-
return {
|
|
1902
|
-
groups,
|
|
1903
|
-
groupCount: Object.keys(groups).length,
|
|
1904
|
-
totalItems: input.array.length
|
|
1905
|
-
};
|
|
1906
|
-
}).build();
|
|
1907
|
-
var objectPick = toolBuilder().name("object-pick").description("Create a new object with only the specified properties from the source object.").category(ToolCategory.UTILITY).tags(["object", "pick", "data", "transform"]).schema(z.object({
|
|
1896
|
+
});
|
|
1897
|
+
var objectPickSchema = z.object({
|
|
1908
1898
|
object: z.record(z.any().describe("Property value")).describe("Source object"),
|
|
1909
1899
|
properties: z.array(z.string().describe("String value")).describe("List of property names to pick")
|
|
1910
|
-
})
|
|
1911
|
-
|
|
1912
|
-
for (const prop of input.properties) {
|
|
1913
|
-
if (prop in input.object) {
|
|
1914
|
-
picked[prop] = input.object[prop];
|
|
1915
|
-
}
|
|
1916
|
-
}
|
|
1917
|
-
return picked;
|
|
1918
|
-
}).build();
|
|
1919
|
-
var objectOmit = toolBuilder().name("object-omit").description("Create a new object excluding the specified properties from the source object.").category(ToolCategory.UTILITY).tags(["object", "omit", "data", "transform"]).schema(z.object({
|
|
1900
|
+
});
|
|
1901
|
+
var objectOmitSchema = z.object({
|
|
1920
1902
|
object: z.record(z.any().describe("Property value")).describe("Source object"),
|
|
1921
1903
|
properties: z.array(z.string().describe("String value")).describe("List of property names to omit")
|
|
1922
|
-
})
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1904
|
+
});
|
|
1905
|
+
function createArrayFilterTool() {
|
|
1906
|
+
return toolBuilder().name("array-filter").description("Filter an array based on a property value. Supports equality, comparison, and contains operations.").category(ToolCategory.UTILITY).tags(["array", "filter", "data", "transform"]).schema(arrayFilterSchema).implement(async (input) => {
|
|
1907
|
+
const getNestedValue = (obj, path12) => {
|
|
1908
|
+
return path12.split(".").reduce((current, key) => current?.[key], obj);
|
|
1909
|
+
};
|
|
1910
|
+
const filtered = input.array.filter((item) => {
|
|
1911
|
+
const itemValue = getNestedValue(item, input.property);
|
|
1912
|
+
switch (input.operator) {
|
|
1913
|
+
case "equals":
|
|
1914
|
+
return itemValue === input.value;
|
|
1915
|
+
case "not-equals":
|
|
1916
|
+
return itemValue !== input.value;
|
|
1917
|
+
case "greater-than":
|
|
1918
|
+
return itemValue > input.value;
|
|
1919
|
+
case "less-than":
|
|
1920
|
+
return itemValue < input.value;
|
|
1921
|
+
case "contains":
|
|
1922
|
+
return String(itemValue).includes(String(input.value));
|
|
1923
|
+
case "starts-with":
|
|
1924
|
+
return String(itemValue).startsWith(String(input.value));
|
|
1925
|
+
case "ends-with":
|
|
1926
|
+
return String(itemValue).endsWith(String(input.value));
|
|
1927
|
+
default:
|
|
1928
|
+
return false;
|
|
1929
|
+
}
|
|
1930
|
+
});
|
|
1931
|
+
return {
|
|
1932
|
+
filtered,
|
|
1933
|
+
originalCount: input.array.length,
|
|
1934
|
+
filteredCount: filtered.length
|
|
1935
|
+
};
|
|
1936
|
+
}).build();
|
|
1937
|
+
}
|
|
1938
|
+
function createArrayMapTool() {
|
|
1939
|
+
return toolBuilder().name("array-map").description("Extract specific properties from each object in an array. Creates a new array with only the selected properties.").category(ToolCategory.UTILITY).tags(["array", "map", "data", "transform"]).schema(arrayMapSchema).implement(async (input) => {
|
|
1940
|
+
const mapped = input.array.map((item) => {
|
|
1941
|
+
const result = {};
|
|
1942
|
+
for (const prop of input.properties) {
|
|
1943
|
+
const value = prop.split(".").reduce((current, key) => current?.[key], item);
|
|
1944
|
+
result[prop] = value;
|
|
1945
|
+
}
|
|
1946
|
+
return result;
|
|
1947
|
+
});
|
|
1948
|
+
return {
|
|
1949
|
+
mapped,
|
|
1950
|
+
count: mapped.length
|
|
1951
|
+
};
|
|
1952
|
+
}).build();
|
|
1953
|
+
}
|
|
1954
|
+
function createArraySortTool() {
|
|
1955
|
+
return toolBuilder().name("array-sort").description("Sort an array by a property value. Supports ascending and descending order.").category(ToolCategory.UTILITY).tags(["array", "sort", "data", "transform"]).schema(arraySortSchema).implement(async (input) => {
|
|
1956
|
+
const getNestedValue = (obj, path12) => {
|
|
1957
|
+
return path12.split(".").reduce((current, key) => current?.[key], obj);
|
|
1958
|
+
};
|
|
1959
|
+
const sorted = [...input.array].sort((a, b) => {
|
|
1960
|
+
const aValue = getNestedValue(a, input.property);
|
|
1961
|
+
const bValue = getNestedValue(b, input.property);
|
|
1962
|
+
if (aValue < bValue) return input.order === "asc" ? -1 : 1;
|
|
1963
|
+
if (aValue > bValue) return input.order === "asc" ? 1 : -1;
|
|
1964
|
+
return 0;
|
|
1965
|
+
});
|
|
1966
|
+
return {
|
|
1967
|
+
sorted,
|
|
1968
|
+
count: sorted.length
|
|
1969
|
+
};
|
|
1970
|
+
}).build();
|
|
1971
|
+
}
|
|
1972
|
+
function createArrayGroupByTool() {
|
|
1973
|
+
return toolBuilder().name("array-group-by").description("Group an array of objects by a property value. Returns an object with groups as keys.").category(ToolCategory.UTILITY).tags(["array", "group", "data", "transform"]).schema(arrayGroupBySchema).implement(async (input) => {
|
|
1974
|
+
const groups = {};
|
|
1975
|
+
for (const item of input.array) {
|
|
1976
|
+
const key = String(item[input.property]);
|
|
1977
|
+
if (!groups[key]) {
|
|
1978
|
+
groups[key] = [];
|
|
1979
|
+
}
|
|
1980
|
+
groups[key].push(item);
|
|
1981
|
+
}
|
|
1982
|
+
return {
|
|
1983
|
+
groups,
|
|
1984
|
+
groupCount: Object.keys(groups).length,
|
|
1985
|
+
totalItems: input.array.length
|
|
1986
|
+
};
|
|
1987
|
+
}).build();
|
|
1988
|
+
}
|
|
1989
|
+
function createObjectPickTool() {
|
|
1990
|
+
return toolBuilder().name("object-pick").description("Create a new object with only the specified properties from the source object.").category(ToolCategory.UTILITY).tags(["object", "pick", "data", "transform"]).schema(objectPickSchema).implement(async (input) => {
|
|
1991
|
+
const picked = {};
|
|
1992
|
+
for (const prop of input.properties) {
|
|
1993
|
+
if (prop in input.object) {
|
|
1994
|
+
picked[prop] = input.object[prop];
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
return picked;
|
|
1998
|
+
}).build();
|
|
1999
|
+
}
|
|
2000
|
+
function createObjectOmitTool() {
|
|
2001
|
+
return toolBuilder().name("object-omit").description("Create a new object excluding the specified properties from the source object.").category(ToolCategory.UTILITY).tags(["object", "omit", "data", "transform"]).schema(objectOmitSchema).implement(async (input) => {
|
|
2002
|
+
const omitted = { ...input.object };
|
|
2003
|
+
for (const prop of input.properties) {
|
|
2004
|
+
delete omitted[prop];
|
|
2005
|
+
}
|
|
2006
|
+
return omitted;
|
|
2007
|
+
}).build();
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
// src/data/transformer/index.ts
|
|
2011
|
+
var arrayFilter = createArrayFilterTool();
|
|
2012
|
+
var arrayMap = createArrayMapTool();
|
|
2013
|
+
var arraySort = createArraySortTool();
|
|
2014
|
+
var arrayGroupBy = createArrayGroupByTool();
|
|
2015
|
+
var objectPick = createObjectPickTool();
|
|
2016
|
+
var objectOmit = createObjectOmitTool();
|
|
2017
|
+
var transformerTools = [arrayFilter, arrayMap, arraySort, arrayGroupBy, objectPick, objectOmit];
|
|
2018
|
+
function createTransformerTools(config = {}) {
|
|
2019
|
+
return [
|
|
2020
|
+
createArrayFilterTool(),
|
|
2021
|
+
createArrayMapTool(),
|
|
2022
|
+
createArraySortTool(),
|
|
2023
|
+
createArrayGroupByTool(),
|
|
2024
|
+
createObjectPickTool(),
|
|
2025
|
+
createObjectOmitTool()
|
|
2026
|
+
];
|
|
2027
|
+
}
|
|
2028
|
+
var fileReaderSchema = z.object({
|
|
1930
2029
|
path: z.string().describe("Path to the file to read"),
|
|
1931
2030
|
encoding: z.enum(["utf8", "utf-8", "ascii", "base64", "hex", "binary"]).default("utf8").describe("File encoding")
|
|
1932
|
-
})
|
|
1933
|
-
|
|
1934
|
-
const stats = await promises.stat(input.path);
|
|
1935
|
-
return {
|
|
1936
|
-
content,
|
|
1937
|
-
size: stats.size,
|
|
1938
|
-
path: input.path,
|
|
1939
|
-
encoding: input.encoding
|
|
1940
|
-
};
|
|
1941
|
-
}).build();
|
|
1942
|
-
var fileWriter = toolBuilder().name("file-writer").description("Write content to a file. Creates the file if it doesn't exist, or overwrites it if it does.").category(ToolCategory.FILE_SYSTEM).tags(["file", "write", "io", "filesystem"]).schema(z.object({
|
|
2031
|
+
});
|
|
2032
|
+
var fileWriterSchema = z.object({
|
|
1943
2033
|
path: z.string().describe("Path to the file to write"),
|
|
1944
2034
|
content: z.string().describe("Content to write to the file"),
|
|
1945
2035
|
encoding: z.enum(["utf8", "utf-8", "ascii", "base64", "hex"]).default("utf8").describe("File encoding"),
|
|
1946
2036
|
createDirs: z.boolean().default(false).describe("Create parent directories if they don't exist")
|
|
1947
|
-
})
|
|
1948
|
-
|
|
1949
|
-
const dir = path3.dirname(input.path);
|
|
1950
|
-
await promises.mkdir(dir, { recursive: true });
|
|
1951
|
-
}
|
|
1952
|
-
await promises.writeFile(input.path, input.content, input.encoding);
|
|
1953
|
-
const stats = await promises.stat(input.path);
|
|
1954
|
-
return {
|
|
1955
|
-
path: input.path,
|
|
1956
|
-
size: stats.size,
|
|
1957
|
-
encoding: input.encoding
|
|
1958
|
-
};
|
|
1959
|
-
}).build();
|
|
1960
|
-
var fileAppend = toolBuilder().name("file-append").description("Append content to the end of a file. Creates the file if it doesn't exist.").category(ToolCategory.FILE_SYSTEM).tags(["file", "append", "io", "filesystem"]).schema(z.object({
|
|
2037
|
+
});
|
|
2038
|
+
var fileAppendSchema = z.object({
|
|
1961
2039
|
path: z.string().describe("Path to the file to append to"),
|
|
1962
2040
|
content: z.string().describe("Content to append to the file"),
|
|
1963
2041
|
encoding: z.enum(["utf8", "utf-8", "ascii"]).default("utf8").describe("File encoding")
|
|
1964
|
-
})
|
|
1965
|
-
|
|
1966
|
-
const stats = await promises.stat(input.path);
|
|
1967
|
-
return {
|
|
1968
|
-
path: input.path,
|
|
1969
|
-
size: stats.size
|
|
1970
|
-
};
|
|
1971
|
-
}).build();
|
|
1972
|
-
var fileDelete = toolBuilder().name("file-delete").description("Delete a file from the file system. Returns an error if the file doesn't exist.").category(ToolCategory.FILE_SYSTEM).tags(["file", "delete", "remove", "filesystem"]).schema(z.object({
|
|
2042
|
+
});
|
|
2043
|
+
var fileDeleteSchema = z.object({
|
|
1973
2044
|
path: z.string().describe("Path to the file to delete")
|
|
1974
|
-
})
|
|
1975
|
-
|
|
1976
|
-
return {
|
|
1977
|
-
path: input.path,
|
|
1978
|
-
message: "File deleted successfully"
|
|
1979
|
-
};
|
|
1980
|
-
}).build();
|
|
1981
|
-
var fileExists = toolBuilder().name("file-exists").description("Check if a file or directory exists at the specified path.").category(ToolCategory.FILE_SYSTEM).tags(["file", "exists", "check", "filesystem"]).schema(z.object({
|
|
2045
|
+
});
|
|
2046
|
+
var fileExistsSchema = z.object({
|
|
1982
2047
|
path: z.string().describe("Path to check")
|
|
1983
|
-
})
|
|
1984
|
-
|
|
1985
|
-
|
|
2048
|
+
});
|
|
2049
|
+
function createFileReaderTool(defaultEncoding = "utf8") {
|
|
2050
|
+
return toolBuilder().name("file-reader").description("Read the contents of a file from the file system. Supports text and binary files with various encodings.").category(ToolCategory.FILE_SYSTEM).tags(["file", "read", "io", "filesystem"]).schema(fileReaderSchema).implementSafe(async (input) => {
|
|
2051
|
+
const encoding = input.encoding || defaultEncoding;
|
|
2052
|
+
const content = await promises.readFile(input.path, encoding);
|
|
2053
|
+
const stats = await promises.stat(input.path);
|
|
2054
|
+
return {
|
|
2055
|
+
content,
|
|
2056
|
+
size: stats.size,
|
|
2057
|
+
path: input.path,
|
|
2058
|
+
encoding
|
|
2059
|
+
};
|
|
2060
|
+
}).build();
|
|
2061
|
+
}
|
|
2062
|
+
function createFileWriterTool(defaultEncoding = "utf8", createDirsDefault = false) {
|
|
2063
|
+
return toolBuilder().name("file-writer").description("Write content to a file. Creates the file if it doesn't exist, or overwrites it if it does.").category(ToolCategory.FILE_SYSTEM).tags(["file", "write", "io", "filesystem"]).schema(fileWriterSchema).implementSafe(async (input) => {
|
|
2064
|
+
const encoding = input.encoding || defaultEncoding;
|
|
2065
|
+
const createDirs = input.createDirs ?? createDirsDefault;
|
|
2066
|
+
if (createDirs) {
|
|
2067
|
+
const dir = path7.dirname(input.path);
|
|
2068
|
+
await promises.mkdir(dir, { recursive: true });
|
|
2069
|
+
}
|
|
2070
|
+
await promises.writeFile(input.path, input.content, encoding);
|
|
1986
2071
|
const stats = await promises.stat(input.path);
|
|
1987
2072
|
return {
|
|
1988
|
-
exists: true,
|
|
1989
2073
|
path: input.path,
|
|
1990
|
-
isFile: stats.isFile(),
|
|
1991
|
-
isDirectory: stats.isDirectory(),
|
|
1992
2074
|
size: stats.size,
|
|
1993
|
-
|
|
2075
|
+
encoding
|
|
1994
2076
|
};
|
|
1995
|
-
}
|
|
2077
|
+
}).build();
|
|
2078
|
+
}
|
|
2079
|
+
function createFileAppendTool(defaultEncoding = "utf8") {
|
|
2080
|
+
return toolBuilder().name("file-append").description("Append content to the end of a file. Creates the file if it doesn't exist.").category(ToolCategory.FILE_SYSTEM).tags(["file", "append", "io", "filesystem"]).schema(fileAppendSchema).implementSafe(async (input) => {
|
|
2081
|
+
const encoding = input.encoding || defaultEncoding;
|
|
2082
|
+
await promises.appendFile(input.path, input.content, encoding);
|
|
2083
|
+
const stats = await promises.stat(input.path);
|
|
1996
2084
|
return {
|
|
1997
|
-
|
|
1998
|
-
|
|
2085
|
+
path: input.path,
|
|
2086
|
+
size: stats.size
|
|
1999
2087
|
};
|
|
2000
|
-
}
|
|
2001
|
-
}
|
|
2002
|
-
|
|
2088
|
+
}).build();
|
|
2089
|
+
}
|
|
2090
|
+
function createFileDeleteTool() {
|
|
2091
|
+
return toolBuilder().name("file-delete").description("Delete a file from the file system. Returns an error if the file doesn't exist.").category(ToolCategory.FILE_SYSTEM).tags(["file", "delete", "remove", "filesystem"]).schema(fileDeleteSchema).implementSafe(async (input) => {
|
|
2092
|
+
await promises.unlink(input.path);
|
|
2093
|
+
return {
|
|
2094
|
+
path: input.path,
|
|
2095
|
+
message: "File deleted successfully"
|
|
2096
|
+
};
|
|
2097
|
+
}).build();
|
|
2098
|
+
}
|
|
2099
|
+
function createFileExistsTool() {
|
|
2100
|
+
return toolBuilder().name("file-exists").description("Check if a file or directory exists at the specified path.").category(ToolCategory.FILE_SYSTEM).tags(["file", "exists", "check", "filesystem"]).schema(fileExistsSchema).implement(async (input) => {
|
|
2101
|
+
try {
|
|
2102
|
+
await promises.access(input.path);
|
|
2103
|
+
const stats = await promises.stat(input.path);
|
|
2104
|
+
return {
|
|
2105
|
+
exists: true,
|
|
2106
|
+
path: input.path,
|
|
2107
|
+
isFile: stats.isFile(),
|
|
2108
|
+
isDirectory: stats.isDirectory(),
|
|
2109
|
+
size: stats.size,
|
|
2110
|
+
modified: stats.mtime.toISOString()
|
|
2111
|
+
};
|
|
2112
|
+
} catch {
|
|
2113
|
+
return {
|
|
2114
|
+
exists: false,
|
|
2115
|
+
path: input.path
|
|
2116
|
+
};
|
|
2117
|
+
}
|
|
2118
|
+
}).build();
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
// src/file/operations/index.ts
|
|
2122
|
+
var fileReader = createFileReaderTool();
|
|
2123
|
+
var fileWriter = createFileWriterTool();
|
|
2124
|
+
var fileAppend = createFileAppendTool();
|
|
2125
|
+
var fileDelete = createFileDeleteTool();
|
|
2126
|
+
var fileExists = createFileExistsTool();
|
|
2127
|
+
var fileOperationTools = [
|
|
2128
|
+
fileReader,
|
|
2129
|
+
fileWriter,
|
|
2130
|
+
fileAppend,
|
|
2131
|
+
fileDelete,
|
|
2132
|
+
fileExists
|
|
2133
|
+
];
|
|
2134
|
+
function createFileOperationTools(config = {}) {
|
|
2135
|
+
const {
|
|
2136
|
+
defaultEncoding = "utf8",
|
|
2137
|
+
createDirsDefault = false
|
|
2138
|
+
} = config;
|
|
2139
|
+
return [
|
|
2140
|
+
createFileReaderTool(defaultEncoding),
|
|
2141
|
+
createFileWriterTool(defaultEncoding, createDirsDefault),
|
|
2142
|
+
createFileAppendTool(defaultEncoding),
|
|
2143
|
+
createFileDeleteTool(),
|
|
2144
|
+
createFileExistsTool()
|
|
2145
|
+
];
|
|
2146
|
+
}
|
|
2147
|
+
var directoryListSchema = z.object({
|
|
2003
2148
|
path: z.string().describe("Path to the directory to list"),
|
|
2004
2149
|
recursive: z.boolean().default(false).describe("List files recursively in subdirectories"),
|
|
2005
2150
|
includeDetails: z.boolean().default(false).describe("Include file size, type, and modification date"),
|
|
2006
2151
|
extension: z.string().optional().describe('Optional file extension filter (e.g., ".txt", ".js")')
|
|
2007
|
-
})
|
|
2008
|
-
|
|
2009
|
-
const entries = await promises.readdir(dir, { withFileTypes: true });
|
|
2010
|
-
const files2 = [];
|
|
2011
|
-
for (const entry of entries) {
|
|
2012
|
-
const fullPath = path3.join(dir, entry.name);
|
|
2013
|
-
const relativePath = path3.relative(input.path, fullPath);
|
|
2014
|
-
if (input.extension && !entry.name.endsWith(input.extension)) {
|
|
2015
|
-
if (!entry.isDirectory() || !recursive) {
|
|
2016
|
-
continue;
|
|
2017
|
-
}
|
|
2018
|
-
}
|
|
2019
|
-
if (input.includeDetails) {
|
|
2020
|
-
const stats = await promises.stat(fullPath);
|
|
2021
|
-
files2.push({
|
|
2022
|
-
name: entry.name,
|
|
2023
|
-
path: relativePath,
|
|
2024
|
-
fullPath,
|
|
2025
|
-
isFile: entry.isFile(),
|
|
2026
|
-
isDirectory: entry.isDirectory(),
|
|
2027
|
-
size: stats.size,
|
|
2028
|
-
modified: stats.mtime.toISOString()
|
|
2029
|
-
});
|
|
2030
|
-
} else {
|
|
2031
|
-
files2.push({
|
|
2032
|
-
name: entry.name,
|
|
2033
|
-
path: relativePath,
|
|
2034
|
-
isFile: entry.isFile(),
|
|
2035
|
-
isDirectory: entry.isDirectory()
|
|
2036
|
-
});
|
|
2037
|
-
}
|
|
2038
|
-
if (recursive && entry.isDirectory()) {
|
|
2039
|
-
const subFiles = await listFiles(fullPath, true);
|
|
2040
|
-
files2.push(...subFiles);
|
|
2041
|
-
}
|
|
2042
|
-
}
|
|
2043
|
-
return files2;
|
|
2044
|
-
};
|
|
2045
|
-
const files = await listFiles(input.path, input.recursive ?? false);
|
|
2046
|
-
return {
|
|
2047
|
-
path: input.path,
|
|
2048
|
-
files,
|
|
2049
|
-
count: files.length
|
|
2050
|
-
};
|
|
2051
|
-
}).build();
|
|
2052
|
-
var directoryCreate = toolBuilder().name("directory-create").description("Create a new directory. Can optionally create parent directories if they don't exist.").category(ToolCategory.FILE_SYSTEM).tags(["directory", "create", "mkdir", "filesystem"]).schema(z.object({
|
|
2152
|
+
});
|
|
2153
|
+
var directoryCreateSchema = z.object({
|
|
2053
2154
|
path: z.string().describe("Path to the directory to create"),
|
|
2054
2155
|
recursive: z.boolean().default(true).describe("Create parent directories if they don't exist")
|
|
2055
|
-
})
|
|
2056
|
-
|
|
2057
|
-
return {
|
|
2058
|
-
path: input.path,
|
|
2059
|
-
message: "Directory created successfully"
|
|
2060
|
-
};
|
|
2061
|
-
}).build();
|
|
2062
|
-
var directoryDelete = toolBuilder().name("directory-delete").description("Delete a directory. Can optionally delete non-empty directories recursively.").category(ToolCategory.FILE_SYSTEM).tags(["directory", "delete", "remove", "filesystem"]).schema(z.object({
|
|
2156
|
+
});
|
|
2157
|
+
var directoryDeleteSchema = z.object({
|
|
2063
2158
|
path: z.string().describe("Path to the directory to delete"),
|
|
2064
2159
|
recursive: z.boolean().default(false).describe("Delete directory and all its contents")
|
|
2065
|
-
})
|
|
2066
|
-
|
|
2067
|
-
return {
|
|
2068
|
-
path: input.path,
|
|
2069
|
-
message: "Directory deleted successfully"
|
|
2070
|
-
};
|
|
2071
|
-
}).build();
|
|
2072
|
-
var fileSearch = toolBuilder().name("file-search").description("Search for files by name pattern in a directory. Supports wildcards and recursive search.").category(ToolCategory.FILE_SYSTEM).tags(["file", "search", "find", "filesystem"]).schema(z.object({
|
|
2160
|
+
});
|
|
2161
|
+
var fileSearchSchema = z.object({
|
|
2073
2162
|
directory: z.string().describe("Directory to search in"),
|
|
2074
2163
|
pattern: z.string().describe("File name pattern to search for (supports * wildcard)"),
|
|
2075
2164
|
recursive: z.boolean().default(true).describe("Search in subdirectories"),
|
|
2076
2165
|
caseSensitive: z.boolean().default(false).describe("Case-sensitive pattern matching")
|
|
2077
|
-
})
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
const
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2166
|
+
});
|
|
2167
|
+
function createDirectoryListTool(defaultRecursive = false, defaultIncludeDetails = false) {
|
|
2168
|
+
return toolBuilder().name("directory-list").description("List all files and directories in a directory. Can optionally include file details and filter by extension.").category(ToolCategory.FILE_SYSTEM).tags(["directory", "list", "files", "filesystem"]).schema(directoryListSchema).implementSafe(async (input) => {
|
|
2169
|
+
const listFiles = async (dir, recursive2) => {
|
|
2170
|
+
const entries = await promises.readdir(dir, { withFileTypes: true });
|
|
2171
|
+
const files2 = [];
|
|
2172
|
+
for (const entry of entries) {
|
|
2173
|
+
const fullPath = path7.join(dir, entry.name);
|
|
2174
|
+
const relativePath = path7.relative(input.path, fullPath);
|
|
2175
|
+
if (input.extension && !entry.name.endsWith(input.extension)) {
|
|
2176
|
+
if (!entry.isDirectory() || !recursive2) {
|
|
2177
|
+
continue;
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
if (input.includeDetails) {
|
|
2181
|
+
const stats = await promises.stat(fullPath);
|
|
2182
|
+
files2.push({
|
|
2183
|
+
name: entry.name,
|
|
2184
|
+
path: relativePath,
|
|
2185
|
+
fullPath,
|
|
2186
|
+
isFile: entry.isFile(),
|
|
2187
|
+
isDirectory: entry.isDirectory(),
|
|
2188
|
+
size: stats.size,
|
|
2189
|
+
modified: stats.mtime.toISOString()
|
|
2190
|
+
});
|
|
2191
|
+
} else {
|
|
2192
|
+
files2.push({
|
|
2193
|
+
name: entry.name,
|
|
2194
|
+
path: relativePath,
|
|
2195
|
+
isFile: entry.isFile(),
|
|
2196
|
+
isDirectory: entry.isDirectory()
|
|
2197
|
+
});
|
|
2198
|
+
}
|
|
2199
|
+
if (recursive2 && entry.isDirectory()) {
|
|
2200
|
+
const subFiles = await listFiles(fullPath, true);
|
|
2201
|
+
files2.push(...subFiles);
|
|
2202
|
+
}
|
|
2087
2203
|
}
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2204
|
+
return files2;
|
|
2205
|
+
};
|
|
2206
|
+
const recursive = input.recursive ?? defaultRecursive;
|
|
2207
|
+
const files = await listFiles(input.path, recursive);
|
|
2208
|
+
return {
|
|
2209
|
+
path: input.path,
|
|
2210
|
+
files,
|
|
2211
|
+
count: files.length
|
|
2212
|
+
};
|
|
2213
|
+
}).build();
|
|
2214
|
+
}
|
|
2215
|
+
function createDirectoryCreateTool(defaultRecursive = true) {
|
|
2216
|
+
return toolBuilder().name("directory-create").description("Create a new directory. Can optionally create parent directories if they don't exist.").category(ToolCategory.FILE_SYSTEM).tags(["directory", "create", "mkdir", "filesystem"]).schema(directoryCreateSchema).implementSafe(async (input) => {
|
|
2217
|
+
const recursive = input.recursive ?? defaultRecursive;
|
|
2218
|
+
await promises.mkdir(input.path, { recursive });
|
|
2219
|
+
return {
|
|
2220
|
+
path: input.path,
|
|
2221
|
+
message: "Directory created successfully"
|
|
2222
|
+
};
|
|
2223
|
+
}).build();
|
|
2224
|
+
}
|
|
2225
|
+
function createDirectoryDeleteTool(defaultRecursive = false) {
|
|
2226
|
+
return toolBuilder().name("directory-delete").description("Delete a directory. Can optionally delete non-empty directories recursively.").category(ToolCategory.FILE_SYSTEM).tags(["directory", "delete", "remove", "filesystem"]).schema(directoryDeleteSchema).implementSafe(async (input) => {
|
|
2227
|
+
const recursive = input.recursive ?? defaultRecursive;
|
|
2228
|
+
await promises.rm(input.path, { recursive, force: false });
|
|
2229
|
+
return {
|
|
2230
|
+
path: input.path,
|
|
2231
|
+
message: "Directory deleted successfully"
|
|
2232
|
+
};
|
|
2233
|
+
}).build();
|
|
2234
|
+
}
|
|
2235
|
+
function createFileSearchTool(defaultRecursive = true, defaultCaseSensitive = false) {
|
|
2236
|
+
return toolBuilder().name("file-search").description("Search for files by name pattern in a directory. Supports wildcards and recursive search.").category(ToolCategory.FILE_SYSTEM).tags(["file", "search", "find", "filesystem"]).schema(fileSearchSchema).implementSafe(async (input) => {
|
|
2237
|
+
const recursive = input.recursive ?? defaultRecursive;
|
|
2238
|
+
const caseSensitive = input.caseSensitive ?? defaultCaseSensitive;
|
|
2239
|
+
const searchFiles = async (dir) => {
|
|
2240
|
+
const entries = await promises.readdir(dir, { withFileTypes: true });
|
|
2241
|
+
const matches2 = [];
|
|
2242
|
+
const regexPattern = input.pattern.replace(/\./g, "\\.").replace(/\*/g, ".*");
|
|
2243
|
+
const regex = new RegExp(`^${regexPattern}$`, caseSensitive ? "" : "i");
|
|
2244
|
+
for (const entry of entries) {
|
|
2245
|
+
const fullPath = path7.join(dir, entry.name);
|
|
2246
|
+
if (entry.isFile() && regex.test(entry.name)) {
|
|
2247
|
+
matches2.push(fullPath);
|
|
2248
|
+
}
|
|
2249
|
+
if (recursive && entry.isDirectory()) {
|
|
2250
|
+
const subMatches = await searchFiles(fullPath);
|
|
2251
|
+
matches2.push(...subMatches);
|
|
2252
|
+
}
|
|
2091
2253
|
}
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
};
|
|
2102
|
-
}
|
|
2103
|
-
|
|
2254
|
+
return matches2;
|
|
2255
|
+
};
|
|
2256
|
+
const matches = await searchFiles(input.directory);
|
|
2257
|
+
return {
|
|
2258
|
+
directory: input.directory,
|
|
2259
|
+
pattern: input.pattern,
|
|
2260
|
+
matches,
|
|
2261
|
+
count: matches.length
|
|
2262
|
+
};
|
|
2263
|
+
}).build();
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2266
|
+
// src/file/directory/index.ts
|
|
2267
|
+
var directoryList = createDirectoryListTool();
|
|
2268
|
+
var directoryCreate = createDirectoryCreateTool();
|
|
2269
|
+
var directoryDelete = createDirectoryDeleteTool();
|
|
2270
|
+
var fileSearch = createFileSearchTool();
|
|
2271
|
+
var directoryOperationTools = [
|
|
2272
|
+
directoryList,
|
|
2273
|
+
directoryCreate,
|
|
2274
|
+
directoryDelete,
|
|
2275
|
+
fileSearch
|
|
2276
|
+
];
|
|
2277
|
+
function createDirectoryOperationTools(config = {}) {
|
|
2278
|
+
const {
|
|
2279
|
+
defaultRecursive = false,
|
|
2280
|
+
defaultIncludeDetails = false,
|
|
2281
|
+
defaultCaseSensitive = false
|
|
2282
|
+
} = config;
|
|
2283
|
+
return [
|
|
2284
|
+
createDirectoryListTool(defaultRecursive, defaultIncludeDetails),
|
|
2285
|
+
createDirectoryCreateTool(true),
|
|
2286
|
+
// Always default to true for create
|
|
2287
|
+
createDirectoryDeleteTool(false),
|
|
2288
|
+
// Always default to false for delete (safety)
|
|
2289
|
+
createFileSearchTool(defaultRecursive, defaultCaseSensitive)
|
|
2290
|
+
];
|
|
2291
|
+
}
|
|
2292
|
+
var pathJoinSchema = z.object({
|
|
2104
2293
|
segments: z.array(z.string().describe("String value")).describe("Path segments to join")
|
|
2105
|
-
})
|
|
2106
|
-
|
|
2107
|
-
return {
|
|
2108
|
-
path: joined,
|
|
2109
|
-
segments: input.segments
|
|
2110
|
-
};
|
|
2111
|
-
}).build();
|
|
2112
|
-
var pathResolve = toolBuilder().name("path-resolve").description("Resolve a sequence of paths into an absolute path. Resolves relative paths from the current working directory.").category(ToolCategory.FILE_SYSTEM).tags(["path", "resolve", "absolute", "filesystem"]).schema(z.object({
|
|
2294
|
+
});
|
|
2295
|
+
var pathResolveSchema = z.object({
|
|
2113
2296
|
paths: z.array(z.string().describe("String value")).describe("Paths to resolve")
|
|
2114
|
-
})
|
|
2115
|
-
|
|
2116
|
-
return {
|
|
2117
|
-
path: resolved,
|
|
2118
|
-
isAbsolute: path3.isAbsolute(resolved)
|
|
2119
|
-
};
|
|
2120
|
-
}).build();
|
|
2121
|
-
var pathParse = toolBuilder().name("path-parse").description("Parse a file path into its components (directory, filename, extension, etc.).").category(ToolCategory.FILE_SYSTEM).tags(["path", "parse", "filesystem"]).schema(z.object({
|
|
2297
|
+
});
|
|
2298
|
+
var pathParseSchema = z.object({
|
|
2122
2299
|
path: z.string().describe("File path to parse")
|
|
2123
|
-
})
|
|
2124
|
-
|
|
2125
|
-
return {
|
|
2126
|
-
root: parsed.root,
|
|
2127
|
-
dir: parsed.dir,
|
|
2128
|
-
base: parsed.base,
|
|
2129
|
-
name: parsed.name,
|
|
2130
|
-
ext: parsed.ext,
|
|
2131
|
-
isAbsolute: path3.isAbsolute(input.path)
|
|
2132
|
-
};
|
|
2133
|
-
}).build();
|
|
2134
|
-
var pathBasename = toolBuilder().name("path-basename").description("Get the last portion of a path (filename with extension). Optionally remove the extension.").category(ToolCategory.FILE_SYSTEM).tags(["path", "basename", "filename", "filesystem"]).schema(z.object({
|
|
2300
|
+
});
|
|
2301
|
+
var pathBasenameSchema = z.object({
|
|
2135
2302
|
path: z.string().describe("File path"),
|
|
2136
2303
|
removeExtension: z.boolean().default(false).describe("Remove the file extension")
|
|
2137
|
-
})
|
|
2138
|
-
|
|
2139
|
-
return {
|
|
2140
|
-
basename: basename2,
|
|
2141
|
-
extension: path3.extname(input.path)
|
|
2142
|
-
};
|
|
2143
|
-
}).build();
|
|
2144
|
-
var pathDirname = toolBuilder().name("path-dirname").description("Get the directory name of a path (everything except the last portion).").category(ToolCategory.FILE_SYSTEM).tags(["path", "dirname", "directory", "filesystem"]).schema(z.object({
|
|
2304
|
+
});
|
|
2305
|
+
var pathDirnameSchema = z.object({
|
|
2145
2306
|
path: z.string().describe("File path")
|
|
2146
|
-
})
|
|
2147
|
-
|
|
2148
|
-
return {
|
|
2149
|
-
dirname: dirname3,
|
|
2150
|
-
basename: path3.basename(input.path)
|
|
2151
|
-
};
|
|
2152
|
-
}).build();
|
|
2153
|
-
var pathExtension = toolBuilder().name("path-extension").description('Get the file extension from a path (including the dot, e.g., ".txt").').category(ToolCategory.FILE_SYSTEM).tags(["path", "extension", "ext", "filesystem"]).schema(z.object({
|
|
2307
|
+
});
|
|
2308
|
+
var pathExtensionSchema = z.object({
|
|
2154
2309
|
path: z.string().describe("File path")
|
|
2155
|
-
})
|
|
2156
|
-
|
|
2157
|
-
return {
|
|
2158
|
-
extension: ext,
|
|
2159
|
-
hasExtension: ext.length > 0,
|
|
2160
|
-
filename: path3.basename(input.path, ext)
|
|
2161
|
-
};
|
|
2162
|
-
}).build();
|
|
2163
|
-
var pathRelative = toolBuilder().name("path-relative").description("Get the relative path from one path to another.").category(ToolCategory.FILE_SYSTEM).tags(["path", "relative", "filesystem"]).schema(z.object({
|
|
2310
|
+
});
|
|
2311
|
+
var pathRelativeSchema = z.object({
|
|
2164
2312
|
from: z.string().describe("Source path"),
|
|
2165
2313
|
to: z.string().describe("Destination path")
|
|
2166
|
-
})
|
|
2167
|
-
|
|
2168
|
-
return {
|
|
2169
|
-
relativePath: relative3,
|
|
2170
|
-
from: input.from,
|
|
2171
|
-
to: input.to
|
|
2172
|
-
};
|
|
2173
|
-
}).build();
|
|
2174
|
-
var pathNormalize = toolBuilder().name("path-normalize").description('Normalize a path by resolving ".." and "." segments and removing duplicate separators.').category(ToolCategory.FILE_SYSTEM).tags(["path", "normalize", "filesystem"]).schema(z.object({
|
|
2314
|
+
});
|
|
2315
|
+
var pathNormalizeSchema = z.object({
|
|
2175
2316
|
path: z.string().describe("Path to normalize")
|
|
2176
|
-
})
|
|
2177
|
-
|
|
2178
|
-
return {
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2317
|
+
});
|
|
2318
|
+
function createPathJoinTool() {
|
|
2319
|
+
return toolBuilder().name("path-join").description("Join multiple path segments into a single path. Handles platform-specific separators.").category(ToolCategory.FILE_SYSTEM).tags(["path", "join", "filesystem"]).schema(pathJoinSchema).implement(async (input) => {
|
|
2320
|
+
const joined = path7.join(...input.segments);
|
|
2321
|
+
return {
|
|
2322
|
+
path: joined,
|
|
2323
|
+
segments: input.segments
|
|
2324
|
+
};
|
|
2325
|
+
}).build();
|
|
2326
|
+
}
|
|
2327
|
+
function createPathResolveTool() {
|
|
2328
|
+
return toolBuilder().name("path-resolve").description("Resolve a sequence of paths into an absolute path. Resolves relative paths from the current working directory.").category(ToolCategory.FILE_SYSTEM).tags(["path", "resolve", "absolute", "filesystem"]).schema(pathResolveSchema).implement(async (input) => {
|
|
2329
|
+
const resolved = path7.resolve(...input.paths);
|
|
2330
|
+
return {
|
|
2331
|
+
path: resolved,
|
|
2332
|
+
isAbsolute: path7.isAbsolute(resolved)
|
|
2333
|
+
};
|
|
2334
|
+
}).build();
|
|
2335
|
+
}
|
|
2336
|
+
function createPathParseTool() {
|
|
2337
|
+
return toolBuilder().name("path-parse").description("Parse a file path into its components (directory, filename, extension, etc.).").category(ToolCategory.FILE_SYSTEM).tags(["path", "parse", "filesystem"]).schema(pathParseSchema).implement(async (input) => {
|
|
2338
|
+
const parsed = path7.parse(input.path);
|
|
2339
|
+
return {
|
|
2340
|
+
root: parsed.root,
|
|
2341
|
+
dir: parsed.dir,
|
|
2342
|
+
base: parsed.base,
|
|
2343
|
+
name: parsed.name,
|
|
2344
|
+
ext: parsed.ext,
|
|
2345
|
+
isAbsolute: path7.isAbsolute(input.path)
|
|
2346
|
+
};
|
|
2347
|
+
}).build();
|
|
2348
|
+
}
|
|
2349
|
+
function createPathBasenameTool() {
|
|
2350
|
+
return toolBuilder().name("path-basename").description("Get the last portion of a path (filename with extension). Optionally remove the extension.").category(ToolCategory.FILE_SYSTEM).tags(["path", "basename", "filename", "filesystem"]).schema(pathBasenameSchema).implement(async (input) => {
|
|
2351
|
+
const basename4 = input.removeExtension ? path7.basename(input.path, path7.extname(input.path)) : path7.basename(input.path);
|
|
2352
|
+
return {
|
|
2353
|
+
basename: basename4,
|
|
2354
|
+
extension: path7.extname(input.path)
|
|
2355
|
+
};
|
|
2356
|
+
}).build();
|
|
2357
|
+
}
|
|
2358
|
+
function createPathDirnameTool() {
|
|
2359
|
+
return toolBuilder().name("path-dirname").description("Get the directory name of a path (everything except the last portion).").category(ToolCategory.FILE_SYSTEM).tags(["path", "dirname", "directory", "filesystem"]).schema(pathDirnameSchema).implement(async (input) => {
|
|
2360
|
+
const dirname3 = path7.dirname(input.path);
|
|
2361
|
+
return {
|
|
2362
|
+
dirname: dirname3,
|
|
2363
|
+
basename: path7.basename(input.path)
|
|
2364
|
+
};
|
|
2365
|
+
}).build();
|
|
2366
|
+
}
|
|
2367
|
+
function createPathExtensionTool() {
|
|
2368
|
+
return toolBuilder().name("path-extension").description('Get the file extension from a path (including the dot, e.g., ".txt").').category(ToolCategory.FILE_SYSTEM).tags(["path", "extension", "ext", "filesystem"]).schema(pathExtensionSchema).implement(async (input) => {
|
|
2369
|
+
const ext = path7.extname(input.path);
|
|
2370
|
+
return {
|
|
2371
|
+
extension: ext,
|
|
2372
|
+
hasExtension: ext.length > 0,
|
|
2373
|
+
filename: path7.basename(input.path, ext)
|
|
2374
|
+
};
|
|
2375
|
+
}).build();
|
|
2376
|
+
}
|
|
2377
|
+
function createPathRelativeTool() {
|
|
2378
|
+
return toolBuilder().name("path-relative").description("Get the relative path from one path to another.").category(ToolCategory.FILE_SYSTEM).tags(["path", "relative", "filesystem"]).schema(pathRelativeSchema).implement(async (input) => {
|
|
2379
|
+
const relative3 = path7.relative(input.from, input.to);
|
|
2380
|
+
return {
|
|
2381
|
+
relativePath: relative3,
|
|
2382
|
+
from: input.from,
|
|
2383
|
+
to: input.to
|
|
2384
|
+
};
|
|
2385
|
+
}).build();
|
|
2386
|
+
}
|
|
2387
|
+
function createPathNormalizeTool() {
|
|
2388
|
+
return toolBuilder().name("path-normalize").description('Normalize a path by resolving ".." and "." segments and removing duplicate separators.').category(ToolCategory.FILE_SYSTEM).tags(["path", "normalize", "filesystem"]).schema(pathNormalizeSchema).implement(async (input) => {
|
|
2389
|
+
const normalized = path7.normalize(input.path);
|
|
2390
|
+
return {
|
|
2391
|
+
normalized,
|
|
2392
|
+
original: input.path
|
|
2393
|
+
};
|
|
2394
|
+
}).build();
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
// src/file/path/index.ts
|
|
2398
|
+
var pathJoin = createPathJoinTool();
|
|
2399
|
+
var pathResolve = createPathResolveTool();
|
|
2400
|
+
var pathParse = createPathParseTool();
|
|
2401
|
+
var pathBasename = createPathBasenameTool();
|
|
2402
|
+
var pathDirname = createPathDirnameTool();
|
|
2403
|
+
var pathExtension = createPathExtensionTool();
|
|
2404
|
+
var pathRelative = createPathRelativeTool();
|
|
2405
|
+
var pathNormalize = createPathNormalizeTool();
|
|
2406
|
+
var pathUtilityTools = [
|
|
2407
|
+
pathJoin,
|
|
2408
|
+
pathResolve,
|
|
2409
|
+
pathParse,
|
|
2410
|
+
pathBasename,
|
|
2411
|
+
pathDirname,
|
|
2412
|
+
pathExtension,
|
|
2413
|
+
pathRelative,
|
|
2414
|
+
pathNormalize
|
|
2415
|
+
];
|
|
2416
|
+
function createPathUtilityTools(config = {}) {
|
|
2417
|
+
return [
|
|
2418
|
+
createPathJoinTool(),
|
|
2419
|
+
createPathResolveTool(),
|
|
2420
|
+
createPathParseTool(),
|
|
2421
|
+
createPathBasenameTool(),
|
|
2422
|
+
createPathDirnameTool(),
|
|
2423
|
+
createPathExtensionTool(),
|
|
2424
|
+
createPathRelativeTool(),
|
|
2425
|
+
createPathNormalizeTool()
|
|
2426
|
+
];
|
|
2427
|
+
}
|
|
2428
|
+
var CurrentDateTimeSchema = z.object({
|
|
2184
2429
|
format: z.enum(["iso", "unix", "custom"]).default("iso").describe("Output format"),
|
|
2185
2430
|
customFormat: z.string().optional().describe('Custom format string (e.g., "yyyy-MM-dd HH:mm:ss") when format is "custom"'),
|
|
2186
2431
|
timezone: z.string().optional().describe('Timezone (e.g., "America/New_York")')
|
|
2187
|
-
})
|
|
2188
|
-
|
|
2189
|
-
let formatted;
|
|
2190
|
-
if (input.format === "iso") {
|
|
2191
|
-
formatted = now.toISOString();
|
|
2192
|
-
} else if (input.format === "unix") {
|
|
2193
|
-
formatted = Math.floor(now.getTime() / 1e3);
|
|
2194
|
-
} else if (input.format === "custom" && input.customFormat) {
|
|
2195
|
-
formatted = format(now, input.customFormat);
|
|
2196
|
-
} else {
|
|
2197
|
-
formatted = now.toISOString();
|
|
2198
|
-
}
|
|
2199
|
-
return {
|
|
2200
|
-
formatted,
|
|
2201
|
-
iso: now.toISOString(),
|
|
2202
|
-
unix: Math.floor(now.getTime() / 1e3),
|
|
2203
|
-
year: now.getFullYear(),
|
|
2204
|
-
month: now.getMonth() + 1,
|
|
2205
|
-
day: now.getDate(),
|
|
2206
|
-
hour: now.getHours(),
|
|
2207
|
-
minute: now.getMinutes(),
|
|
2208
|
-
second: now.getSeconds()
|
|
2209
|
-
};
|
|
2210
|
-
}).build();
|
|
2211
|
-
var dateFormatter = toolBuilder().name("date-formatter").description("Format a date string or timestamp into a different format. Supports ISO, Unix timestamps, and custom formats.").category(ToolCategory.UTILITY).tags(["date", "format", "time"]).schema(z.object({
|
|
2432
|
+
});
|
|
2433
|
+
var DateFormatterSchema = z.object({
|
|
2212
2434
|
date: z.string().describe("Date string or Unix timestamp to format"),
|
|
2213
2435
|
outputFormat: z.string().describe('Output format string (e.g., "yyyy-MM-dd", "MMM dd, yyyy")'),
|
|
2214
2436
|
inputFormat: z.string().optional().describe("Input format string (optional, auto-detected if not provided)")
|
|
2215
|
-
})
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2437
|
+
});
|
|
2438
|
+
var DateArithmeticSchema = z.object({
|
|
2439
|
+
date: z.string().describe("Starting date (ISO string or Unix timestamp)"),
|
|
2440
|
+
operation: z.enum(["add", "subtract"]).describe("Operation to perform"),
|
|
2441
|
+
amount: z.number().describe("Amount to add or subtract"),
|
|
2442
|
+
unit: z.enum(["years", "months", "weeks", "days", "hours", "minutes", "seconds"]).describe("Time unit")
|
|
2443
|
+
});
|
|
2444
|
+
var DateDifferenceSchema = z.object({
|
|
2445
|
+
startDate: z.string().describe("Start date (ISO string or Unix timestamp)"),
|
|
2446
|
+
endDate: z.string().describe("End date (ISO string or Unix timestamp)"),
|
|
2447
|
+
unit: z.enum(["days", "hours", "minutes"]).default("days").describe("Unit for the difference")
|
|
2448
|
+
});
|
|
2449
|
+
var DateComparisonSchema = z.object({
|
|
2450
|
+
date1: z.string().describe("First date to compare"),
|
|
2451
|
+
date2: z.string().describe("Second date to compare")
|
|
2452
|
+
});
|
|
2453
|
+
|
|
2454
|
+
// src/utility/date-time/tools/current-date-time.ts
|
|
2455
|
+
function createCurrentDateTimeTool() {
|
|
2456
|
+
return toolBuilder().name("current-date-time").description("Get the current date and time in various formats (ISO, Unix timestamp, formatted string).").category(ToolCategory.UTILITY).tags(["date", "time", "now", "current"]).schema(CurrentDateTimeSchema).implement(async (input) => {
|
|
2457
|
+
const now = /* @__PURE__ */ new Date();
|
|
2458
|
+
let formatted;
|
|
2459
|
+
if (input.format === "iso") {
|
|
2460
|
+
formatted = now.toISOString();
|
|
2461
|
+
} else if (input.format === "unix") {
|
|
2462
|
+
formatted = Math.floor(now.getTime() / 1e3);
|
|
2463
|
+
} else if (input.format === "custom" && input.customFormat) {
|
|
2464
|
+
formatted = format(now, input.customFormat);
|
|
2222
2465
|
} else {
|
|
2223
|
-
|
|
2466
|
+
formatted = now.toISOString();
|
|
2224
2467
|
}
|
|
2225
|
-
if (!isValid(date)) {
|
|
2226
|
-
return {
|
|
2227
|
-
success: false,
|
|
2228
|
-
error: "Invalid date"
|
|
2229
|
-
};
|
|
2230
|
-
}
|
|
2231
|
-
const formatted = format(date, input.outputFormat);
|
|
2232
2468
|
return {
|
|
2233
|
-
success: true,
|
|
2234
2469
|
formatted,
|
|
2235
|
-
iso:
|
|
2470
|
+
iso: now.toISOString(),
|
|
2471
|
+
unix: Math.floor(now.getTime() / 1e3),
|
|
2472
|
+
year: now.getFullYear(),
|
|
2473
|
+
month: now.getMonth() + 1,
|
|
2474
|
+
day: now.getDate(),
|
|
2475
|
+
hour: now.getHours(),
|
|
2476
|
+
minute: now.getMinutes(),
|
|
2477
|
+
second: now.getSeconds()
|
|
2236
2478
|
};
|
|
2237
|
-
}
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
}
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2479
|
+
}).build();
|
|
2480
|
+
}
|
|
2481
|
+
function createDateFormatterTool() {
|
|
2482
|
+
return toolBuilder().name("date-formatter").description("Format a date string or timestamp into a different format. Supports ISO, Unix timestamps, and custom formats.").category(ToolCategory.UTILITY).tags(["date", "format", "time"]).schema(DateFormatterSchema).implement(async (input) => {
|
|
2483
|
+
try {
|
|
2484
|
+
let date;
|
|
2485
|
+
if (input.inputFormat) {
|
|
2486
|
+
date = parse$1(input.date, input.inputFormat, /* @__PURE__ */ new Date());
|
|
2487
|
+
} else if (!isNaN(Number(input.date))) {
|
|
2488
|
+
date = new Date(Number(input.date) * 1e3);
|
|
2489
|
+
} else {
|
|
2490
|
+
date = new Date(input.date);
|
|
2491
|
+
}
|
|
2492
|
+
if (!isValid(date)) {
|
|
2493
|
+
return {
|
|
2494
|
+
success: false,
|
|
2495
|
+
error: "Invalid date"
|
|
2496
|
+
};
|
|
2497
|
+
}
|
|
2498
|
+
const formatted = format(date, input.outputFormat);
|
|
2499
|
+
return {
|
|
2500
|
+
success: true,
|
|
2501
|
+
formatted,
|
|
2502
|
+
iso: date.toISOString()
|
|
2503
|
+
};
|
|
2504
|
+
} catch (error) {
|
|
2253
2505
|
return {
|
|
2254
2506
|
success: false,
|
|
2255
|
-
error: "
|
|
2507
|
+
error: error instanceof Error ? error.message : "Failed to format date"
|
|
2256
2508
|
};
|
|
2257
2509
|
}
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
}
|
|
2277
|
-
|
|
2278
|
-
const start = new Date(input.startDate);
|
|
2279
|
-
const end = new Date(input.endDate);
|
|
2280
|
-
if (!isValid(start) || !isValid(end)) {
|
|
2510
|
+
}).build();
|
|
2511
|
+
}
|
|
2512
|
+
function createDateArithmeticTool() {
|
|
2513
|
+
return toolBuilder().name("date-arithmetic").description("Add or subtract time from a date. Supports years, months, weeks, days, hours, minutes, and seconds.").category(ToolCategory.UTILITY).tags(["date", "time", "add", "subtract", "arithmetic"]).schema(DateArithmeticSchema).implement(async (input) => {
|
|
2514
|
+
try {
|
|
2515
|
+
const date = new Date(input.date);
|
|
2516
|
+
if (!isValid(date)) {
|
|
2517
|
+
return {
|
|
2518
|
+
success: false,
|
|
2519
|
+
error: "Invalid date"
|
|
2520
|
+
};
|
|
2521
|
+
}
|
|
2522
|
+
const duration = { [input.unit]: input.amount };
|
|
2523
|
+
const result = input.operation === "add" ? add(date, duration) : sub(date, duration);
|
|
2524
|
+
return {
|
|
2525
|
+
success: true,
|
|
2526
|
+
result: result.toISOString(),
|
|
2527
|
+
unix: Math.floor(result.getTime() / 1e3)
|
|
2528
|
+
};
|
|
2529
|
+
} catch (error) {
|
|
2281
2530
|
return {
|
|
2282
2531
|
success: false,
|
|
2283
|
-
error: "
|
|
2532
|
+
error: error instanceof Error ? error.message : "Failed to perform date arithmetic"
|
|
2284
2533
|
};
|
|
2285
2534
|
}
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2535
|
+
}).build();
|
|
2536
|
+
}
|
|
2537
|
+
function createDateDifferenceTool() {
|
|
2538
|
+
return toolBuilder().name("date-difference").description("Calculate the difference between two dates in various units (days, hours, minutes).").category(ToolCategory.UTILITY).tags(["date", "time", "difference", "duration"]).schema(DateDifferenceSchema).implement(async (input) => {
|
|
2539
|
+
try {
|
|
2540
|
+
const start = new Date(input.startDate);
|
|
2541
|
+
const end = new Date(input.endDate);
|
|
2542
|
+
if (!isValid(start) || !isValid(end)) {
|
|
2543
|
+
return {
|
|
2544
|
+
success: false,
|
|
2545
|
+
error: "Invalid date(s)"
|
|
2546
|
+
};
|
|
2547
|
+
}
|
|
2548
|
+
let difference;
|
|
2549
|
+
if (input.unit === "days") {
|
|
2550
|
+
difference = differenceInDays(end, start);
|
|
2551
|
+
} else if (input.unit === "hours") {
|
|
2552
|
+
difference = differenceInHours(end, start);
|
|
2553
|
+
} else {
|
|
2554
|
+
difference = differenceInMinutes(end, start);
|
|
2555
|
+
}
|
|
2556
|
+
return {
|
|
2557
|
+
success: true,
|
|
2558
|
+
difference,
|
|
2559
|
+
unit: input.unit,
|
|
2560
|
+
startDate: start.toISOString(),
|
|
2561
|
+
endDate: end.toISOString()
|
|
2562
|
+
};
|
|
2563
|
+
} catch (error) {
|
|
2564
|
+
return {
|
|
2565
|
+
success: false,
|
|
2566
|
+
error: error instanceof Error ? error.message : "Failed to calculate date difference"
|
|
2567
|
+
};
|
|
2293
2568
|
}
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2569
|
+
}).build();
|
|
2570
|
+
}
|
|
2571
|
+
function createDateComparisonTool() {
|
|
2572
|
+
return toolBuilder().name("date-comparison").description("Compare two dates to determine if one is before, after, or equal to the other.").category(ToolCategory.UTILITY).tags(["date", "time", "compare", "comparison"]).schema(DateComparisonSchema).implement(async (input) => {
|
|
2573
|
+
try {
|
|
2574
|
+
const d1 = new Date(input.date1);
|
|
2575
|
+
const d2 = new Date(input.date2);
|
|
2576
|
+
if (!isValid(d1) || !isValid(d2)) {
|
|
2577
|
+
return {
|
|
2578
|
+
success: false,
|
|
2579
|
+
error: "Invalid date(s)"
|
|
2580
|
+
};
|
|
2581
|
+
}
|
|
2582
|
+
return {
|
|
2583
|
+
success: true,
|
|
2584
|
+
date1IsBefore: isBefore(d1, d2),
|
|
2585
|
+
date1IsAfter: isAfter(d1, d2),
|
|
2586
|
+
datesAreEqual: d1.getTime() === d2.getTime(),
|
|
2587
|
+
date1: d1.toISOString(),
|
|
2588
|
+
date2: d2.toISOString()
|
|
2589
|
+
};
|
|
2590
|
+
} catch (error) {
|
|
2316
2591
|
return {
|
|
2317
2592
|
success: false,
|
|
2318
|
-
error: "
|
|
2593
|
+
error: error instanceof Error ? error.message : "Failed to compare dates"
|
|
2319
2594
|
};
|
|
2320
2595
|
}
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2596
|
+
}).build();
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
// src/utility/date-time/index.ts
|
|
2600
|
+
var currentDateTime = createCurrentDateTimeTool();
|
|
2601
|
+
var dateFormatter = createDateFormatterTool();
|
|
2602
|
+
var dateArithmetic = createDateArithmeticTool();
|
|
2603
|
+
var dateDifference = createDateDifferenceTool();
|
|
2604
|
+
var dateComparison = createDateComparisonTool();
|
|
2605
|
+
var dateTimeTools = [
|
|
2606
|
+
currentDateTime,
|
|
2607
|
+
dateFormatter,
|
|
2608
|
+
dateArithmetic,
|
|
2609
|
+
dateDifference,
|
|
2610
|
+
dateComparison
|
|
2611
|
+
];
|
|
2612
|
+
function createDateTimeTools(config = {}) {
|
|
2613
|
+
return [
|
|
2614
|
+
createCurrentDateTimeTool(),
|
|
2615
|
+
createDateFormatterTool(),
|
|
2616
|
+
createDateArithmeticTool(),
|
|
2617
|
+
createDateDifferenceTool(),
|
|
2618
|
+
createDateComparisonTool()
|
|
2619
|
+
];
|
|
2620
|
+
}
|
|
2621
|
+
var StringCaseConverterSchema = z.object({
|
|
2337
2622
|
text: z.string().describe("Text to convert"),
|
|
2338
2623
|
targetCase: z.enum(["lowercase", "uppercase", "title", "camel", "snake", "kebab", "pascal"]).describe("Target case format")
|
|
2339
|
-
})
|
|
2340
|
-
|
|
2341
|
-
switch (input.targetCase) {
|
|
2342
|
-
case "lowercase":
|
|
2343
|
-
result = input.text.toLowerCase();
|
|
2344
|
-
break;
|
|
2345
|
-
case "uppercase":
|
|
2346
|
-
result = input.text.toUpperCase();
|
|
2347
|
-
break;
|
|
2348
|
-
case "title":
|
|
2349
|
-
result = input.text.toLowerCase().replace(/\b\w/g, (char) => char.toUpperCase());
|
|
2350
|
-
break;
|
|
2351
|
-
case "camel":
|
|
2352
|
-
result = input.text.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_, char) => char.toUpperCase());
|
|
2353
|
-
break;
|
|
2354
|
-
case "snake":
|
|
2355
|
-
result = input.text.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
2356
|
-
break;
|
|
2357
|
-
case "kebab":
|
|
2358
|
-
result = input.text.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
2359
|
-
break;
|
|
2360
|
-
case "pascal":
|
|
2361
|
-
result = input.text.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_, char) => char.toUpperCase()).replace(/^./, (char) => char.toUpperCase());
|
|
2362
|
-
break;
|
|
2363
|
-
default:
|
|
2364
|
-
result = input.text;
|
|
2365
|
-
}
|
|
2366
|
-
return {
|
|
2367
|
-
original: input.text,
|
|
2368
|
-
converted: result,
|
|
2369
|
-
targetCase: input.targetCase
|
|
2370
|
-
};
|
|
2371
|
-
}).build();
|
|
2372
|
-
var stringTrim = toolBuilder().name("string-trim").description("Remove whitespace from the beginning and/or end of a string. Supports trim, trim start, and trim end.").category(ToolCategory.UTILITY).tags(["string", "trim", "whitespace"]).schema(z.object({
|
|
2624
|
+
});
|
|
2625
|
+
var StringTrimSchema = z.object({
|
|
2373
2626
|
text: z.string().describe("Text to trim"),
|
|
2374
2627
|
mode: z.enum(["both", "start", "end"]).default("both").describe("Which side to trim"),
|
|
2375
2628
|
characters: z.string().optional().describe("Optional custom characters to trim (default: whitespace)")
|
|
2376
|
-
})
|
|
2377
|
-
|
|
2378
|
-
if (input.characters) {
|
|
2379
|
-
const chars = input.characters.split("").map((c) => c.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
|
|
2380
|
-
const regex = input.mode === "both" ? new RegExp(`^[${chars}]+|[${chars}]+$`, "g") : input.mode === "start" ? new RegExp(`^[${chars}]+`, "g") : new RegExp(`[${chars}]+$`, "g");
|
|
2381
|
-
result = input.text.replace(regex, "");
|
|
2382
|
-
} else {
|
|
2383
|
-
result = input.mode === "both" ? input.text.trim() : input.mode === "start" ? input.text.trimStart() : input.text.trimEnd();
|
|
2384
|
-
}
|
|
2385
|
-
return {
|
|
2386
|
-
original: input.text,
|
|
2387
|
-
trimmed: result,
|
|
2388
|
-
removed: input.text.length - result.length
|
|
2389
|
-
};
|
|
2390
|
-
}).build();
|
|
2391
|
-
var stringReplace = toolBuilder().name("string-replace").description("Replace occurrences of a substring or pattern in a string. Supports regex patterns and global replacement.").category(ToolCategory.UTILITY).tags(["string", "replace", "substitute"]).schema(z.object({
|
|
2629
|
+
});
|
|
2630
|
+
var StringReplaceSchema = z.object({
|
|
2392
2631
|
text: z.string().describe("Text to search in"),
|
|
2393
2632
|
search: z.string().describe("String or regex pattern to search for"),
|
|
2394
2633
|
replace: z.string().describe("Replacement string"),
|
|
2395
2634
|
global: z.boolean().default(true).describe("Replace all occurrences (true) or just the first (false)"),
|
|
2396
2635
|
caseInsensitive: z.boolean().default(false).describe("Case-insensitive search")
|
|
2397
|
-
})
|
|
2398
|
-
|
|
2399
|
-
const regex = new RegExp(input.search, flags);
|
|
2400
|
-
const result = input.text.replace(regex, input.replace);
|
|
2401
|
-
const matches = input.text.match(regex);
|
|
2402
|
-
const count = matches ? matches.length : 0;
|
|
2403
|
-
return {
|
|
2404
|
-
original: input.text,
|
|
2405
|
-
result,
|
|
2406
|
-
replacements: count
|
|
2407
|
-
};
|
|
2408
|
-
}).build();
|
|
2409
|
-
var stringSplit = toolBuilder().name("string-split").description("Split a string into an array of substrings using a delimiter. Supports regex delimiters and limit.").category(ToolCategory.UTILITY).tags(["string", "split", "array"]).schema(z.object({
|
|
2636
|
+
});
|
|
2637
|
+
var StringSplitSchema = z.object({
|
|
2410
2638
|
text: z.string().describe("Text to split"),
|
|
2411
2639
|
delimiter: z.string().describe("Delimiter to split on (can be a regex pattern)"),
|
|
2412
2640
|
limit: z.number().optional().describe("Maximum number of splits")
|
|
2413
|
-
})
|
|
2414
|
-
|
|
2415
|
-
return {
|
|
2416
|
-
parts,
|
|
2417
|
-
count: parts.length
|
|
2418
|
-
};
|
|
2419
|
-
}).build();
|
|
2420
|
-
var stringJoin = toolBuilder().name("string-join").description("Join an array of strings into a single string with a separator.").category(ToolCategory.UTILITY).tags(["string", "join", "array"]).schema(z.object({
|
|
2641
|
+
});
|
|
2642
|
+
var StringJoinSchema = z.object({
|
|
2421
2643
|
parts: z.array(z.string().describe("String value")).describe("Array of strings to join"),
|
|
2422
2644
|
separator: z.string().default("").describe("Separator to use between parts")
|
|
2423
|
-
})
|
|
2424
|
-
|
|
2425
|
-
return {
|
|
2426
|
-
result,
|
|
2427
|
-
partCount: input.parts.length,
|
|
2428
|
-
length: result.length
|
|
2429
|
-
};
|
|
2430
|
-
}).build();
|
|
2431
|
-
var stringSubstring = toolBuilder().name("string-substring").description("Extract a substring from a string using start and end positions.").category(ToolCategory.UTILITY).tags(["string", "substring", "slice"]).schema(z.object({
|
|
2645
|
+
});
|
|
2646
|
+
var StringSubstringSchema = z.object({
|
|
2432
2647
|
text: z.string().describe("Source text"),
|
|
2433
2648
|
start: z.number().describe("Start position (0-based)"),
|
|
2434
2649
|
end: z.number().optional().describe("End position (optional, defaults to end of string)")
|
|
2435
|
-
})
|
|
2436
|
-
|
|
2437
|
-
return {
|
|
2438
|
-
result,
|
|
2439
|
-
length: result.length,
|
|
2440
|
-
start: input.start,
|
|
2441
|
-
end: input.end ?? input.text.length
|
|
2442
|
-
};
|
|
2443
|
-
}).build();
|
|
2444
|
-
var stringLength = toolBuilder().name("string-length").description("Get the length of a string in characters, words, or lines.").category(ToolCategory.UTILITY).tags(["string", "length", "count"]).schema(z.object({
|
|
2650
|
+
});
|
|
2651
|
+
var StringLengthSchema = z.object({
|
|
2445
2652
|
text: z.string().describe("Text to measure")
|
|
2446
|
-
})
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2653
|
+
});
|
|
2654
|
+
|
|
2655
|
+
// src/utility/string/tools/string-case-converter.ts
|
|
2656
|
+
function createStringCaseConverterTool() {
|
|
2657
|
+
return toolBuilder().name("string-case-converter").description("Convert string to different cases: lowercase, uppercase, title case, camel case, snake case, kebab case.").category(ToolCategory.UTILITY).tags(["string", "case", "convert", "transform"]).schema(StringCaseConverterSchema).implement(async (input) => {
|
|
2658
|
+
let result;
|
|
2659
|
+
switch (input.targetCase) {
|
|
2660
|
+
case "lowercase":
|
|
2661
|
+
result = input.text.toLowerCase();
|
|
2662
|
+
break;
|
|
2663
|
+
case "uppercase":
|
|
2664
|
+
result = input.text.toUpperCase();
|
|
2665
|
+
break;
|
|
2666
|
+
case "title":
|
|
2667
|
+
result = input.text.toLowerCase().replace(/\b\w/g, (char) => char.toUpperCase());
|
|
2668
|
+
break;
|
|
2669
|
+
case "camel":
|
|
2670
|
+
result = input.text.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_, char) => char.toUpperCase());
|
|
2671
|
+
break;
|
|
2672
|
+
case "snake":
|
|
2673
|
+
result = input.text.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
2674
|
+
break;
|
|
2675
|
+
case "kebab":
|
|
2676
|
+
result = input.text.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
2677
|
+
break;
|
|
2678
|
+
case "pascal":
|
|
2679
|
+
result = input.text.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_, char) => char.toUpperCase()).replace(/^./, (char) => char.toUpperCase());
|
|
2680
|
+
break;
|
|
2681
|
+
default:
|
|
2682
|
+
result = input.text;
|
|
2683
|
+
}
|
|
2684
|
+
return {
|
|
2685
|
+
original: input.text,
|
|
2686
|
+
converted: result,
|
|
2687
|
+
targetCase: input.targetCase
|
|
2688
|
+
};
|
|
2689
|
+
}).build();
|
|
2690
|
+
}
|
|
2691
|
+
function createStringTrimTool() {
|
|
2692
|
+
return toolBuilder().name("string-trim").description("Remove whitespace from the beginning and/or end of a string. Supports trim, trim start, and trim end.").category(ToolCategory.UTILITY).tags(["string", "trim", "whitespace"]).schema(StringTrimSchema).implement(async (input) => {
|
|
2693
|
+
let result;
|
|
2694
|
+
if (input.characters) {
|
|
2695
|
+
const chars = input.characters.split("").map((c) => c.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
|
|
2696
|
+
const regex = input.mode === "both" ? new RegExp(`^[${chars}]+|[${chars}]+$`, "g") : input.mode === "start" ? new RegExp(`^[${chars}]+`, "g") : new RegExp(`[${chars}]+$`, "g");
|
|
2697
|
+
result = input.text.replace(regex, "");
|
|
2698
|
+
} else {
|
|
2699
|
+
result = input.mode === "both" ? input.text.trim() : input.mode === "start" ? input.text.trimStart() : input.text.trimEnd();
|
|
2700
|
+
}
|
|
2701
|
+
return {
|
|
2702
|
+
original: input.text,
|
|
2703
|
+
trimmed: result,
|
|
2704
|
+
removed: input.text.length - result.length
|
|
2705
|
+
};
|
|
2706
|
+
}).build();
|
|
2707
|
+
}
|
|
2708
|
+
function createStringReplaceTool() {
|
|
2709
|
+
return toolBuilder().name("string-replace").description("Replace occurrences of a substring or pattern in a string. Supports regex patterns and global replacement.").category(ToolCategory.UTILITY).tags(["string", "replace", "substitute"]).schema(StringReplaceSchema).implement(async (input) => {
|
|
2710
|
+
const flags = (input.global ? "g" : "") + (input.caseInsensitive ? "i" : "");
|
|
2711
|
+
const regex = new RegExp(input.search, flags);
|
|
2712
|
+
const result = input.text.replace(regex, input.replace);
|
|
2713
|
+
const matches = input.text.match(regex);
|
|
2714
|
+
const count = matches ? matches.length : 0;
|
|
2715
|
+
return {
|
|
2716
|
+
original: input.text,
|
|
2717
|
+
result,
|
|
2718
|
+
replacements: count
|
|
2719
|
+
};
|
|
2720
|
+
}).build();
|
|
2721
|
+
}
|
|
2722
|
+
function createStringSplitTool() {
|
|
2723
|
+
return toolBuilder().name("string-split").description("Split a string into an array of substrings using a delimiter. Supports regex delimiters and limit.").category(ToolCategory.UTILITY).tags(["string", "split", "array"]).schema(StringSplitSchema).implement(async (input) => {
|
|
2724
|
+
const parts = input.text.split(input.delimiter, input.limit);
|
|
2725
|
+
return {
|
|
2726
|
+
parts,
|
|
2727
|
+
count: parts.length
|
|
2728
|
+
};
|
|
2729
|
+
}).build();
|
|
2730
|
+
}
|
|
2731
|
+
function createStringJoinTool() {
|
|
2732
|
+
return toolBuilder().name("string-join").description("Join an array of strings into a single string with a separator.").category(ToolCategory.UTILITY).tags(["string", "join", "array"]).schema(StringJoinSchema).implement(async (input) => {
|
|
2733
|
+
const result = input.parts.join(input.separator);
|
|
2734
|
+
return {
|
|
2735
|
+
result,
|
|
2736
|
+
partCount: input.parts.length,
|
|
2737
|
+
length: result.length
|
|
2738
|
+
};
|
|
2739
|
+
}).build();
|
|
2740
|
+
}
|
|
2741
|
+
function createStringSubstringTool() {
|
|
2742
|
+
return toolBuilder().name("string-substring").description("Extract a substring from a string using start and end positions.").category(ToolCategory.UTILITY).tags(["string", "substring", "slice"]).schema(StringSubstringSchema).implement(async (input) => {
|
|
2743
|
+
const result = input.text.substring(input.start, input.end);
|
|
2744
|
+
return {
|
|
2745
|
+
result,
|
|
2746
|
+
length: result.length,
|
|
2747
|
+
start: input.start,
|
|
2748
|
+
end: input.end ?? input.text.length
|
|
2749
|
+
};
|
|
2750
|
+
}).build();
|
|
2751
|
+
}
|
|
2752
|
+
function createStringLengthTool() {
|
|
2753
|
+
return toolBuilder().name("string-length").description("Get the length of a string in characters, words, or lines.").category(ToolCategory.UTILITY).tags(["string", "length", "count"]).schema(StringLengthSchema).implement(async (input) => {
|
|
2754
|
+
const words = input.text.trim().split(/\s+/).filter((w) => w.length > 0);
|
|
2755
|
+
const lines = input.text.split("\n");
|
|
2756
|
+
return {
|
|
2757
|
+
characters: input.text.length,
|
|
2758
|
+
words: words.length,
|
|
2759
|
+
lines: lines.length
|
|
2760
|
+
};
|
|
2761
|
+
}).build();
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
// src/utility/string/index.ts
|
|
2765
|
+
var stringCaseConverter = createStringCaseConverterTool();
|
|
2766
|
+
var stringTrim = createStringTrimTool();
|
|
2767
|
+
var stringReplace = createStringReplaceTool();
|
|
2768
|
+
var stringSplit = createStringSplitTool();
|
|
2769
|
+
var stringJoin = createStringJoinTool();
|
|
2770
|
+
var stringSubstring = createStringSubstringTool();
|
|
2771
|
+
var stringLength = createStringLengthTool();
|
|
2772
|
+
var stringUtilityTools = [
|
|
2773
|
+
stringCaseConverter,
|
|
2774
|
+
stringTrim,
|
|
2775
|
+
stringReplace,
|
|
2776
|
+
stringSplit,
|
|
2777
|
+
stringJoin,
|
|
2778
|
+
stringSubstring,
|
|
2779
|
+
stringLength
|
|
2780
|
+
];
|
|
2781
|
+
function createStringUtilityTools(config = {}) {
|
|
2782
|
+
return [
|
|
2783
|
+
createStringCaseConverterTool(),
|
|
2784
|
+
createStringTrimTool(),
|
|
2785
|
+
createStringReplaceTool(),
|
|
2786
|
+
createStringSplitTool(),
|
|
2787
|
+
createStringJoinTool(),
|
|
2788
|
+
createStringSubstringTool(),
|
|
2789
|
+
createStringLengthTool()
|
|
2790
|
+
];
|
|
2791
|
+
}
|
|
2792
|
+
var CalculatorSchema = z.object({
|
|
2456
2793
|
operation: z.enum(["add", "subtract", "multiply", "divide", "power", "modulo"]).describe("Mathematical operation to perform"),
|
|
2457
2794
|
a: z.number().describe("First number"),
|
|
2458
2795
|
b: z.number().describe("Second number")
|
|
2459
|
-
})
|
|
2460
|
-
|
|
2461
|
-
switch (input.operation) {
|
|
2462
|
-
case "add":
|
|
2463
|
-
result = input.a + input.b;
|
|
2464
|
-
break;
|
|
2465
|
-
case "subtract":
|
|
2466
|
-
result = input.a - input.b;
|
|
2467
|
-
break;
|
|
2468
|
-
case "multiply":
|
|
2469
|
-
result = input.a * input.b;
|
|
2470
|
-
break;
|
|
2471
|
-
case "divide":
|
|
2472
|
-
if (input.b === 0) {
|
|
2473
|
-
return {
|
|
2474
|
-
success: false,
|
|
2475
|
-
error: "Division by zero"
|
|
2476
|
-
};
|
|
2477
|
-
}
|
|
2478
|
-
result = input.a / input.b;
|
|
2479
|
-
break;
|
|
2480
|
-
case "power":
|
|
2481
|
-
result = Math.pow(input.a, input.b);
|
|
2482
|
-
break;
|
|
2483
|
-
case "modulo":
|
|
2484
|
-
result = input.a % input.b;
|
|
2485
|
-
break;
|
|
2486
|
-
default:
|
|
2487
|
-
return {
|
|
2488
|
-
success: false,
|
|
2489
|
-
error: "Unknown operation"
|
|
2490
|
-
};
|
|
2491
|
-
}
|
|
2492
|
-
return {
|
|
2493
|
-
success: true,
|
|
2494
|
-
result,
|
|
2495
|
-
operation: input.operation,
|
|
2496
|
-
a: input.a,
|
|
2497
|
-
b: input.b
|
|
2498
|
-
};
|
|
2499
|
-
}).build();
|
|
2500
|
-
var mathFunctions = toolBuilder().name("math-functions").description("Apply mathematical functions: sqrt, abs, round, floor, ceil, sin, cos, tan, log, exp.").category(ToolCategory.UTILITY).tags(["math", "functions", "trigonometry"]).schema(z.object({
|
|
2796
|
+
});
|
|
2797
|
+
var MathFunctionsSchema = z.object({
|
|
2501
2798
|
function: z.enum(["sqrt", "abs", "round", "floor", "ceil", "sin", "cos", "tan", "log", "exp"]).describe("Mathematical function to apply"),
|
|
2502
2799
|
value: z.number().describe("Input value")
|
|
2503
|
-
})
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
result = Math.ceil(input.value);
|
|
2800
|
+
});
|
|
2801
|
+
var RandomNumberSchema = z.object({
|
|
2802
|
+
min: z.number().default(0).describe("Minimum value (inclusive)"),
|
|
2803
|
+
max: z.number().default(1).describe("Maximum value (exclusive for decimals, inclusive for integers)"),
|
|
2804
|
+
integer: z.boolean().default(false).describe("Generate an integer (true) or decimal (false)")
|
|
2805
|
+
});
|
|
2806
|
+
var StatisticsSchema = z.object({
|
|
2807
|
+
numbers: z.array(z.number().describe("Number value")).describe("Array of numbers to analyze")
|
|
2808
|
+
});
|
|
2809
|
+
|
|
2810
|
+
// src/utility/math/tools/calculator.ts
|
|
2811
|
+
function createCalculatorTool() {
|
|
2812
|
+
return toolBuilder().name("calculator").description("Perform basic arithmetic operations: add, subtract, multiply, divide, power, modulo.").category(ToolCategory.UTILITY).tags(["math", "calculator", "arithmetic"]).schema(CalculatorSchema).implement(async (input) => {
|
|
2813
|
+
let result;
|
|
2814
|
+
switch (input.operation) {
|
|
2815
|
+
case "add":
|
|
2816
|
+
result = input.a + input.b;
|
|
2521
2817
|
break;
|
|
2522
|
-
case "
|
|
2523
|
-
result =
|
|
2818
|
+
case "subtract":
|
|
2819
|
+
result = input.a - input.b;
|
|
2524
2820
|
break;
|
|
2525
|
-
case "
|
|
2526
|
-
result =
|
|
2821
|
+
case "multiply":
|
|
2822
|
+
result = input.a * input.b;
|
|
2527
2823
|
break;
|
|
2528
|
-
case "
|
|
2529
|
-
|
|
2824
|
+
case "divide":
|
|
2825
|
+
if (input.b === 0) {
|
|
2826
|
+
return {
|
|
2827
|
+
success: false,
|
|
2828
|
+
error: "Division by zero"
|
|
2829
|
+
};
|
|
2830
|
+
}
|
|
2831
|
+
result = input.a / input.b;
|
|
2530
2832
|
break;
|
|
2531
|
-
case "
|
|
2532
|
-
result = Math.
|
|
2833
|
+
case "power":
|
|
2834
|
+
result = Math.pow(input.a, input.b);
|
|
2533
2835
|
break;
|
|
2534
|
-
case "
|
|
2535
|
-
result =
|
|
2836
|
+
case "modulo":
|
|
2837
|
+
result = input.a % input.b;
|
|
2536
2838
|
break;
|
|
2537
2839
|
default:
|
|
2538
2840
|
return {
|
|
2539
2841
|
success: false,
|
|
2540
|
-
error: "Unknown
|
|
2842
|
+
error: "Unknown operation"
|
|
2541
2843
|
};
|
|
2542
2844
|
}
|
|
2543
|
-
|
|
2845
|
+
return {
|
|
2846
|
+
success: true,
|
|
2847
|
+
result,
|
|
2848
|
+
operation: input.operation,
|
|
2849
|
+
a: input.a,
|
|
2850
|
+
b: input.b
|
|
2851
|
+
};
|
|
2852
|
+
}).build();
|
|
2853
|
+
}
|
|
2854
|
+
function createMathFunctionsTool() {
|
|
2855
|
+
return toolBuilder().name("math-functions").description("Apply mathematical functions: sqrt, abs, round, floor, ceil, sin, cos, tan, log, exp.").category(ToolCategory.UTILITY).tags(["math", "functions", "trigonometry"]).schema(MathFunctionsSchema).implement(async (input) => {
|
|
2856
|
+
let result;
|
|
2857
|
+
try {
|
|
2858
|
+
switch (input.function) {
|
|
2859
|
+
case "sqrt":
|
|
2860
|
+
result = Math.sqrt(input.value);
|
|
2861
|
+
break;
|
|
2862
|
+
case "abs":
|
|
2863
|
+
result = Math.abs(input.value);
|
|
2864
|
+
break;
|
|
2865
|
+
case "round":
|
|
2866
|
+
result = Math.round(input.value);
|
|
2867
|
+
break;
|
|
2868
|
+
case "floor":
|
|
2869
|
+
result = Math.floor(input.value);
|
|
2870
|
+
break;
|
|
2871
|
+
case "ceil":
|
|
2872
|
+
result = Math.ceil(input.value);
|
|
2873
|
+
break;
|
|
2874
|
+
case "sin":
|
|
2875
|
+
result = Math.sin(input.value);
|
|
2876
|
+
break;
|
|
2877
|
+
case "cos":
|
|
2878
|
+
result = Math.cos(input.value);
|
|
2879
|
+
break;
|
|
2880
|
+
case "tan":
|
|
2881
|
+
result = Math.tan(input.value);
|
|
2882
|
+
break;
|
|
2883
|
+
case "log":
|
|
2884
|
+
result = Math.log(input.value);
|
|
2885
|
+
break;
|
|
2886
|
+
case "exp":
|
|
2887
|
+
result = Math.exp(input.value);
|
|
2888
|
+
break;
|
|
2889
|
+
default:
|
|
2890
|
+
return {
|
|
2891
|
+
success: false,
|
|
2892
|
+
error: "Unknown function"
|
|
2893
|
+
};
|
|
2894
|
+
}
|
|
2895
|
+
if (isNaN(result) || !isFinite(result)) {
|
|
2896
|
+
return {
|
|
2897
|
+
success: false,
|
|
2898
|
+
error: "Invalid result (NaN or Infinity)"
|
|
2899
|
+
};
|
|
2900
|
+
}
|
|
2901
|
+
return {
|
|
2902
|
+
success: true,
|
|
2903
|
+
result,
|
|
2904
|
+
function: input.function,
|
|
2905
|
+
input: input.value
|
|
2906
|
+
};
|
|
2907
|
+
} catch (error) {
|
|
2544
2908
|
return {
|
|
2545
2909
|
success: false,
|
|
2546
|
-
error:
|
|
2910
|
+
error: error instanceof Error ? error.message : "Math operation failed"
|
|
2547
2911
|
};
|
|
2548
2912
|
}
|
|
2913
|
+
}).build();
|
|
2914
|
+
}
|
|
2915
|
+
function createRandomNumberTool() {
|
|
2916
|
+
return toolBuilder().name("random-number").description("Generate a random number within a specified range. Supports integers and decimals.").category(ToolCategory.UTILITY).tags(["random", "number", "generator"]).schema(RandomNumberSchema).implement(async (input) => {
|
|
2917
|
+
const min = input.min ?? 0;
|
|
2918
|
+
const max = input.max ?? 1;
|
|
2919
|
+
const integer = input.integer ?? false;
|
|
2920
|
+
let result;
|
|
2921
|
+
if (integer) {
|
|
2922
|
+
result = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
2923
|
+
} else {
|
|
2924
|
+
result = Math.random() * (max - min) + min;
|
|
2925
|
+
}
|
|
2549
2926
|
return {
|
|
2550
|
-
success: true,
|
|
2551
2927
|
result,
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
} catch (error) {
|
|
2556
|
-
return {
|
|
2557
|
-
success: false,
|
|
2558
|
-
error: error instanceof Error ? error.message : "Math operation failed"
|
|
2928
|
+
min,
|
|
2929
|
+
max,
|
|
2930
|
+
integer
|
|
2559
2931
|
};
|
|
2560
|
-
}
|
|
2561
|
-
}
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
max,
|
|
2580
|
-
integer
|
|
2581
|
-
};
|
|
2582
|
-
}).build();
|
|
2583
|
-
var statistics = toolBuilder().name("statistics").description("Calculate statistics for an array of numbers: sum, average, min, max, median, standard deviation.").category(ToolCategory.UTILITY).tags(["math", "statistics", "average", "sum"]).schema(z.object({
|
|
2584
|
-
numbers: z.array(z.number().describe("Number value")).describe("Array of numbers to analyze")
|
|
2585
|
-
})).implement(async (input) => {
|
|
2586
|
-
if (input.numbers.length === 0) {
|
|
2932
|
+
}).build();
|
|
2933
|
+
}
|
|
2934
|
+
function createStatisticsTool() {
|
|
2935
|
+
return toolBuilder().name("statistics").description("Calculate statistics for an array of numbers: sum, average, min, max, median, standard deviation.").category(ToolCategory.UTILITY).tags(["math", "statistics", "average", "sum"]).schema(StatisticsSchema).implement(async (input) => {
|
|
2936
|
+
if (input.numbers.length === 0) {
|
|
2937
|
+
return {
|
|
2938
|
+
success: false,
|
|
2939
|
+
error: "Empty array"
|
|
2940
|
+
};
|
|
2941
|
+
}
|
|
2942
|
+
const sorted = [...input.numbers].sort((a, b) => a - b);
|
|
2943
|
+
const sum = input.numbers.reduce((acc, n) => acc + n, 0);
|
|
2944
|
+
const average = sum / input.numbers.length;
|
|
2945
|
+
const min = sorted[0];
|
|
2946
|
+
const max = sorted[sorted.length - 1];
|
|
2947
|
+
const mid = Math.floor(sorted.length / 2);
|
|
2948
|
+
const median = sorted.length % 2 === 0 ? (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
2949
|
+
const variance = input.numbers.reduce((acc, n) => acc + Math.pow(n - average, 2), 0) / input.numbers.length;
|
|
2950
|
+
const stdDev = Math.sqrt(variance);
|
|
2587
2951
|
return {
|
|
2588
|
-
success:
|
|
2589
|
-
|
|
2952
|
+
success: true,
|
|
2953
|
+
count: input.numbers.length,
|
|
2954
|
+
sum,
|
|
2955
|
+
average,
|
|
2956
|
+
min,
|
|
2957
|
+
max,
|
|
2958
|
+
median,
|
|
2959
|
+
standardDeviation: stdDev,
|
|
2960
|
+
variance
|
|
2590
2961
|
};
|
|
2591
|
-
}
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
}
|
|
2613
|
-
var
|
|
2962
|
+
}).build();
|
|
2963
|
+
}
|
|
2964
|
+
|
|
2965
|
+
// src/utility/math/index.ts
|
|
2966
|
+
var calculator = createCalculatorTool();
|
|
2967
|
+
var mathFunctions = createMathFunctionsTool();
|
|
2968
|
+
var randomNumber = createRandomNumberTool();
|
|
2969
|
+
var statistics = createStatisticsTool();
|
|
2970
|
+
var mathOperationTools = [
|
|
2971
|
+
calculator,
|
|
2972
|
+
mathFunctions,
|
|
2973
|
+
randomNumber,
|
|
2974
|
+
statistics
|
|
2975
|
+
];
|
|
2976
|
+
function createMathOperationTools(config = {}) {
|
|
2977
|
+
return [
|
|
2978
|
+
createCalculatorTool(),
|
|
2979
|
+
createMathFunctionsTool(),
|
|
2980
|
+
createRandomNumberTool(),
|
|
2981
|
+
createStatisticsTool()
|
|
2982
|
+
];
|
|
2983
|
+
}
|
|
2984
|
+
var EmailValidatorSchema = z.object({
|
|
2614
2985
|
email: z.string().describe("Email address to validate")
|
|
2615
|
-
})
|
|
2616
|
-
|
|
2617
|
-
const valid = emailRegex.test(input.email);
|
|
2618
|
-
return {
|
|
2619
|
-
valid,
|
|
2620
|
-
email: input.email,
|
|
2621
|
-
message: valid ? "Valid email address" : "Invalid email address format"
|
|
2622
|
-
};
|
|
2623
|
-
}).build();
|
|
2624
|
-
var urlValidatorSimple = toolBuilder().name("url-validator-simple").description("Validate if a string is a valid URL format.").category(ToolCategory.UTILITY).tags(["validation", "url", "validate"]).schema(z.object({
|
|
2986
|
+
});
|
|
2987
|
+
var UrlValidatorSimpleSchema = z.object({
|
|
2625
2988
|
url: z.string().describe("URL to validate")
|
|
2626
|
-
})
|
|
2627
|
-
|
|
2628
|
-
|
|
2989
|
+
});
|
|
2990
|
+
var PhoneValidatorSchema = z.object({
|
|
2991
|
+
phone: z.string().describe("Phone number to validate"),
|
|
2992
|
+
strict: z.boolean().default(false).describe("Use strict validation (requires country code)")
|
|
2993
|
+
});
|
|
2994
|
+
var CreditCardValidatorSchema = z.object({
|
|
2995
|
+
cardNumber: z.string().describe("Credit card number to validate")
|
|
2996
|
+
});
|
|
2997
|
+
var IpValidatorSchema = z.object({
|
|
2998
|
+
ip: z.string().describe("IP address to validate"),
|
|
2999
|
+
version: z.enum(["v4", "v6", "any"]).default("any").describe("IP version to validate against")
|
|
3000
|
+
});
|
|
3001
|
+
var UuidValidatorSchema = z.object({
|
|
3002
|
+
uuid: z.string().describe("UUID to validate")
|
|
3003
|
+
});
|
|
3004
|
+
|
|
3005
|
+
// src/utility/validation/tools/email-validator.ts
|
|
3006
|
+
function createEmailValidatorTool() {
|
|
3007
|
+
return toolBuilder().name("email-validator").description("Validate if a string is a valid email address format.").category(ToolCategory.UTILITY).tags(["validation", "email", "validate"]).schema(EmailValidatorSchema).implement(async (input) => {
|
|
3008
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
3009
|
+
const valid = emailRegex.test(input.email);
|
|
2629
3010
|
return {
|
|
2630
|
-
valid
|
|
2631
|
-
|
|
2632
|
-
message: "Valid
|
|
3011
|
+
valid,
|
|
3012
|
+
email: input.email,
|
|
3013
|
+
message: valid ? "Valid email address" : "Invalid email address format"
|
|
2633
3014
|
};
|
|
2634
|
-
}
|
|
3015
|
+
}).build();
|
|
3016
|
+
}
|
|
3017
|
+
function createUrlValidatorSimpleTool() {
|
|
3018
|
+
return toolBuilder().name("url-validator-simple").description("Validate if a string is a valid URL format.").category(ToolCategory.UTILITY).tags(["validation", "url", "validate"]).schema(UrlValidatorSimpleSchema).implement(async (input) => {
|
|
3019
|
+
try {
|
|
3020
|
+
new URL(input.url);
|
|
3021
|
+
return {
|
|
3022
|
+
valid: true,
|
|
3023
|
+
url: input.url,
|
|
3024
|
+
message: "Valid URL"
|
|
3025
|
+
};
|
|
3026
|
+
} catch {
|
|
3027
|
+
return {
|
|
3028
|
+
valid: false,
|
|
3029
|
+
url: input.url,
|
|
3030
|
+
message: "Invalid URL format"
|
|
3031
|
+
};
|
|
3032
|
+
}
|
|
3033
|
+
}).build();
|
|
3034
|
+
}
|
|
3035
|
+
function createPhoneValidatorTool() {
|
|
3036
|
+
return toolBuilder().name("phone-validator").description("Validate if a string is a valid phone number format. Supports various international formats.").category(ToolCategory.UTILITY).tags(["validation", "phone", "validate"]).schema(PhoneValidatorSchema).implement(async (input) => {
|
|
3037
|
+
const basicRegex = /^[\d\s\-\+\(\)]+$/;
|
|
3038
|
+
const strictRegex = /^\+?[1-9]\d{1,14}$/;
|
|
3039
|
+
const regex = input.strict ? strictRegex : basicRegex;
|
|
3040
|
+
const valid = regex.test(input.phone.replace(/\s/g, ""));
|
|
2635
3041
|
return {
|
|
2636
|
-
valid
|
|
2637
|
-
|
|
2638
|
-
message: "Invalid
|
|
3042
|
+
valid,
|
|
3043
|
+
phone: input.phone,
|
|
3044
|
+
message: valid ? "Valid phone number format" : "Invalid phone number format"
|
|
2639
3045
|
};
|
|
2640
|
-
}
|
|
2641
|
-
}
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
3046
|
+
}).build();
|
|
3047
|
+
}
|
|
3048
|
+
function createCreditCardValidatorTool() {
|
|
3049
|
+
return toolBuilder().name("credit-card-validator").description("Validate if a string is a valid credit card number using the Luhn algorithm.").category(ToolCategory.UTILITY).tags(["validation", "credit-card", "validate", "luhn"]).schema(CreditCardValidatorSchema).implement(async (input) => {
|
|
3050
|
+
const cleaned = input.cardNumber.replace(/[\s\-]/g, "");
|
|
3051
|
+
if (!/^\d+$/.test(cleaned)) {
|
|
3052
|
+
return {
|
|
3053
|
+
valid: false,
|
|
3054
|
+
message: "Card number must contain only digits"
|
|
3055
|
+
};
|
|
3056
|
+
}
|
|
3057
|
+
let sum = 0;
|
|
3058
|
+
let isEven = false;
|
|
3059
|
+
for (let i = cleaned.length - 1; i >= 0; i--) {
|
|
3060
|
+
let digit = parseInt(cleaned[i], 10);
|
|
3061
|
+
if (isEven) {
|
|
3062
|
+
digit *= 2;
|
|
3063
|
+
if (digit > 9) {
|
|
3064
|
+
digit -= 9;
|
|
3065
|
+
}
|
|
3066
|
+
}
|
|
3067
|
+
sum += digit;
|
|
3068
|
+
isEven = !isEven;
|
|
3069
|
+
}
|
|
3070
|
+
const valid = sum % 10 === 0;
|
|
2661
3071
|
return {
|
|
2662
|
-
valid
|
|
2663
|
-
|
|
3072
|
+
valid,
|
|
3073
|
+
cardNumber: input.cardNumber,
|
|
3074
|
+
message: valid ? "Valid credit card number" : "Invalid credit card number (failed Luhn check)"
|
|
2664
3075
|
};
|
|
2665
|
-
}
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
3076
|
+
}).build();
|
|
3077
|
+
}
|
|
3078
|
+
function createIpValidatorTool() {
|
|
3079
|
+
return toolBuilder().name("ip-validator").description("Validate if a string is a valid IPv4 or IPv6 address.").category(ToolCategory.UTILITY).tags(["validation", "ip", "validate", "network"]).schema(IpValidatorSchema).implement(async (input) => {
|
|
3080
|
+
const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
|
|
3081
|
+
const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;
|
|
3082
|
+
let valid = false;
|
|
3083
|
+
let detectedVersion;
|
|
3084
|
+
if (input.version === "v4" || input.version === "any") {
|
|
3085
|
+
if (ipv4Regex.test(input.ip)) {
|
|
3086
|
+
const parts = input.ip.split(".");
|
|
3087
|
+
valid = parts.every((part) => {
|
|
3088
|
+
const num = parseInt(part, 10);
|
|
3089
|
+
return num >= 0 && num <= 255;
|
|
3090
|
+
});
|
|
3091
|
+
if (valid) detectedVersion = "IPv4";
|
|
2674
3092
|
}
|
|
2675
3093
|
}
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
valid,
|
|
2682
|
-
cardNumber: input.cardNumber,
|
|
2683
|
-
message: valid ? "Valid credit card number" : "Invalid credit card number (failed Luhn check)"
|
|
2684
|
-
};
|
|
2685
|
-
}).build();
|
|
2686
|
-
var ipValidator = toolBuilder().name("ip-validator").description("Validate if a string is a valid IPv4 or IPv6 address.").category(ToolCategory.UTILITY).tags(["validation", "ip", "validate", "network"]).schema(z.object({
|
|
2687
|
-
ip: z.string().describe("IP address to validate"),
|
|
2688
|
-
version: z.enum(["v4", "v6", "any"]).default("any").describe("IP version to validate against")
|
|
2689
|
-
})).implement(async (input) => {
|
|
2690
|
-
const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
|
|
2691
|
-
const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;
|
|
2692
|
-
let valid = false;
|
|
2693
|
-
let detectedVersion;
|
|
2694
|
-
if (input.version === "v4" || input.version === "any") {
|
|
2695
|
-
if (ipv4Regex.test(input.ip)) {
|
|
2696
|
-
const parts = input.ip.split(".");
|
|
2697
|
-
valid = parts.every((part) => {
|
|
2698
|
-
const num = parseInt(part, 10);
|
|
2699
|
-
return num >= 0 && num <= 255;
|
|
2700
|
-
});
|
|
2701
|
-
if (valid) detectedVersion = "IPv4";
|
|
3094
|
+
if (!valid && (input.version === "v6" || input.version === "any")) {
|
|
3095
|
+
if (ipv6Regex.test(input.ip)) {
|
|
3096
|
+
valid = true;
|
|
3097
|
+
detectedVersion = "IPv6";
|
|
3098
|
+
}
|
|
2702
3099
|
}
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
detectedVersion
|
|
3100
|
+
return {
|
|
3101
|
+
valid,
|
|
3102
|
+
ip: input.ip,
|
|
3103
|
+
version: detectedVersion,
|
|
3104
|
+
message: valid ? `Valid ${detectedVersion} address` : "Invalid IP address format"
|
|
3105
|
+
};
|
|
3106
|
+
}).build();
|
|
3107
|
+
}
|
|
3108
|
+
function createUuidValidatorTool() {
|
|
3109
|
+
return toolBuilder().name("uuid-validator").description("Validate if a string is a valid UUID (v1, v3, v4, or v5).").category(ToolCategory.UTILITY).tags(["validation", "uuid", "validate", "guid"]).schema(UuidValidatorSchema).implement(async (input) => {
|
|
3110
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
3111
|
+
const valid = uuidRegex.test(input.uuid);
|
|
3112
|
+
let version;
|
|
3113
|
+
if (valid) {
|
|
3114
|
+
version = parseInt(input.uuid[14], 10);
|
|
2708
3115
|
}
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
};
|
|
2716
|
-
}
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
3116
|
+
return {
|
|
3117
|
+
valid,
|
|
3118
|
+
uuid: input.uuid,
|
|
3119
|
+
version,
|
|
3120
|
+
message: valid ? `Valid UUID v${version}` : "Invalid UUID format"
|
|
3121
|
+
};
|
|
3122
|
+
}).build();
|
|
3123
|
+
}
|
|
3124
|
+
|
|
3125
|
+
// src/utility/validation/index.ts
|
|
3126
|
+
var emailValidator = createEmailValidatorTool();
|
|
3127
|
+
var urlValidatorSimple = createUrlValidatorSimpleTool();
|
|
3128
|
+
var phoneValidator = createPhoneValidatorTool();
|
|
3129
|
+
var creditCardValidator = createCreditCardValidatorTool();
|
|
3130
|
+
var ipValidator = createIpValidatorTool();
|
|
3131
|
+
var uuidValidator = createUuidValidatorTool();
|
|
3132
|
+
var validationTools = [
|
|
3133
|
+
emailValidator,
|
|
3134
|
+
urlValidatorSimple,
|
|
3135
|
+
phoneValidator,
|
|
3136
|
+
creditCardValidator,
|
|
3137
|
+
ipValidator,
|
|
3138
|
+
uuidValidator
|
|
3139
|
+
];
|
|
3140
|
+
function createValidationTools(config = {}) {
|
|
3141
|
+
return [
|
|
3142
|
+
createEmailValidatorTool(),
|
|
3143
|
+
createUrlValidatorSimpleTool(),
|
|
3144
|
+
createPhoneValidatorTool(),
|
|
3145
|
+
createCreditCardValidatorTool(),
|
|
3146
|
+
createIpValidatorTool(),
|
|
3147
|
+
createUuidValidatorTool()
|
|
3148
|
+
];
|
|
3149
|
+
}
|
|
2733
3150
|
var AskHumanInputSchema = z.object({
|
|
2734
3151
|
/**
|
|
2735
3152
|
* The question to ask the human
|
|
@@ -2821,6 +3238,6 @@ function createAskHumanTool() {
|
|
|
2821
3238
|
}
|
|
2822
3239
|
var askHumanTool = createAskHumanTool();
|
|
2823
3240
|
|
|
2824
|
-
export { AskHumanInputSchema, DuckDuckGoProvider, SerperProvider, archiveConfluencePage, arrayFilter, arrayGroupBy, arrayMap, arraySort, askHumanTool, calculator, confluenceTools, createAskHumanTool, createConfluencePage, createConfluenceTools, createDuckDuckGoProvider, createSerperProvider, createSlackTools, creditCardValidator, csvGenerator, csvParser, csvToJson, currentDateTime, dateArithmetic, dateComparison, dateDifference, dateFormatter, directoryCreate, directoryDelete, directoryList, emailValidator, extractImages, extractLinks, fileAppend, fileDelete, fileExists, fileReader, fileSearch, fileWriter, getConfluencePage, getSlackChannels, getSlackMessages, getSpacePages, htmlParser, httpClient, httpGet, httpPost, ipValidator, jsonMerge, jsonParser, jsonQuery, jsonStringify, jsonToCsv, jsonToXml, jsonValidator, listConfluenceSpaces, mathFunctions, notifySlack, objectOmit, objectPick, pathBasename, pathDirname, pathExtension, pathJoin, pathNormalize, pathParse, pathRelative, pathResolve, phoneValidator, randomNumber, searchConfluence, searchResultSchema, sendSlackMessage, slackTools, statistics, stringCaseConverter, stringJoin, stringLength, stringReplace, stringSplit, stringSubstring, stringTrim, updateConfluencePage, urlBuilder, urlQueryParser, urlValidator, urlValidatorSimple, uuidValidator, webScraper, webSearch, webSearchOutputSchema, webSearchSchema, xmlGenerator, xmlParser, xmlToJson };
|
|
3241
|
+
export { AskHumanInputSchema, CalculatorSchema, CreditCardValidatorSchema, CurrentDateTimeSchema, DateArithmeticSchema, DateComparisonSchema, DateDifferenceSchema, DateFormatterSchema, DuckDuckGoProvider, EmailValidatorSchema, HttpMethod, IpValidatorSchema, MathFunctionsSchema, PhoneValidatorSchema, RandomNumberSchema, SerperProvider, StatisticsSchema, StringCaseConverterSchema, StringJoinSchema, StringLengthSchema, StringReplaceSchema, StringSplitSchema, StringSubstringSchema, StringTrimSchema, UrlValidatorSimpleSchema, UuidValidatorSchema, archiveConfluencePage, arrayFilter, arrayFilterSchema, arrayGroupBy, arrayGroupBySchema, arrayMap, arrayMapSchema, arraySort, arraySortSchema, askHumanTool, calculator, confluenceTools, createArrayFilterTool, createArrayGroupByTool, createArrayMapTool, createArraySortTool, createAskHumanTool, createCalculatorTool, createConfluencePage, createConfluenceTools, createCreditCardValidatorTool, createCsvGeneratorTool, createCsvParserTool, createCsvToJsonTool, createCsvTools, createCurrentDateTimeTool, createDateArithmeticTool, createDateComparisonTool, createDateDifferenceTool, createDateFormatterTool, createDateTimeTools, createDirectoryCreateTool, createDirectoryDeleteTool, createDirectoryListTool, createDirectoryOperationTools, createDuckDuckGoProvider, createEmailValidatorTool, createExtractImagesTool, createExtractLinksTool, createFileAppendTool, createFileDeleteTool, createFileExistsTool, createFileOperationTools, createFileReaderTool, createFileSearchTool, createFileWriterTool, createHtmlParserTool, createHtmlParserTools, createHttpTools, createIpValidatorTool, createJsonMergeTool, createJsonParserTool, createJsonQueryTool, createJsonStringifyTool, createJsonToCsvTool, createJsonToXmlTool, createJsonTools, createJsonValidatorTool, createMathFunctionsTool, createMathOperationTools, createObjectOmitTool, createObjectPickTool, createPathBasenameTool, createPathDirnameTool, createPathExtensionTool, createPathJoinTool, createPathNormalizeTool, createPathParseTool, createPathRelativeTool, createPathResolveTool, createPathUtilityTools, createPhoneValidatorTool, createRandomNumberTool, createScraperTools, createSerperProvider, createSlackTools, createStatisticsTool, createStringCaseConverterTool, createStringJoinTool, createStringLengthTool, createStringReplaceTool, createStringSplitTool, createStringSubstringTool, createStringTrimTool, createStringUtilityTools, createTransformerTools, createUrlBuilderTool, createUrlQueryParserTool, createUrlValidatorSimpleTool, createUrlValidatorTool, createUrlValidatorTools, createUuidValidatorTool, createValidationTools, createWebScraperTool, createXmlGeneratorTool, createXmlParserTool, createXmlToJsonTool, createXmlTools, creditCardValidator, csvGenerator, csvGeneratorSchema, csvParser, csvParserSchema, csvToJson, csvToJsonSchema, csvTools, currentDateTime, dateArithmetic, dateComparison, dateDifference, dateFormatter, dateTimeTools, directoryCreate, directoryCreateSchema, directoryDelete, directoryDeleteSchema, directoryList, directoryListSchema, directoryOperationTools, emailValidator, extractImages, extractImagesSchema, extractLinks, extractLinksSchema, fileAppend, fileAppendSchema, fileDelete, fileDeleteSchema, fileExists, fileExistsSchema, fileOperationTools, fileReader, fileReaderSchema, fileSearch, fileSearchSchema, fileWriter, fileWriterSchema, getConfluencePage, getSlackChannels, getSlackMessages, getSpacePages, htmlParser, htmlParserSchema, htmlParserTools, httpClient, httpGet, httpGetSchema, httpPost, httpPostSchema, httpRequestSchema, httpTools, ipValidator, jsonMerge, jsonMergeSchema, jsonParser, jsonParserSchema, jsonQuery, jsonQuerySchema, jsonStringify, jsonStringifySchema, jsonToCsv, jsonToCsvSchema, jsonToXml, jsonToXmlSchema, jsonTools, jsonValidator, jsonValidatorSchema, listConfluenceSpaces, mathFunctions, mathOperationTools, notifySlack, objectOmit, objectOmitSchema, objectPick, objectPickSchema, pathBasename, pathBasenameSchema, pathDirname, pathDirnameSchema, pathExtension, pathExtensionSchema, pathJoin, pathJoinSchema, pathNormalize, pathNormalizeSchema, pathParse, pathParseSchema, pathRelative, pathRelativeSchema, pathResolve, pathResolveSchema, pathUtilityTools, phoneValidator, randomNumber, scraperTools, searchConfluence, searchResultSchema, sendSlackMessage, slackTools, statistics, stringCaseConverter, stringJoin, stringLength, stringReplace, stringSplit, stringSubstring, stringTrim, stringUtilityTools, transformerTools, updateConfluencePage, urlBuilder, urlBuilderSchema, urlQueryParser, urlQueryParserSchema, urlValidator, urlValidatorSchema, urlValidatorSimple, urlValidatorTools, uuidValidator, validationTools, webScraper, webScraperSchema, webSearch, webSearchOutputSchema, webSearchSchema, xmlGenerator, xmlGeneratorSchema, xmlParser, xmlParserSchema, xmlToJson, xmlToJsonSchema, xmlTools };
|
|
2825
3242
|
//# sourceMappingURL=index.js.map
|
|
2826
3243
|
//# sourceMappingURL=index.js.map
|