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