@easynet/agent-tool-buildin 0.0.1 → 0.0.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/dist/CoreToolsModule.d.ts +3 -2
- package/dist/CoreToolsModule.d.ts.map +1 -1
- package/dist/exec/runCommand.d.ts.map +1 -1
- package/dist/fs/deletePath.d.ts.map +1 -1
- package/dist/fs/listDir.d.ts.map +1 -1
- package/dist/fs/readText.d.ts.map +1 -1
- package/dist/fs/searchText.d.ts.map +1 -1
- package/dist/fs/sha256.d.ts.map +1 -1
- package/dist/fs/writeText.d.ts.map +1 -1
- package/dist/http/downloadFile.d.ts.map +1 -1
- package/dist/http/duckduckgoSearch.d.ts.map +1 -1
- package/dist/http/fetchJson.d.ts.map +1 -1
- package/dist/http/fetchPageMainContent.d.ts.map +1 -1
- package/dist/http/fetchText.d.ts.map +1 -1
- package/dist/http/head.d.ts.map +1 -1
- package/dist/http/yahooFinance.d.ts +22 -0
- package/dist/http/yahooFinance.d.ts.map +1 -0
- package/dist/index.cjs +261 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +259 -85
- package/dist/index.js.map +1 -1
- package/dist/util/jsonSelect.d.ts.map +1 -1
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/package.json +5 -3
package/dist/index.cjs
CHANGED
|
@@ -2036,7 +2036,8 @@ __export(index_exports, {
|
|
|
2036
2036
|
templateRenderSpec: () => templateRenderSpec,
|
|
2037
2037
|
truncateSpec: () => truncateSpec,
|
|
2038
2038
|
validateUrl: () => validateUrl,
|
|
2039
|
-
writeTextSpec: () => writeTextSpec
|
|
2039
|
+
writeTextSpec: () => writeTextSpec,
|
|
2040
|
+
yahooFinanceQuoteSpec: () => yahooFinanceQuoteSpec
|
|
2040
2041
|
});
|
|
2041
2042
|
module.exports = __toCommonJS(index_exports);
|
|
2042
2043
|
|
|
@@ -2190,7 +2191,10 @@ function isWithinRoot(path, root) {
|
|
|
2190
2191
|
var import_agent_tool2 = require("@easynet/agent-tool");
|
|
2191
2192
|
var readTextHandler = (async (args) => {
|
|
2192
2193
|
const ctx = getBuiltinContext();
|
|
2193
|
-
const inputPath = args.path;
|
|
2194
|
+
const inputPath = (args.path ?? args.filePath)?.trim();
|
|
2195
|
+
if (!inputPath) {
|
|
2196
|
+
throw (0, import_agent_tool2.createTaggedError)("FS_INVALID", "path is required (pass 'path' or 'filePath')", {});
|
|
2197
|
+
}
|
|
2194
2198
|
const maxBytes = args.maxBytes ?? ctx.config.maxReadBytes;
|
|
2195
2199
|
const resolvedPath = await resolveSandboxedPath(inputPath, ctx.config.sandboxRoot);
|
|
2196
2200
|
const fileStat = await (0, import_promises2.stat)(resolvedPath);
|
|
@@ -2225,8 +2229,11 @@ var import_node_crypto = require("crypto");
|
|
|
2225
2229
|
var import_node_path2 = require("path");
|
|
2226
2230
|
var writeTextHandler = (async (args) => {
|
|
2227
2231
|
const ctx = getBuiltinContext();
|
|
2228
|
-
const inputPath = args.path;
|
|
2229
|
-
|
|
2232
|
+
const inputPath = (args.path ?? args.filePath)?.trim();
|
|
2233
|
+
if (!inputPath) {
|
|
2234
|
+
throw new Error("path is required (pass 'path' or 'filePath')");
|
|
2235
|
+
}
|
|
2236
|
+
const text = args.text ?? args.content ?? "";
|
|
2230
2237
|
const overwrite = args.overwrite ?? false;
|
|
2231
2238
|
const mkdirp = args.mkdirp ?? true;
|
|
2232
2239
|
const resolvedPath = await resolveSandboxedPath(inputPath, ctx.config.sandboxRoot);
|
|
@@ -2272,7 +2279,10 @@ var import_promises4 = require("fs/promises");
|
|
|
2272
2279
|
var import_node_path3 = require("path");
|
|
2273
2280
|
var listDirHandler = (async (args) => {
|
|
2274
2281
|
const ctx = getBuiltinContext();
|
|
2275
|
-
const inputPath = args.path;
|
|
2282
|
+
const inputPath = (args.path ?? args.filePath ?? args.dir ?? args.directory)?.trim();
|
|
2283
|
+
if (!inputPath) {
|
|
2284
|
+
throw new Error("path is required (pass 'path', 'filePath', 'dir', or 'directory')");
|
|
2285
|
+
}
|
|
2276
2286
|
const maxEntries = args.maxEntries ?? 2e3;
|
|
2277
2287
|
const includeHidden = args.includeHidden ?? false;
|
|
2278
2288
|
const recursive = args.recursive ?? false;
|
|
@@ -2364,8 +2374,14 @@ var import_node_readline = require("readline");
|
|
|
2364
2374
|
var import_node_path4 = require("path");
|
|
2365
2375
|
var searchTextHandler = (async (args) => {
|
|
2366
2376
|
const ctx = getBuiltinContext();
|
|
2367
|
-
const rootPath = args.root;
|
|
2368
|
-
|
|
2377
|
+
const rootPath = (args.root ?? args.path ?? args.dir ?? args.directory)?.trim();
|
|
2378
|
+
if (!rootPath) {
|
|
2379
|
+
throw new Error("root is required (pass 'root', 'path', 'dir', or 'directory')");
|
|
2380
|
+
}
|
|
2381
|
+
const query = (args.query ?? args.q)?.trim();
|
|
2382
|
+
if (!query) {
|
|
2383
|
+
throw new Error("query is required (pass 'query' or 'q')");
|
|
2384
|
+
}
|
|
2369
2385
|
const glob = args.glob ?? "**/*.{md,txt,log,json,ts,js,py,java,scala}";
|
|
2370
2386
|
const maxMatches = args.maxMatches ?? 100;
|
|
2371
2387
|
const maxFiles = args.maxFiles ?? 500;
|
|
@@ -2484,9 +2500,13 @@ function escapeRegExp(str) {
|
|
|
2484
2500
|
var import_node_fs2 = require("fs");
|
|
2485
2501
|
var import_promises6 = require("fs/promises");
|
|
2486
2502
|
var import_node_crypto2 = require("crypto");
|
|
2503
|
+
var import_agent_tool3 = require("@easynet/agent-tool");
|
|
2487
2504
|
var sha256Handler = (async (args) => {
|
|
2488
2505
|
const ctx = getBuiltinContext();
|
|
2489
|
-
const inputPath = args.path;
|
|
2506
|
+
const inputPath = (args.path ?? args.filePath)?.trim();
|
|
2507
|
+
if (!inputPath) {
|
|
2508
|
+
throw (0, import_agent_tool3.createTaggedError)("FS_INVALID", "path is required (pass 'path' or 'filePath')", {});
|
|
2509
|
+
}
|
|
2490
2510
|
const resolvedPath = await resolveSandboxedPath(inputPath, ctx.config.sandboxRoot);
|
|
2491
2511
|
const fileStat = await (0, import_promises6.stat)(resolvedPath);
|
|
2492
2512
|
const hash = await new Promise((resolve3, reject) => {
|
|
@@ -2517,7 +2537,10 @@ var sha256Handler = (async (args) => {
|
|
|
2517
2537
|
var import_promises7 = require("fs/promises");
|
|
2518
2538
|
var deletePathHandler = (async (args) => {
|
|
2519
2539
|
const ctx = getBuiltinContext();
|
|
2520
|
-
const inputPath = args.path;
|
|
2540
|
+
const inputPath = (args.path ?? args.filePath)?.trim();
|
|
2541
|
+
if (!inputPath) {
|
|
2542
|
+
throw new Error("path is required (pass 'path' or 'filePath')");
|
|
2543
|
+
}
|
|
2521
2544
|
const recursive = args.recursive ?? false;
|
|
2522
2545
|
const confirm = args.confirm;
|
|
2523
2546
|
if (!confirm) {
|
|
@@ -2566,20 +2589,20 @@ var deletePathHandler = (async (args) => {
|
|
|
2566
2589
|
|
|
2567
2590
|
// security/ssrf.ts
|
|
2568
2591
|
var import_promises8 = require("dns/promises");
|
|
2569
|
-
var
|
|
2592
|
+
var import_agent_tool4 = require("@easynet/agent-tool");
|
|
2570
2593
|
async function validateUrl(url, allowedHosts, blockedCidrs) {
|
|
2571
2594
|
let parsed;
|
|
2572
2595
|
try {
|
|
2573
2596
|
parsed = new URL(url);
|
|
2574
2597
|
} catch {
|
|
2575
|
-
throw (0,
|
|
2598
|
+
throw (0, import_agent_tool4.createTaggedError)(
|
|
2576
2599
|
"HTTP_DISALLOWED_HOST",
|
|
2577
2600
|
`Invalid URL: ${url}`,
|
|
2578
2601
|
{ url }
|
|
2579
2602
|
);
|
|
2580
2603
|
}
|
|
2581
2604
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
2582
|
-
throw (0,
|
|
2605
|
+
throw (0, import_agent_tool4.createTaggedError)(
|
|
2583
2606
|
"HTTP_DISALLOWED_HOST",
|
|
2584
2607
|
`Protocol not allowed: ${parsed.protocol}. Only http: and https: are supported.`,
|
|
2585
2608
|
{ url, protocol: parsed.protocol }
|
|
@@ -2587,7 +2610,7 @@ async function validateUrl(url, allowedHosts, blockedCidrs) {
|
|
|
2587
2610
|
}
|
|
2588
2611
|
const hostname = parsed.hostname;
|
|
2589
2612
|
if (!isHostAllowed(hostname, allowedHosts)) {
|
|
2590
|
-
throw (0,
|
|
2613
|
+
throw (0, import_agent_tool4.createTaggedError)(
|
|
2591
2614
|
"HTTP_DISALLOWED_HOST",
|
|
2592
2615
|
`Host "${hostname}" is not in the allowed hosts list`,
|
|
2593
2616
|
{ url, hostname, allowedHosts }
|
|
@@ -2596,7 +2619,7 @@ async function validateUrl(url, allowedHosts, blockedCidrs) {
|
|
|
2596
2619
|
try {
|
|
2597
2620
|
const { address } = await (0, import_promises8.lookup)(hostname);
|
|
2598
2621
|
if (isIpInBlockedCidrs(address, blockedCidrs)) {
|
|
2599
|
-
throw (0,
|
|
2622
|
+
throw (0, import_agent_tool4.createTaggedError)(
|
|
2600
2623
|
"HTTP_DISALLOWED_HOST",
|
|
2601
2624
|
`Host "${hostname}" resolves to blocked IP: ${address}`,
|
|
2602
2625
|
{ url, hostname, resolvedIp: address }
|
|
@@ -2606,7 +2629,7 @@ async function validateUrl(url, allowedHosts, blockedCidrs) {
|
|
|
2606
2629
|
if (err instanceof Error && err.kind === "HTTP_DISALLOWED_HOST") {
|
|
2607
2630
|
throw err;
|
|
2608
2631
|
}
|
|
2609
|
-
throw (0,
|
|
2632
|
+
throw (0, import_agent_tool4.createTaggedError)(
|
|
2610
2633
|
"HTTP_DISALLOWED_HOST",
|
|
2611
2634
|
`DNS resolution failed for host "${hostname}": ${err instanceof Error ? err.message : String(err)}`,
|
|
2612
2635
|
{ url, hostname }
|
|
@@ -2717,10 +2740,13 @@ function expandIpv6(ip) {
|
|
|
2717
2740
|
}
|
|
2718
2741
|
|
|
2719
2742
|
// http/fetchText.ts
|
|
2720
|
-
var
|
|
2743
|
+
var import_agent_tool5 = require("@easynet/agent-tool");
|
|
2721
2744
|
var fetchTextHandler = (async (args) => {
|
|
2722
2745
|
const ctx = getBuiltinContext();
|
|
2723
|
-
const url = args.url;
|
|
2746
|
+
const url = (args.url ?? args.uri)?.trim();
|
|
2747
|
+
if (!url) {
|
|
2748
|
+
throw (0, import_agent_tool5.createTaggedError)("HTTP_INVALID", "url is required (pass 'url' or 'uri')", {});
|
|
2749
|
+
}
|
|
2724
2750
|
const method = args.method ?? "GET";
|
|
2725
2751
|
const headers = args.headers ?? {};
|
|
2726
2752
|
const body = args.body ?? void 0;
|
|
@@ -2742,13 +2768,13 @@ var fetchTextHandler = (async (args) => {
|
|
|
2742
2768
|
});
|
|
2743
2769
|
} catch (err) {
|
|
2744
2770
|
if (err instanceof Error && err.name === "AbortError") {
|
|
2745
|
-
throw (0,
|
|
2771
|
+
throw (0, import_agent_tool5.createTaggedError)(
|
|
2746
2772
|
"HTTP_TIMEOUT",
|
|
2747
2773
|
`Request to ${url} timed out after ${timeoutMs}ms`,
|
|
2748
2774
|
{ url, timeoutMs }
|
|
2749
2775
|
);
|
|
2750
2776
|
}
|
|
2751
|
-
throw (0,
|
|
2777
|
+
throw (0, import_agent_tool5.createTaggedError)(
|
|
2752
2778
|
"UPSTREAM_ERROR",
|
|
2753
2779
|
`Fetch failed for ${url}: ${err instanceof Error ? err.message : String(err)}`,
|
|
2754
2780
|
{ url }
|
|
@@ -2758,7 +2784,7 @@ var fetchTextHandler = (async (args) => {
|
|
|
2758
2784
|
}
|
|
2759
2785
|
const contentLength = response.headers.get("content-length");
|
|
2760
2786
|
if (contentLength && parseInt(contentLength, 10) > maxBytes) {
|
|
2761
|
-
throw (0,
|
|
2787
|
+
throw (0, import_agent_tool5.createTaggedError)(
|
|
2762
2788
|
"HTTP_TOO_LARGE",
|
|
2763
2789
|
`Response Content-Length ${contentLength} exceeds limit of ${maxBytes} bytes`,
|
|
2764
2790
|
{ url, contentLength: parseInt(contentLength, 10), limit: maxBytes }
|
|
@@ -2803,7 +2829,7 @@ async function readResponseWithLimit(response, maxBytes, url) {
|
|
|
2803
2829
|
totalBytes += value.byteLength;
|
|
2804
2830
|
if (totalBytes > maxBytes) {
|
|
2805
2831
|
reader.cancel();
|
|
2806
|
-
throw (0,
|
|
2832
|
+
throw (0, import_agent_tool5.createTaggedError)(
|
|
2807
2833
|
"HTTP_TOO_LARGE",
|
|
2808
2834
|
`Response body exceeded limit of ${maxBytes} bytes while reading from ${url}`,
|
|
2809
2835
|
{ url, bytesRead: totalBytes, limit: maxBytes }
|
|
@@ -2819,10 +2845,13 @@ async function readResponseWithLimit(response, maxBytes, url) {
|
|
|
2819
2845
|
}
|
|
2820
2846
|
|
|
2821
2847
|
// http/fetchJson.ts
|
|
2822
|
-
var
|
|
2848
|
+
var import_agent_tool6 = require("@easynet/agent-tool");
|
|
2823
2849
|
var fetchJsonHandler = (async (args) => {
|
|
2824
2850
|
const ctx = getBuiltinContext();
|
|
2825
|
-
const url = args.url;
|
|
2851
|
+
const url = (args.url ?? args.uri)?.trim();
|
|
2852
|
+
if (!url) {
|
|
2853
|
+
throw (0, import_agent_tool6.createTaggedError)("HTTP_INVALID", "url is required (pass 'url' or 'uri')", {});
|
|
2854
|
+
}
|
|
2826
2855
|
const method = args.method ?? "GET";
|
|
2827
2856
|
const headers = args.headers ?? {};
|
|
2828
2857
|
const body = args.body ?? void 0;
|
|
@@ -2847,13 +2876,13 @@ var fetchJsonHandler = (async (args) => {
|
|
|
2847
2876
|
});
|
|
2848
2877
|
} catch (err) {
|
|
2849
2878
|
if (err instanceof Error && err.name === "AbortError") {
|
|
2850
|
-
throw (0,
|
|
2879
|
+
throw (0, import_agent_tool6.createTaggedError)(
|
|
2851
2880
|
"HTTP_TIMEOUT",
|
|
2852
2881
|
`Request to ${url} timed out after ${timeoutMs}ms`,
|
|
2853
2882
|
{ url, timeoutMs }
|
|
2854
2883
|
);
|
|
2855
2884
|
}
|
|
2856
|
-
throw (0,
|
|
2885
|
+
throw (0, import_agent_tool6.createTaggedError)(
|
|
2857
2886
|
"UPSTREAM_ERROR",
|
|
2858
2887
|
`Fetch failed for ${url}: ${err instanceof Error ? err.message : String(err)}`,
|
|
2859
2888
|
{ url }
|
|
@@ -2863,7 +2892,7 @@ var fetchJsonHandler = (async (args) => {
|
|
|
2863
2892
|
}
|
|
2864
2893
|
const contentLength = response.headers.get("content-length");
|
|
2865
2894
|
if (contentLength && parseInt(contentLength, 10) > maxBytes) {
|
|
2866
|
-
throw (0,
|
|
2895
|
+
throw (0, import_agent_tool6.createTaggedError)(
|
|
2867
2896
|
"HTTP_TOO_LARGE",
|
|
2868
2897
|
`Response Content-Length ${contentLength} exceeds limit of ${maxBytes} bytes`,
|
|
2869
2898
|
{ url, contentLength: parseInt(contentLength, 10), limit: maxBytes }
|
|
@@ -2872,7 +2901,7 @@ var fetchJsonHandler = (async (args) => {
|
|
|
2872
2901
|
const text = await response.text();
|
|
2873
2902
|
const bytes = Buffer.byteLength(text, "utf-8");
|
|
2874
2903
|
if (bytes > maxBytes) {
|
|
2875
|
-
throw (0,
|
|
2904
|
+
throw (0, import_agent_tool6.createTaggedError)(
|
|
2876
2905
|
"HTTP_TOO_LARGE",
|
|
2877
2906
|
`Response body ${bytes} bytes exceeds limit of ${maxBytes} bytes`,
|
|
2878
2907
|
{ url, bytes, limit: maxBytes }
|
|
@@ -2882,7 +2911,7 @@ var fetchJsonHandler = (async (args) => {
|
|
|
2882
2911
|
try {
|
|
2883
2912
|
json = JSON.parse(text);
|
|
2884
2913
|
} catch {
|
|
2885
|
-
throw (0,
|
|
2914
|
+
throw (0, import_agent_tool6.createTaggedError)(
|
|
2886
2915
|
"UPSTREAM_ERROR",
|
|
2887
2916
|
`Failed to parse JSON response from ${url}: ${text.slice(0, 200)}`,
|
|
2888
2917
|
{ url, status: response.status, textPreview: text.slice(0, 500) }
|
|
@@ -2910,11 +2939,17 @@ var fetchJsonHandler = (async (args) => {
|
|
|
2910
2939
|
var import_promises9 = require("fs/promises");
|
|
2911
2940
|
var import_node_crypto3 = require("crypto");
|
|
2912
2941
|
var import_node_path5 = require("path");
|
|
2913
|
-
var
|
|
2942
|
+
var import_agent_tool7 = require("@easynet/agent-tool");
|
|
2914
2943
|
var downloadFileHandler = (async (args) => {
|
|
2915
2944
|
const ctx = getBuiltinContext();
|
|
2916
|
-
const url = args.url;
|
|
2917
|
-
|
|
2945
|
+
const url = (args.url ?? args.uri)?.trim();
|
|
2946
|
+
if (!url) {
|
|
2947
|
+
throw (0, import_agent_tool7.createTaggedError)("HTTP_INVALID", "url is required (pass 'url' or 'uri')", {});
|
|
2948
|
+
}
|
|
2949
|
+
const destPath = (args.destPath ?? args.destination ?? args.filePath)?.trim();
|
|
2950
|
+
if (!destPath) {
|
|
2951
|
+
throw (0, import_agent_tool7.createTaggedError)("HTTP_INVALID", "destPath is required (pass 'destPath', 'destination', or 'filePath')", {});
|
|
2952
|
+
}
|
|
2918
2953
|
const headers = args.headers ?? {};
|
|
2919
2954
|
const timeoutMs = args.timeoutMs ?? ctx.config.defaultTimeoutMs;
|
|
2920
2955
|
const maxBytes = args.maxBytes ?? ctx.config.maxDownloadBytes;
|
|
@@ -2949,13 +2984,13 @@ var downloadFileHandler = (async (args) => {
|
|
|
2949
2984
|
});
|
|
2950
2985
|
} catch (err) {
|
|
2951
2986
|
if (err instanceof Error && err.name === "AbortError") {
|
|
2952
|
-
throw (0,
|
|
2987
|
+
throw (0, import_agent_tool7.createTaggedError)(
|
|
2953
2988
|
"HTTP_TIMEOUT",
|
|
2954
2989
|
`Download from ${url} timed out after ${timeoutMs}ms`,
|
|
2955
2990
|
{ url, timeoutMs }
|
|
2956
2991
|
);
|
|
2957
2992
|
}
|
|
2958
|
-
throw (0,
|
|
2993
|
+
throw (0, import_agent_tool7.createTaggedError)(
|
|
2959
2994
|
"UPSTREAM_ERROR",
|
|
2960
2995
|
`Download failed for ${url}: ${err instanceof Error ? err.message : String(err)}`,
|
|
2961
2996
|
{ url }
|
|
@@ -2965,14 +3000,14 @@ var downloadFileHandler = (async (args) => {
|
|
|
2965
3000
|
}
|
|
2966
3001
|
const contentLength = response.headers.get("content-length");
|
|
2967
3002
|
if (contentLength && parseInt(contentLength, 10) > maxBytes) {
|
|
2968
|
-
throw (0,
|
|
3003
|
+
throw (0, import_agent_tool7.createTaggedError)(
|
|
2969
3004
|
"HTTP_TOO_LARGE",
|
|
2970
3005
|
`Download Content-Length ${contentLength} exceeds limit of ${maxBytes} bytes`,
|
|
2971
3006
|
{ url, contentLength: parseInt(contentLength, 10), limit: maxBytes }
|
|
2972
3007
|
);
|
|
2973
3008
|
}
|
|
2974
3009
|
if (!response.body) {
|
|
2975
|
-
throw (0,
|
|
3010
|
+
throw (0, import_agent_tool7.createTaggedError)("UPSTREAM_ERROR", `No response body from ${url}`, { url });
|
|
2976
3011
|
}
|
|
2977
3012
|
const reader = response.body.getReader();
|
|
2978
3013
|
const chunks = [];
|
|
@@ -2985,7 +3020,7 @@ var downloadFileHandler = (async (args) => {
|
|
|
2985
3020
|
totalBytes += value.byteLength;
|
|
2986
3021
|
if (totalBytes > maxBytes) {
|
|
2987
3022
|
reader.cancel();
|
|
2988
|
-
throw (0,
|
|
3023
|
+
throw (0, import_agent_tool7.createTaggedError)(
|
|
2989
3024
|
"HTTP_TOO_LARGE",
|
|
2990
3025
|
`Download from ${url} exceeded limit of ${maxBytes} bytes (received ${totalBytes})`,
|
|
2991
3026
|
{ url, bytesRead: totalBytes, limit: maxBytes }
|
|
@@ -3027,10 +3062,13 @@ var downloadFileHandler = (async (args) => {
|
|
|
3027
3062
|
});
|
|
3028
3063
|
|
|
3029
3064
|
// http/head.ts
|
|
3030
|
-
var
|
|
3065
|
+
var import_agent_tool8 = require("@easynet/agent-tool");
|
|
3031
3066
|
var headHandler = (async (args) => {
|
|
3032
3067
|
const ctx = getBuiltinContext();
|
|
3033
|
-
const url = args.url;
|
|
3068
|
+
const url = (args.url ?? args.uri)?.trim();
|
|
3069
|
+
if (!url) {
|
|
3070
|
+
throw (0, import_agent_tool8.createTaggedError)("HTTP_INVALID", "url is required (pass 'url' or 'uri')", {});
|
|
3071
|
+
}
|
|
3034
3072
|
const headers = args.headers ?? {};
|
|
3035
3073
|
const timeoutMs = args.timeoutMs ?? ctx.config.defaultTimeoutMs;
|
|
3036
3074
|
await validateUrl(url, ctx.config.allowedHosts, ctx.config.blockedCidrs);
|
|
@@ -3048,13 +3086,13 @@ var headHandler = (async (args) => {
|
|
|
3048
3086
|
});
|
|
3049
3087
|
} catch (err) {
|
|
3050
3088
|
if (err instanceof Error && err.name === "AbortError") {
|
|
3051
|
-
throw (0,
|
|
3089
|
+
throw (0, import_agent_tool8.createTaggedError)(
|
|
3052
3090
|
"HTTP_TIMEOUT",
|
|
3053
3091
|
`HEAD request to ${url} timed out after ${timeoutMs}ms`,
|
|
3054
3092
|
{ url, timeoutMs }
|
|
3055
3093
|
);
|
|
3056
3094
|
}
|
|
3057
|
-
throw (0,
|
|
3095
|
+
throw (0, import_agent_tool8.createTaggedError)(
|
|
3058
3096
|
"UPSTREAM_ERROR",
|
|
3059
3097
|
`HEAD request failed for ${url}: ${err instanceof Error ? err.message : String(err)}`,
|
|
3060
3098
|
{ url }
|
|
@@ -3084,13 +3122,13 @@ var headHandler = (async (args) => {
|
|
|
3084
3122
|
});
|
|
3085
3123
|
|
|
3086
3124
|
// http/duckduckgoSearch.ts
|
|
3087
|
-
var
|
|
3125
|
+
var import_agent_tool9 = require("@easynet/agent-tool");
|
|
3088
3126
|
var DUCKDUCKGO_API = "https://api.duckduckgo.com/";
|
|
3089
3127
|
var duckduckgoSearchHandler = (async (args) => {
|
|
3090
3128
|
const ctx = getBuiltinContext();
|
|
3091
|
-
const query = args.query?.trim();
|
|
3129
|
+
const query = (args.query ?? args.q)?.trim();
|
|
3092
3130
|
if (!query) {
|
|
3093
|
-
throw (0,
|
|
3131
|
+
throw (0, import_agent_tool9.createTaggedError)("DUCKDUCKGO_INVALID", "query is required (pass 'query' or 'q')", {});
|
|
3094
3132
|
}
|
|
3095
3133
|
const timeoutMs = args.timeoutMs ?? ctx.config.defaultTimeoutMs;
|
|
3096
3134
|
const maxResults = args.maxResults ?? 10;
|
|
@@ -3108,13 +3146,13 @@ var duckduckgoSearchHandler = (async (args) => {
|
|
|
3108
3146
|
} catch (err) {
|
|
3109
3147
|
clearTimeout(timer);
|
|
3110
3148
|
if (err instanceof Error && err.name === "AbortError") {
|
|
3111
|
-
throw (0,
|
|
3149
|
+
throw (0, import_agent_tool9.createTaggedError)(
|
|
3112
3150
|
"HTTP_TIMEOUT",
|
|
3113
3151
|
`DuckDuckGo search timed out after ${timeoutMs}ms`,
|
|
3114
3152
|
{ query, timeoutMs }
|
|
3115
3153
|
);
|
|
3116
3154
|
}
|
|
3117
|
-
throw (0,
|
|
3155
|
+
throw (0, import_agent_tool9.createTaggedError)(
|
|
3118
3156
|
"UPSTREAM_ERROR",
|
|
3119
3157
|
`DuckDuckGo search failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
3120
3158
|
{ query }
|
|
@@ -3125,7 +3163,7 @@ var duckduckgoSearchHandler = (async (args) => {
|
|
|
3125
3163
|
const text = await response.text();
|
|
3126
3164
|
const bytes = Buffer.byteLength(text, "utf-8");
|
|
3127
3165
|
if (bytes > maxBytes) {
|
|
3128
|
-
throw (0,
|
|
3166
|
+
throw (0, import_agent_tool9.createTaggedError)(
|
|
3129
3167
|
"HTTP_TOO_LARGE",
|
|
3130
3168
|
`DuckDuckGo response ${bytes} bytes exceeds limit of ${maxBytes} bytes`,
|
|
3131
3169
|
{ query, bytes, limit: maxBytes }
|
|
@@ -3135,7 +3173,7 @@ var duckduckgoSearchHandler = (async (args) => {
|
|
|
3135
3173
|
try {
|
|
3136
3174
|
raw = JSON.parse(text);
|
|
3137
3175
|
} catch {
|
|
3138
|
-
throw (0,
|
|
3176
|
+
throw (0, import_agent_tool9.createTaggedError)(
|
|
3139
3177
|
"UPSTREAM_ERROR",
|
|
3140
3178
|
`DuckDuckGo returned invalid JSON`,
|
|
3141
3179
|
{ query, textPreview: text.slice(0, 200) }
|
|
@@ -3186,7 +3224,7 @@ var duckduckgoSearchHandler = (async (args) => {
|
|
|
3186
3224
|
|
|
3187
3225
|
// http/fetchPageMainContent.ts
|
|
3188
3226
|
var import_node_html_parser = require("node-html-parser");
|
|
3189
|
-
var
|
|
3227
|
+
var import_agent_tool10 = require("@easynet/agent-tool");
|
|
3190
3228
|
var MAIN_SELECTORS = [
|
|
3191
3229
|
"main",
|
|
3192
3230
|
"article",
|
|
@@ -3227,7 +3265,10 @@ function extractMainContent(html) {
|
|
|
3227
3265
|
}
|
|
3228
3266
|
var fetchPageMainContentHandler = (async (args) => {
|
|
3229
3267
|
const ctx = getBuiltinContext();
|
|
3230
|
-
const url = args.url;
|
|
3268
|
+
const url = (args.url ?? args.uri)?.trim();
|
|
3269
|
+
if (!url) {
|
|
3270
|
+
throw (0, import_agent_tool10.createTaggedError)("HTTP_INVALID", "url is required (pass 'url' or 'uri')", {});
|
|
3271
|
+
}
|
|
3231
3272
|
const timeoutMs = args.timeoutMs ?? ctx.config.defaultTimeoutMs;
|
|
3232
3273
|
const maxBytes = args.maxBytes ?? ctx.config.maxHttpBytes;
|
|
3233
3274
|
await validateUrl(url, ctx.config.allowedHosts, ctx.config.blockedCidrs);
|
|
@@ -3243,13 +3284,13 @@ var fetchPageMainContentHandler = (async (args) => {
|
|
|
3243
3284
|
} catch (err) {
|
|
3244
3285
|
clearTimeout(timer);
|
|
3245
3286
|
if (err instanceof Error && err.name === "AbortError") {
|
|
3246
|
-
throw (0,
|
|
3287
|
+
throw (0, import_agent_tool10.createTaggedError)(
|
|
3247
3288
|
"HTTP_TIMEOUT",
|
|
3248
3289
|
`Request to ${url} timed out after ${timeoutMs}ms`,
|
|
3249
3290
|
{ url, timeoutMs }
|
|
3250
3291
|
);
|
|
3251
3292
|
}
|
|
3252
|
-
throw (0,
|
|
3293
|
+
throw (0, import_agent_tool10.createTaggedError)(
|
|
3253
3294
|
"UPSTREAM_ERROR",
|
|
3254
3295
|
`Fetch failed for ${url}: ${err instanceof Error ? err.message : String(err)}`,
|
|
3255
3296
|
{ url }
|
|
@@ -3258,7 +3299,7 @@ var fetchPageMainContentHandler = (async (args) => {
|
|
|
3258
3299
|
clearTimeout(timer);
|
|
3259
3300
|
const contentLength = response.headers.get("content-length");
|
|
3260
3301
|
if (contentLength && parseInt(contentLength, 10) > maxBytes) {
|
|
3261
|
-
throw (0,
|
|
3302
|
+
throw (0, import_agent_tool10.createTaggedError)(
|
|
3262
3303
|
"HTTP_TOO_LARGE",
|
|
3263
3304
|
`Response Content-Length ${contentLength} exceeds limit of ${maxBytes} bytes`,
|
|
3264
3305
|
{ url, contentLength: parseInt(contentLength, 10), limit: maxBytes }
|
|
@@ -3267,7 +3308,7 @@ var fetchPageMainContentHandler = (async (args) => {
|
|
|
3267
3308
|
const rawText = await response.text();
|
|
3268
3309
|
const rawBytes = Buffer.byteLength(rawText, "utf-8");
|
|
3269
3310
|
if (rawBytes > maxBytes) {
|
|
3270
|
-
throw (0,
|
|
3311
|
+
throw (0, import_agent_tool10.createTaggedError)(
|
|
3271
3312
|
"HTTP_TOO_LARGE",
|
|
3272
3313
|
`Response body ${rawBytes} bytes exceeds limit of ${maxBytes} bytes`,
|
|
3273
3314
|
{ url, bytes: rawBytes, limit: maxBytes }
|
|
@@ -3309,10 +3350,133 @@ var fetchPageMainContentHandler = (async (args) => {
|
|
|
3309
3350
|
};
|
|
3310
3351
|
});
|
|
3311
3352
|
|
|
3353
|
+
// http/yahooFinance.ts
|
|
3354
|
+
var import_agent_tool11 = require("@easynet/agent-tool");
|
|
3355
|
+
var YAHOO_CHART_BASE = "https://query1.finance.yahoo.com/v8/finance/chart/";
|
|
3356
|
+
var yahooFinanceQuoteHandler = (async (args) => {
|
|
3357
|
+
const ctx = getBuiltinContext();
|
|
3358
|
+
const rawSymbols = args.symbols ?? args.symbol ?? args.tickers;
|
|
3359
|
+
const symbols = Array.isArray(rawSymbols) ? rawSymbols.map((s) => String(s).trim().toUpperCase()).filter(Boolean) : rawSymbols != null ? [String(rawSymbols).trim().toUpperCase()].filter(Boolean) : [];
|
|
3360
|
+
if (symbols.length === 0) {
|
|
3361
|
+
throw (0, import_agent_tool11.createTaggedError)(
|
|
3362
|
+
"YAHOO_INVALID",
|
|
3363
|
+
"At least one symbol is required",
|
|
3364
|
+
{}
|
|
3365
|
+
);
|
|
3366
|
+
}
|
|
3367
|
+
const range = args.range ?? "1d";
|
|
3368
|
+
const timeoutMs = args.timeoutMs ?? ctx.config.defaultTimeoutMs;
|
|
3369
|
+
const maxBytes = ctx.config.maxHttpBytes;
|
|
3370
|
+
const quotes = [];
|
|
3371
|
+
for (const symbol of symbols) {
|
|
3372
|
+
const url2 = `${YAHOO_CHART_BASE}${encodeURIComponent(symbol)}?interval=1d&range=${range}`;
|
|
3373
|
+
await validateUrl(url2, ctx.config.allowedHosts, ctx.config.blockedCidrs);
|
|
3374
|
+
const controller = new AbortController();
|
|
3375
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
3376
|
+
let response;
|
|
3377
|
+
try {
|
|
3378
|
+
response = await fetch(url2, {
|
|
3379
|
+
method: "GET",
|
|
3380
|
+
headers: {
|
|
3381
|
+
"User-Agent": ctx.config.httpUserAgent,
|
|
3382
|
+
Accept: "application/json"
|
|
3383
|
+
},
|
|
3384
|
+
signal: controller.signal
|
|
3385
|
+
});
|
|
3386
|
+
} catch (err) {
|
|
3387
|
+
clearTimeout(timer);
|
|
3388
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
3389
|
+
throw (0, import_agent_tool11.createTaggedError)(
|
|
3390
|
+
"HTTP_TIMEOUT",
|
|
3391
|
+
`Yahoo Finance request for ${symbol} timed out after ${timeoutMs}ms`,
|
|
3392
|
+
{ symbol, timeoutMs }
|
|
3393
|
+
);
|
|
3394
|
+
}
|
|
3395
|
+
throw (0, import_agent_tool11.createTaggedError)(
|
|
3396
|
+
"UPSTREAM_ERROR",
|
|
3397
|
+
`Yahoo Finance request failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
3398
|
+
{ symbol }
|
|
3399
|
+
);
|
|
3400
|
+
}
|
|
3401
|
+
clearTimeout(timer);
|
|
3402
|
+
const text = await response.text();
|
|
3403
|
+
const bytes = Buffer.byteLength(text, "utf-8");
|
|
3404
|
+
if (bytes > maxBytes) {
|
|
3405
|
+
throw (0, import_agent_tool11.createTaggedError)(
|
|
3406
|
+
"HTTP_TOO_LARGE",
|
|
3407
|
+
`Yahoo Finance response ${bytes} bytes exceeds limit of ${maxBytes} bytes`,
|
|
3408
|
+
{ symbol, bytes, limit: maxBytes }
|
|
3409
|
+
);
|
|
3410
|
+
}
|
|
3411
|
+
let data;
|
|
3412
|
+
try {
|
|
3413
|
+
data = JSON.parse(text);
|
|
3414
|
+
} catch {
|
|
3415
|
+
throw (0, import_agent_tool11.createTaggedError)(
|
|
3416
|
+
"UPSTREAM_ERROR",
|
|
3417
|
+
"Yahoo Finance returned invalid JSON",
|
|
3418
|
+
{ symbol, textPreview: text.slice(0, 200) }
|
|
3419
|
+
);
|
|
3420
|
+
}
|
|
3421
|
+
const error = data.chart?.error;
|
|
3422
|
+
if (error?.description) {
|
|
3423
|
+
throw (0, import_agent_tool11.createTaggedError)(
|
|
3424
|
+
"YAHOO_ERROR",
|
|
3425
|
+
`Yahoo Finance error for ${symbol}: ${error.description}`,
|
|
3426
|
+
{ symbol, code: error.code }
|
|
3427
|
+
);
|
|
3428
|
+
}
|
|
3429
|
+
const result = data.chart?.result?.[0];
|
|
3430
|
+
if (!result) {
|
|
3431
|
+
quotes.push({ symbol });
|
|
3432
|
+
continue;
|
|
3433
|
+
}
|
|
3434
|
+
const meta = result.meta ?? {};
|
|
3435
|
+
const quoteArr = result.indicators?.quote?.[0];
|
|
3436
|
+
const lastIdx = (result.timestamp?.length ?? 1) - 1;
|
|
3437
|
+
const price = meta.regularMarketPrice ?? meta.previousClose ?? quoteArr?.close?.[lastIdx] ?? void 0;
|
|
3438
|
+
const previousClose = meta.previousClose ?? meta.chartPreviousClose ?? quoteArr?.close?.[Math.max(0, lastIdx - 1)] ?? void 0;
|
|
3439
|
+
const change = price != null && previousClose != null ? price - previousClose : void 0;
|
|
3440
|
+
const changePercent = change != null && previousClose != null && previousClose !== 0 ? change / previousClose * 100 : void 0;
|
|
3441
|
+
quotes.push({
|
|
3442
|
+
symbol: meta.symbol ?? symbol,
|
|
3443
|
+
currency: meta.currency,
|
|
3444
|
+
price: price ?? void 0,
|
|
3445
|
+
previousClose: previousClose ?? void 0,
|
|
3446
|
+
change,
|
|
3447
|
+
changePercent,
|
|
3448
|
+
open: quoteArr?.open?.[lastIdx] ?? void 0,
|
|
3449
|
+
high: quoteArr?.high?.[lastIdx] ?? void 0,
|
|
3450
|
+
low: quoteArr?.low?.[lastIdx] ?? void 0,
|
|
3451
|
+
volume: quoteArr?.volume?.[lastIdx] ?? void 0,
|
|
3452
|
+
timestamp: result.timestamp?.[lastIdx]
|
|
3453
|
+
});
|
|
3454
|
+
}
|
|
3455
|
+
const url = `${YAHOO_CHART_BASE}${encodeURIComponent(symbols[0])}?interval=1d&range=${range}`;
|
|
3456
|
+
return {
|
|
3457
|
+
result: {
|
|
3458
|
+
symbols: quotes.map((q) => q.symbol),
|
|
3459
|
+
quotes,
|
|
3460
|
+
range
|
|
3461
|
+
},
|
|
3462
|
+
evidence: [
|
|
3463
|
+
{
|
|
3464
|
+
type: "url",
|
|
3465
|
+
ref: url,
|
|
3466
|
+
summary: `Yahoo Finance quote: ${symbols.join(", ")} (${quotes.length} result(s))`,
|
|
3467
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3468
|
+
}
|
|
3469
|
+
]
|
|
3470
|
+
};
|
|
3471
|
+
});
|
|
3472
|
+
|
|
3312
3473
|
// util/jsonSelect.ts
|
|
3313
3474
|
var jsonSelectHandler = (async (args) => {
|
|
3314
3475
|
const json = args.json;
|
|
3315
|
-
const path = args.path;
|
|
3476
|
+
const path = (args.path ?? args.expression)?.trim();
|
|
3477
|
+
if (path === void 0 || path === "") {
|
|
3478
|
+
throw new Error("path is required (pass 'path' or 'expression')");
|
|
3479
|
+
}
|
|
3316
3480
|
let jmespath;
|
|
3317
3481
|
try {
|
|
3318
3482
|
jmespath = await Promise.resolve().then(() => __toESM(require_jmespath(), 1));
|
|
@@ -3469,37 +3633,37 @@ var templateRenderHandler = (async (args) => {
|
|
|
3469
3633
|
// exec/runCommand.ts
|
|
3470
3634
|
var import_node_child_process = require("child_process");
|
|
3471
3635
|
var import_node_path6 = require("path");
|
|
3472
|
-
var
|
|
3636
|
+
var import_agent_tool12 = require("@easynet/agent-tool");
|
|
3473
3637
|
var runCommandHandler = (async (args) => {
|
|
3474
3638
|
const ctx = getBuiltinContext();
|
|
3475
3639
|
const { allowedCommands, maxCommandOutputBytes, commandTimeoutMs } = ctx.config;
|
|
3476
3640
|
if (!allowedCommands.length) {
|
|
3477
|
-
throw (0,
|
|
3641
|
+
throw (0, import_agent_tool12.createTaggedError)(
|
|
3478
3642
|
"EXEC_DISABLED",
|
|
3479
3643
|
"Exec is disabled: allowedCommands is empty",
|
|
3480
3644
|
{}
|
|
3481
3645
|
);
|
|
3482
3646
|
}
|
|
3483
|
-
const rawCommand = args.command?.trim();
|
|
3647
|
+
const rawCommand = (args.command ?? args.cmd)?.trim();
|
|
3484
3648
|
if (!rawCommand) {
|
|
3485
|
-
throw (0,
|
|
3649
|
+
throw (0, import_agent_tool12.createTaggedError)("EXEC_INVALID", "command is required (pass 'command' or 'cmd')", {});
|
|
3486
3650
|
}
|
|
3487
3651
|
const baseName = rawCommand.replace(/^.*\//, "").trim();
|
|
3488
3652
|
if (baseName !== rawCommand || /[;&|$`\s]/.test(rawCommand)) {
|
|
3489
|
-
throw (0,
|
|
3653
|
+
throw (0, import_agent_tool12.createTaggedError)(
|
|
3490
3654
|
"EXEC_INVALID",
|
|
3491
3655
|
"command must be a single executable name (no path, no shell chars)",
|
|
3492
3656
|
{ command: rawCommand }
|
|
3493
3657
|
);
|
|
3494
3658
|
}
|
|
3495
3659
|
if (!allowedCommands.includes(baseName)) {
|
|
3496
|
-
throw (0,
|
|
3660
|
+
throw (0, import_agent_tool12.createTaggedError)(
|
|
3497
3661
|
"EXEC_NOT_ALLOWED",
|
|
3498
3662
|
`Command "${baseName}" is not in allowedCommands`,
|
|
3499
3663
|
{ command: baseName, allowed: allowedCommands }
|
|
3500
3664
|
);
|
|
3501
3665
|
}
|
|
3502
|
-
const cmdArgs = Array.isArray(args.args) ? args.args : [];
|
|
3666
|
+
const cmdArgs = Array.isArray(args.args) ? args.args : Array.isArray(args.arguments) ? args.arguments : [];
|
|
3503
3667
|
const timeoutMs = args.timeoutMs ?? commandTimeoutMs;
|
|
3504
3668
|
let cwd = (0, import_node_path6.resolve)(ctx.config.sandboxRoot);
|
|
3505
3669
|
if (args.cwd != null && args.cwd !== "") {
|
|
@@ -3520,7 +3684,7 @@ var runCommandHandler = (async (args) => {
|
|
|
3520
3684
|
if (totalBytes + len > maxCommandOutputBytes) {
|
|
3521
3685
|
proc.kill("SIGKILL");
|
|
3522
3686
|
rejectPromise(
|
|
3523
|
-
(0,
|
|
3687
|
+
(0, import_agent_tool12.createTaggedError)(
|
|
3524
3688
|
"EXEC_OUTPUT_TOO_LARGE",
|
|
3525
3689
|
`Command output exceeded ${maxCommandOutputBytes} bytes`,
|
|
3526
3690
|
{ maxBytes: maxCommandOutputBytes }
|
|
@@ -3558,7 +3722,7 @@ var runCommandHandler = (async (args) => {
|
|
|
3558
3722
|
proc.on("error", (err) => {
|
|
3559
3723
|
clearTimeout(timeout);
|
|
3560
3724
|
rejectPromise(
|
|
3561
|
-
(0,
|
|
3725
|
+
(0, import_agent_tool12.createTaggedError)("EXEC_SPAWN_ERROR", err.message, { command: baseName })
|
|
3562
3726
|
);
|
|
3563
3727
|
});
|
|
3564
3728
|
proc.on("close", (code, signal) => {
|
|
@@ -3590,7 +3754,7 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3590
3754
|
{
|
|
3591
3755
|
name: "core/fs.readText",
|
|
3592
3756
|
kind: "core",
|
|
3593
|
-
description: "Read a UTF-8 text file from the sandbox",
|
|
3757
|
+
description: "Read a UTF-8 text file from the sandbox. Input: path (or filePath), optional maxBytes.",
|
|
3594
3758
|
tags: ["filesystem", "read", "core"],
|
|
3595
3759
|
capabilities: ["read:fs"],
|
|
3596
3760
|
sideEffect: "none"
|
|
@@ -3598,7 +3762,7 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3598
3762
|
{
|
|
3599
3763
|
name: "core/fs.writeText",
|
|
3600
3764
|
kind: "core",
|
|
3601
|
-
description: "Write UTF-8 text to a file in the sandbox",
|
|
3765
|
+
description: "Write UTF-8 text to a file in the sandbox. Input: path (or filePath), text (or content), optional overwrite, mkdirp.",
|
|
3602
3766
|
tags: ["filesystem", "write", "core"],
|
|
3603
3767
|
capabilities: ["write:fs"],
|
|
3604
3768
|
sideEffect: "local_write"
|
|
@@ -3606,7 +3770,7 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3606
3770
|
{
|
|
3607
3771
|
name: "core/fs.listDir",
|
|
3608
3772
|
kind: "core",
|
|
3609
|
-
description: "List directory contents in the sandbox",
|
|
3773
|
+
description: "List directory contents in the sandbox. Input: path (or filePath, dir, directory), optional maxEntries, includeHidden, recursive, maxDepth.",
|
|
3610
3774
|
tags: ["filesystem", "read", "core"],
|
|
3611
3775
|
capabilities: ["read:fs"],
|
|
3612
3776
|
sideEffect: "none"
|
|
@@ -3614,7 +3778,7 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3614
3778
|
{
|
|
3615
3779
|
name: "core/fs.searchText",
|
|
3616
3780
|
kind: "core",
|
|
3617
|
-
description: "Search for text patterns in files within the sandbox",
|
|
3781
|
+
description: "Search for text patterns in files within the sandbox. Input: root (or path, dir, directory), query (or q), optional glob, maxMatches, maxFiles.",
|
|
3618
3782
|
tags: ["filesystem", "search", "core"],
|
|
3619
3783
|
capabilities: ["read:fs"],
|
|
3620
3784
|
sideEffect: "none"
|
|
@@ -3622,7 +3786,7 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3622
3786
|
{
|
|
3623
3787
|
name: "core/fs.sha256",
|
|
3624
3788
|
kind: "core",
|
|
3625
|
-
description: "Compute SHA-256 hash of a file in the sandbox",
|
|
3789
|
+
description: "Compute SHA-256 hash of a file in the sandbox. Input: path (or filePath).",
|
|
3626
3790
|
tags: ["filesystem", "hash", "core"],
|
|
3627
3791
|
capabilities: ["read:fs"],
|
|
3628
3792
|
sideEffect: "none"
|
|
@@ -3630,7 +3794,7 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3630
3794
|
{
|
|
3631
3795
|
name: "core/fs.deletePath",
|
|
3632
3796
|
kind: "core",
|
|
3633
|
-
description: "Delete a file or directory in the sandbox (dangerous, requires explicit confirmation)",
|
|
3797
|
+
description: "Delete a file or directory in the sandbox (dangerous, requires explicit confirmation). Input: path (or filePath), confirm=true, optional recursive.",
|
|
3634
3798
|
tags: ["filesystem", "delete", "dangerous", "core"],
|
|
3635
3799
|
capabilities: ["danger:destructive", "write:fs"],
|
|
3636
3800
|
sideEffect: "destructive"
|
|
@@ -3639,7 +3803,7 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3639
3803
|
{
|
|
3640
3804
|
name: "core/http.fetchText",
|
|
3641
3805
|
kind: "core",
|
|
3642
|
-
description: "Fetch a URL and return the response as text",
|
|
3806
|
+
description: "Fetch a URL and return the response as text. Input: url (or uri), optional method, headers, body, timeoutMs, maxBytes.",
|
|
3643
3807
|
tags: ["http", "network", "core"],
|
|
3644
3808
|
capabilities: ["network"],
|
|
3645
3809
|
sideEffect: "none"
|
|
@@ -3647,7 +3811,7 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3647
3811
|
{
|
|
3648
3812
|
name: "core/http.fetchJson",
|
|
3649
3813
|
kind: "core",
|
|
3650
|
-
description: "Fetch a URL and return the response as parsed JSON",
|
|
3814
|
+
description: "Fetch a URL and return the response as parsed JSON. Input: url (or uri), optional method, headers, body, timeoutMs, maxBytes.",
|
|
3651
3815
|
tags: ["http", "network", "json", "core"],
|
|
3652
3816
|
capabilities: ["network"],
|
|
3653
3817
|
sideEffect: "none"
|
|
@@ -3655,7 +3819,7 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3655
3819
|
{
|
|
3656
3820
|
name: "core/http.downloadFile",
|
|
3657
3821
|
kind: "core",
|
|
3658
|
-
description: "Download a file from a URL to the sandbox",
|
|
3822
|
+
description: "Download a file from a URL to the sandbox. Input: url (or uri), destPath (or destination, filePath), optional headers, timeoutMs, maxBytes, overwrite.",
|
|
3659
3823
|
tags: ["http", "network", "download", "core"],
|
|
3660
3824
|
capabilities: ["network", "write:fs"],
|
|
3661
3825
|
sideEffect: "local_write"
|
|
@@ -3663,7 +3827,7 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3663
3827
|
{
|
|
3664
3828
|
name: "core/http.head",
|
|
3665
3829
|
kind: "core",
|
|
3666
|
-
description: "Send a HEAD request to get response headers without body",
|
|
3830
|
+
description: "Send a HEAD request to get response headers without body. Input: url (or uri), optional headers, timeoutMs.",
|
|
3667
3831
|
tags: ["http", "network", "core"],
|
|
3668
3832
|
capabilities: ["network"],
|
|
3669
3833
|
sideEffect: "none"
|
|
@@ -3671,7 +3835,7 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3671
3835
|
{
|
|
3672
3836
|
name: "core/http.duckduckgoSearch",
|
|
3673
3837
|
kind: "core",
|
|
3674
|
-
description: "Search DuckDuckGo via Instant Answer API (no API key). Add api.duckduckgo.com to allowedHosts.",
|
|
3838
|
+
description: "Search DuckDuckGo via Instant Answer API (no API key). Add api.duckduckgo.com to allowedHosts. Input: use 'query' (or 'q') for the search string, optional 'maxResults'.",
|
|
3675
3839
|
tags: ["http", "search", "duckduckgo", "core"],
|
|
3676
3840
|
capabilities: ["network"],
|
|
3677
3841
|
sideEffect: "none"
|
|
@@ -3679,16 +3843,24 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3679
3843
|
{
|
|
3680
3844
|
name: "core/http.fetchPageMainContent",
|
|
3681
3845
|
kind: "core",
|
|
3682
|
-
description: "Fetch a URL and return only the main content (main/article/body text). Strips nav, header, footer, scripts.",
|
|
3846
|
+
description: "Fetch a URL and return only the main content (main/article/body text). Strips nav, header, footer, scripts. Input: url (or uri), optional timeoutMs, maxBytes.",
|
|
3683
3847
|
tags: ["http", "network", "html", "main-content", "core"],
|
|
3684
3848
|
capabilities: ["network"],
|
|
3685
3849
|
sideEffect: "none"
|
|
3686
3850
|
},
|
|
3851
|
+
{
|
|
3852
|
+
name: "core/http.yahooFinanceQuote",
|
|
3853
|
+
kind: "core",
|
|
3854
|
+
description: "Fetch stock quote(s) from Yahoo Finance chart API (no API key). Add query1.finance.yahoo.com to allowedHosts. Input: symbols (or symbol, tickers), optional range, timeoutMs.",
|
|
3855
|
+
tags: ["http", "finance", "yahoo", "stock", "quote", "core"],
|
|
3856
|
+
capabilities: ["network"],
|
|
3857
|
+
sideEffect: "none"
|
|
3858
|
+
},
|
|
3687
3859
|
// Utils
|
|
3688
3860
|
{
|
|
3689
3861
|
name: "core/util.json.select",
|
|
3690
3862
|
kind: "core",
|
|
3691
|
-
description: "Select fields from JSON data using JMESPath expressions",
|
|
3863
|
+
description: "Select fields from JSON data using JMESPath expressions. Input: json, path (or expression).",
|
|
3692
3864
|
tags: ["util", "json", "core"],
|
|
3693
3865
|
capabilities: [],
|
|
3694
3866
|
sideEffect: "none"
|
|
@@ -3729,7 +3901,7 @@ var CORE_TOOL_MANIFEST = [
|
|
|
3729
3901
|
{
|
|
3730
3902
|
name: "core/exec.runCommand",
|
|
3731
3903
|
kind: "core",
|
|
3732
|
-
description: "Run a Linux command in the sandbox (allowlist, timeout, no shell).
|
|
3904
|
+
description: "Run a Linux command in the sandbox (allowlist, timeout, no shell). Input: command (or cmd), optional args (or arguments), cwd, timeoutMs.",
|
|
3733
3905
|
tags: ["exec", "shell", "linux", "core"],
|
|
3734
3906
|
capabilities: ["exec"],
|
|
3735
3907
|
sideEffect: "local_write"
|
|
@@ -3748,6 +3920,7 @@ var CORE_TOOL_HANDLERS = [
|
|
|
3748
3920
|
headHandler,
|
|
3749
3921
|
duckduckgoSearchHandler,
|
|
3750
3922
|
fetchPageMainContentHandler,
|
|
3923
|
+
yahooFinanceQuoteHandler,
|
|
3751
3924
|
jsonSelectHandler,
|
|
3752
3925
|
truncateHandler,
|
|
3753
3926
|
hashTextHandler,
|
|
@@ -3765,14 +3938,15 @@ var fetchTextSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[6]);
|
|
|
3765
3938
|
var fetchJsonSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[7]);
|
|
3766
3939
|
var downloadFileSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[8]);
|
|
3767
3940
|
var headSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[9]);
|
|
3768
|
-
var
|
|
3769
|
-
var
|
|
3770
|
-
var
|
|
3771
|
-
var
|
|
3772
|
-
var
|
|
3773
|
-
var
|
|
3774
|
-
var
|
|
3775
|
-
var
|
|
3941
|
+
var duckduckgoSearchSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[10]);
|
|
3942
|
+
var fetchPageMainContentSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[11]);
|
|
3943
|
+
var yahooFinanceQuoteSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[12]);
|
|
3944
|
+
var jsonSelectSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[13]);
|
|
3945
|
+
var truncateSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[14]);
|
|
3946
|
+
var hashTextSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[15]);
|
|
3947
|
+
var nowSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[16]);
|
|
3948
|
+
var templateRenderSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[17]);
|
|
3949
|
+
var runCommandSpec = (0, import_core.createToolSpec)(CORE_TOOL_MANIFEST[18]);
|
|
3776
3950
|
var CORE_GROUP_PREFIX = {
|
|
3777
3951
|
fs: "core/fs.",
|
|
3778
3952
|
http: "core/http.",
|
|
@@ -3827,7 +4001,8 @@ function registerCoreTools(registry, userConfig, options) {
|
|
|
3827
4001
|
templateRenderSpec,
|
|
3828
4002
|
truncateSpec,
|
|
3829
4003
|
validateUrl,
|
|
3830
|
-
writeTextSpec
|
|
4004
|
+
writeTextSpec,
|
|
4005
|
+
yahooFinanceQuoteSpec
|
|
3831
4006
|
});
|
|
3832
4007
|
/*! Bundled license information:
|
|
3833
4008
|
|