@everworker/oneringai 0.2.2 → 0.2.3
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 +63 -17
- package/dist/index.cjs +1022 -129
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +461 -4
- package/dist/index.d.ts +461 -4
- package/dist/index.js +946 -70
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var crypto2 = require('crypto');
|
|
4
4
|
var jose = require('jose');
|
|
5
|
-
var
|
|
5
|
+
var fs17 = require('fs');
|
|
6
6
|
var eventemitter3 = require('eventemitter3');
|
|
7
7
|
var path2 = require('path');
|
|
8
8
|
var TurndownService = require('turndown');
|
|
@@ -17,7 +17,7 @@ var z = require('zod/v4');
|
|
|
17
17
|
var spawn = require('cross-spawn');
|
|
18
18
|
var process2 = require('process');
|
|
19
19
|
var stream = require('stream');
|
|
20
|
-
var
|
|
20
|
+
var fs16 = require('fs/promises');
|
|
21
21
|
var simpleIcons = require('simple-icons');
|
|
22
22
|
var child_process = require('child_process');
|
|
23
23
|
var util = require('util');
|
|
@@ -45,7 +45,7 @@ function _interopNamespace(e) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
var crypto2__namespace = /*#__PURE__*/_interopNamespace(crypto2);
|
|
48
|
-
var
|
|
48
|
+
var fs17__namespace = /*#__PURE__*/_interopNamespace(fs17);
|
|
49
49
|
var path2__namespace = /*#__PURE__*/_interopNamespace(path2);
|
|
50
50
|
var TurndownService__default = /*#__PURE__*/_interopDefault(TurndownService);
|
|
51
51
|
var os2__namespace = /*#__PURE__*/_interopNamespace(os2);
|
|
@@ -55,7 +55,7 @@ var z4mini__namespace = /*#__PURE__*/_interopNamespace(z4mini);
|
|
|
55
55
|
var z__namespace = /*#__PURE__*/_interopNamespace(z);
|
|
56
56
|
var spawn__default = /*#__PURE__*/_interopDefault(spawn);
|
|
57
57
|
var process2__default = /*#__PURE__*/_interopDefault(process2);
|
|
58
|
-
var
|
|
58
|
+
var fs16__namespace = /*#__PURE__*/_interopNamespace(fs16);
|
|
59
59
|
var simpleIcons__namespace = /*#__PURE__*/_interopNamespace(simpleIcons);
|
|
60
60
|
var vm__namespace = /*#__PURE__*/_interopNamespace(vm);
|
|
61
61
|
|
|
@@ -673,7 +673,7 @@ var init_JWTBearer = __esm({
|
|
|
673
673
|
this.privateKey = config.privateKey;
|
|
674
674
|
} else if (config.privateKeyPath) {
|
|
675
675
|
try {
|
|
676
|
-
this.privateKey =
|
|
676
|
+
this.privateKey = fs17__namespace.readFileSync(config.privateKeyPath, "utf8");
|
|
677
677
|
} catch (error) {
|
|
678
678
|
throw new Error(`Failed to read private key from ${config.privateKeyPath}: ${error.message}`);
|
|
679
679
|
}
|
|
@@ -1324,10 +1324,10 @@ var init_Logger = __esm({
|
|
|
1324
1324
|
initFileStream(filePath) {
|
|
1325
1325
|
try {
|
|
1326
1326
|
const dir = path2__namespace.dirname(filePath);
|
|
1327
|
-
if (!
|
|
1328
|
-
|
|
1327
|
+
if (!fs17__namespace.existsSync(dir)) {
|
|
1328
|
+
fs17__namespace.mkdirSync(dir, { recursive: true });
|
|
1329
1329
|
}
|
|
1330
|
-
this.fileStream =
|
|
1330
|
+
this.fileStream = fs17__namespace.createWriteStream(filePath, {
|
|
1331
1331
|
flags: "a",
|
|
1332
1332
|
// append mode
|
|
1333
1333
|
encoding: "utf8"
|
|
@@ -14664,12 +14664,12 @@ var require_dist = __commonJS({
|
|
|
14664
14664
|
throw new Error(`Unknown format "${name}"`);
|
|
14665
14665
|
return f;
|
|
14666
14666
|
};
|
|
14667
|
-
function addFormats(ajv, list,
|
|
14667
|
+
function addFormats(ajv, list, fs18, exportName) {
|
|
14668
14668
|
var _a;
|
|
14669
14669
|
var _b;
|
|
14670
14670
|
(_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
14671
14671
|
for (const f of list)
|
|
14672
|
-
ajv.addFormat(f,
|
|
14672
|
+
ajv.addFormat(f, fs18[f]);
|
|
14673
14673
|
}
|
|
14674
14674
|
module.exports = exports$1 = formatsPlugin;
|
|
14675
14675
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
@@ -16723,6 +16723,9 @@ var ToolManager = class extends eventemitter3.EventEmitter {
|
|
|
16723
16723
|
if (options.priority !== void 0) existing.priority = options.priority;
|
|
16724
16724
|
if (options.conditions !== void 0) existing.conditions = options.conditions;
|
|
16725
16725
|
if (options.permission !== void 0) existing.permission = options.permission;
|
|
16726
|
+
if (options.tags !== void 0) existing.tags = options.tags;
|
|
16727
|
+
if (options.category !== void 0) existing.category = options.category;
|
|
16728
|
+
if (options.source !== void 0) existing.source = options.source;
|
|
16726
16729
|
return;
|
|
16727
16730
|
}
|
|
16728
16731
|
const namespace = options.namespace ?? "default";
|
|
@@ -16741,7 +16744,10 @@ var ToolManager = class extends eventemitter3.EventEmitter {
|
|
|
16741
16744
|
successCount: 0,
|
|
16742
16745
|
failureCount: 0
|
|
16743
16746
|
},
|
|
16744
|
-
permission: effectivePermission
|
|
16747
|
+
permission: effectivePermission,
|
|
16748
|
+
tags: options.tags,
|
|
16749
|
+
category: options.category,
|
|
16750
|
+
source: options.source
|
|
16745
16751
|
};
|
|
16746
16752
|
this.registry.set(name, registration);
|
|
16747
16753
|
this.addToNamespace(name, namespace);
|
|
@@ -17324,6 +17330,9 @@ var ToolManager = class extends eventemitter3.EventEmitter {
|
|
|
17324
17330
|
const namespaces = {};
|
|
17325
17331
|
const priorities = {};
|
|
17326
17332
|
const permissions = {};
|
|
17333
|
+
const tags = {};
|
|
17334
|
+
const categories = {};
|
|
17335
|
+
const sources = {};
|
|
17327
17336
|
for (const [name, reg] of this.registry) {
|
|
17328
17337
|
enabled[name] = reg.enabled;
|
|
17329
17338
|
namespaces[name] = reg.namespace;
|
|
@@ -17331,8 +17340,17 @@ var ToolManager = class extends eventemitter3.EventEmitter {
|
|
|
17331
17340
|
if (reg.permission) {
|
|
17332
17341
|
permissions[name] = reg.permission;
|
|
17333
17342
|
}
|
|
17343
|
+
if (reg.tags) {
|
|
17344
|
+
tags[name] = reg.tags;
|
|
17345
|
+
}
|
|
17346
|
+
if (reg.category) {
|
|
17347
|
+
categories[name] = reg.category;
|
|
17348
|
+
}
|
|
17349
|
+
if (reg.source) {
|
|
17350
|
+
sources[name] = reg.source;
|
|
17351
|
+
}
|
|
17334
17352
|
}
|
|
17335
|
-
return { enabled, namespaces, priorities, permissions };
|
|
17353
|
+
return { enabled, namespaces, priorities, permissions, tags, categories, sources };
|
|
17336
17354
|
}
|
|
17337
17355
|
/**
|
|
17338
17356
|
* Load state (restores enabled/disabled, namespaces, priorities, permissions)
|
|
@@ -17356,6 +17374,24 @@ var ToolManager = class extends eventemitter3.EventEmitter {
|
|
|
17356
17374
|
this.setPermission(name, permission);
|
|
17357
17375
|
}
|
|
17358
17376
|
}
|
|
17377
|
+
if (state.tags) {
|
|
17378
|
+
for (const [name, toolTags] of Object.entries(state.tags)) {
|
|
17379
|
+
const reg = this.registry.get(name);
|
|
17380
|
+
if (reg) reg.tags = toolTags;
|
|
17381
|
+
}
|
|
17382
|
+
}
|
|
17383
|
+
if (state.categories) {
|
|
17384
|
+
for (const [name, category] of Object.entries(state.categories)) {
|
|
17385
|
+
const reg = this.registry.get(name);
|
|
17386
|
+
if (reg) reg.category = category;
|
|
17387
|
+
}
|
|
17388
|
+
}
|
|
17389
|
+
if (state.sources) {
|
|
17390
|
+
for (const [name, source] of Object.entries(state.sources)) {
|
|
17391
|
+
const reg = this.registry.get(name);
|
|
17392
|
+
if (reg) reg.source = source;
|
|
17393
|
+
}
|
|
17394
|
+
}
|
|
17359
17395
|
}
|
|
17360
17396
|
// ==========================================================================
|
|
17361
17397
|
// Private Helpers
|
|
@@ -20357,7 +20393,7 @@ var FilePersistentInstructionsStorage = class {
|
|
|
20357
20393
|
*/
|
|
20358
20394
|
async load() {
|
|
20359
20395
|
try {
|
|
20360
|
-
const raw = await
|
|
20396
|
+
const raw = await fs17.promises.readFile(this.filePath, "utf-8");
|
|
20361
20397
|
const data = JSON.parse(raw);
|
|
20362
20398
|
if (data.version === 2 && Array.isArray(data.entries)) {
|
|
20363
20399
|
return data.entries.length > 0 ? data.entries : null;
|
|
@@ -20369,7 +20405,7 @@ var FilePersistentInstructionsStorage = class {
|
|
|
20369
20405
|
}
|
|
20370
20406
|
}
|
|
20371
20407
|
try {
|
|
20372
|
-
const content = await
|
|
20408
|
+
const content = await fs17.promises.readFile(this.legacyFilePath, "utf-8");
|
|
20373
20409
|
const trimmed = content.trim();
|
|
20374
20410
|
if (!trimmed) return null;
|
|
20375
20411
|
const now = Date.now();
|
|
@@ -20399,11 +20435,11 @@ var FilePersistentInstructionsStorage = class {
|
|
|
20399
20435
|
};
|
|
20400
20436
|
const tempPath = `${this.filePath}.tmp`;
|
|
20401
20437
|
try {
|
|
20402
|
-
await
|
|
20403
|
-
await
|
|
20438
|
+
await fs17.promises.writeFile(tempPath, JSON.stringify(data, null, 2), "utf-8");
|
|
20439
|
+
await fs17.promises.rename(tempPath, this.filePath);
|
|
20404
20440
|
} catch (error) {
|
|
20405
20441
|
try {
|
|
20406
|
-
await
|
|
20442
|
+
await fs17.promises.unlink(tempPath);
|
|
20407
20443
|
} catch {
|
|
20408
20444
|
}
|
|
20409
20445
|
throw error;
|
|
@@ -20415,7 +20451,7 @@ var FilePersistentInstructionsStorage = class {
|
|
|
20415
20451
|
*/
|
|
20416
20452
|
async delete() {
|
|
20417
20453
|
try {
|
|
20418
|
-
await
|
|
20454
|
+
await fs17.promises.unlink(this.filePath);
|
|
20419
20455
|
} catch (error) {
|
|
20420
20456
|
if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
|
|
20421
20457
|
throw error;
|
|
@@ -20428,11 +20464,11 @@ var FilePersistentInstructionsStorage = class {
|
|
|
20428
20464
|
*/
|
|
20429
20465
|
async exists() {
|
|
20430
20466
|
try {
|
|
20431
|
-
await
|
|
20467
|
+
await fs17.promises.access(this.filePath);
|
|
20432
20468
|
return true;
|
|
20433
20469
|
} catch {
|
|
20434
20470
|
try {
|
|
20435
|
-
await
|
|
20471
|
+
await fs17.promises.access(this.legacyFilePath);
|
|
20436
20472
|
return true;
|
|
20437
20473
|
} catch {
|
|
20438
20474
|
return false;
|
|
@@ -20456,7 +20492,7 @@ var FilePersistentInstructionsStorage = class {
|
|
|
20456
20492
|
*/
|
|
20457
20493
|
async ensureDirectory() {
|
|
20458
20494
|
try {
|
|
20459
|
-
await
|
|
20495
|
+
await fs17.promises.mkdir(this.directory, { recursive: true });
|
|
20460
20496
|
} catch (error) {
|
|
20461
20497
|
if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
|
|
20462
20498
|
throw error;
|
|
@@ -20468,7 +20504,7 @@ var FilePersistentInstructionsStorage = class {
|
|
|
20468
20504
|
*/
|
|
20469
20505
|
async removeLegacyFile() {
|
|
20470
20506
|
try {
|
|
20471
|
-
await
|
|
20507
|
+
await fs17.promises.unlink(this.legacyFilePath);
|
|
20472
20508
|
} catch (error) {
|
|
20473
20509
|
if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
|
|
20474
20510
|
console.warn(`Failed to remove legacy instructions file: ${this.legacyFilePath}`);
|
|
@@ -28328,7 +28364,7 @@ init_constants();
|
|
|
28328
28364
|
throw new Error("Configuration file not found. Searched: " + this.DEFAULT_PATHS.join(", "));
|
|
28329
28365
|
}
|
|
28330
28366
|
try {
|
|
28331
|
-
const content = await
|
|
28367
|
+
const content = await fs17.promises.readFile(configPath, "utf-8");
|
|
28332
28368
|
let config = JSON.parse(content);
|
|
28333
28369
|
config = this.interpolateEnvVars(config);
|
|
28334
28370
|
this.validate(config);
|
|
@@ -28349,8 +28385,8 @@ init_constants();
|
|
|
28349
28385
|
throw new Error("Configuration file not found. Searched: " + this.DEFAULT_PATHS.join(", "));
|
|
28350
28386
|
}
|
|
28351
28387
|
try {
|
|
28352
|
-
const
|
|
28353
|
-
const content =
|
|
28388
|
+
const fs18 = __require("fs");
|
|
28389
|
+
const content = fs18.readFileSync(configPath, "utf-8");
|
|
28354
28390
|
let config = JSON.parse(content);
|
|
28355
28391
|
config = this.interpolateEnvVars(config);
|
|
28356
28392
|
this.validate(config);
|
|
@@ -28368,7 +28404,7 @@ init_constants();
|
|
|
28368
28404
|
static async findConfig() {
|
|
28369
28405
|
for (const path6 of this.DEFAULT_PATHS) {
|
|
28370
28406
|
try {
|
|
28371
|
-
await
|
|
28407
|
+
await fs17.promises.access(path2.resolve(path6));
|
|
28372
28408
|
return path2.resolve(path6);
|
|
28373
28409
|
} catch {
|
|
28374
28410
|
}
|
|
@@ -28379,10 +28415,10 @@ init_constants();
|
|
|
28379
28415
|
* Find configuration file synchronously
|
|
28380
28416
|
*/
|
|
28381
28417
|
static findConfigSync() {
|
|
28382
|
-
const
|
|
28418
|
+
const fs18 = __require("fs");
|
|
28383
28419
|
for (const path6 of this.DEFAULT_PATHS) {
|
|
28384
28420
|
try {
|
|
28385
|
-
|
|
28421
|
+
fs18.accessSync(path2.resolve(path6));
|
|
28386
28422
|
return path2.resolve(path6);
|
|
28387
28423
|
} catch {
|
|
28388
28424
|
}
|
|
@@ -33938,7 +33974,7 @@ var MCPRegistry = class {
|
|
|
33938
33974
|
static async loadFromConfigFile(path6) {
|
|
33939
33975
|
try {
|
|
33940
33976
|
const configPath = path2.resolve(path6);
|
|
33941
|
-
const content = await
|
|
33977
|
+
const content = await fs17.promises.readFile(configPath, "utf-8");
|
|
33942
33978
|
const config = JSON.parse(content);
|
|
33943
33979
|
if (!config.mcp) {
|
|
33944
33980
|
throw new MCPError("Configuration file does not contain MCP section");
|
|
@@ -34543,7 +34579,7 @@ var OpenAISTTProvider = class extends BaseMediaProvider {
|
|
|
34543
34579
|
if (Buffer.isBuffer(audio)) {
|
|
34544
34580
|
return new File([new Uint8Array(audio)], "audio.wav", { type: "audio/wav" });
|
|
34545
34581
|
} else if (typeof audio === "string") {
|
|
34546
|
-
return
|
|
34582
|
+
return fs17__namespace.createReadStream(audio);
|
|
34547
34583
|
} else {
|
|
34548
34584
|
throw new Error("Invalid audio input: must be Buffer or file path");
|
|
34549
34585
|
}
|
|
@@ -35096,7 +35132,7 @@ var TextToSpeech = class _TextToSpeech {
|
|
|
35096
35132
|
*/
|
|
35097
35133
|
async toFile(text, filePath, options) {
|
|
35098
35134
|
const response = await this.synthesize(text, options);
|
|
35099
|
-
await
|
|
35135
|
+
await fs16__namespace.writeFile(filePath, response.audio);
|
|
35100
35136
|
}
|
|
35101
35137
|
// ======================== Introspection Methods ========================
|
|
35102
35138
|
/**
|
|
@@ -35444,7 +35480,7 @@ var SpeechToText = class _SpeechToText {
|
|
|
35444
35480
|
* @param options - Optional transcription parameters
|
|
35445
35481
|
*/
|
|
35446
35482
|
async transcribeFile(filePath, options) {
|
|
35447
|
-
const audio = await
|
|
35483
|
+
const audio = await fs16__namespace.readFile(filePath);
|
|
35448
35484
|
return this.transcribe(audio, options);
|
|
35449
35485
|
}
|
|
35450
35486
|
/**
|
|
@@ -35770,7 +35806,7 @@ var OpenAIImageProvider = class extends BaseMediaProvider {
|
|
|
35770
35806
|
if (Buffer.isBuffer(image)) {
|
|
35771
35807
|
return new File([new Uint8Array(image)], "image.png", { type: "image/png" });
|
|
35772
35808
|
}
|
|
35773
|
-
return
|
|
35809
|
+
return fs17__namespace.createReadStream(image);
|
|
35774
35810
|
}
|
|
35775
35811
|
/**
|
|
35776
35812
|
* Handle OpenAI API errors
|
|
@@ -35917,8 +35953,8 @@ var GoogleImageProvider = class extends BaseMediaProvider {
|
|
|
35917
35953
|
if (Buffer.isBuffer(image)) {
|
|
35918
35954
|
imageBytes = image.toString("base64");
|
|
35919
35955
|
} else {
|
|
35920
|
-
const
|
|
35921
|
-
const buffer =
|
|
35956
|
+
const fs18 = await import('fs');
|
|
35957
|
+
const buffer = fs18.readFileSync(image);
|
|
35922
35958
|
imageBytes = buffer.toString("base64");
|
|
35923
35959
|
}
|
|
35924
35960
|
return {
|
|
@@ -36079,7 +36115,7 @@ var GrokImageProvider = class extends BaseMediaProvider {
|
|
|
36079
36115
|
if (Buffer.isBuffer(image)) {
|
|
36080
36116
|
return new File([new Uint8Array(image)], "image.png", { type: "image/png" });
|
|
36081
36117
|
}
|
|
36082
|
-
return
|
|
36118
|
+
return fs17__namespace.createReadStream(image);
|
|
36083
36119
|
}
|
|
36084
36120
|
/**
|
|
36085
36121
|
* Handle API errors
|
|
@@ -37529,8 +37565,8 @@ var OpenAISoraProvider = class extends BaseMediaProvider {
|
|
|
37529
37565
|
return new File([new Uint8Array(image)], "input.png", { type: "image/png" });
|
|
37530
37566
|
}
|
|
37531
37567
|
if (!image.startsWith("http")) {
|
|
37532
|
-
const
|
|
37533
|
-
const data =
|
|
37568
|
+
const fs18 = await import('fs');
|
|
37569
|
+
const data = fs18.readFileSync(image);
|
|
37534
37570
|
return new File([new Uint8Array(data)], "input.png", { type: "image/png" });
|
|
37535
37571
|
}
|
|
37536
37572
|
const response = await fetch(image);
|
|
@@ -37708,7 +37744,7 @@ var GoogleVeoProvider = class extends BaseMediaProvider {
|
|
|
37708
37744
|
if (video.videoBytes) {
|
|
37709
37745
|
buffer = Buffer.from(video.videoBytes, "base64");
|
|
37710
37746
|
} else if (video.uri) {
|
|
37711
|
-
const
|
|
37747
|
+
const fs18 = await import('fs/promises');
|
|
37712
37748
|
const os3 = await import('os');
|
|
37713
37749
|
const path6 = await import('path');
|
|
37714
37750
|
const tempDir = os3.tmpdir();
|
|
@@ -37719,11 +37755,11 @@ var GoogleVeoProvider = class extends BaseMediaProvider {
|
|
|
37719
37755
|
// Pass as GeneratedVideo
|
|
37720
37756
|
downloadPath: tempFile
|
|
37721
37757
|
});
|
|
37722
|
-
buffer = await
|
|
37723
|
-
await
|
|
37758
|
+
buffer = await fs18.readFile(tempFile);
|
|
37759
|
+
await fs18.unlink(tempFile).catch(() => {
|
|
37724
37760
|
});
|
|
37725
37761
|
} catch (downloadError) {
|
|
37726
|
-
await
|
|
37762
|
+
await fs18.unlink(tempFile).catch(() => {
|
|
37727
37763
|
});
|
|
37728
37764
|
throw new ProviderError(
|
|
37729
37765
|
"google",
|
|
@@ -37845,8 +37881,8 @@ var GoogleVeoProvider = class extends BaseMediaProvider {
|
|
|
37845
37881
|
if (image.startsWith("http://") || image.startsWith("https://")) {
|
|
37846
37882
|
return { imageUri: image };
|
|
37847
37883
|
}
|
|
37848
|
-
const
|
|
37849
|
-
const data = await
|
|
37884
|
+
const fs18 = await import('fs/promises');
|
|
37885
|
+
const data = await fs18.readFile(image);
|
|
37850
37886
|
return {
|
|
37851
37887
|
imageBytes: data.toString("base64")
|
|
37852
37888
|
};
|
|
@@ -38153,8 +38189,8 @@ var GrokImagineProvider = class extends BaseMediaProvider {
|
|
|
38153
38189
|
if (image.startsWith("http") || image.startsWith("data:")) {
|
|
38154
38190
|
return image;
|
|
38155
38191
|
}
|
|
38156
|
-
const
|
|
38157
|
-
const data =
|
|
38192
|
+
const fs18 = await import('fs');
|
|
38193
|
+
const data = fs18.readFileSync(image);
|
|
38158
38194
|
const base64 = data.toString("base64");
|
|
38159
38195
|
const ext = image.split(".").pop()?.toLowerCase() || "png";
|
|
38160
38196
|
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext}`;
|
|
@@ -39590,7 +39626,7 @@ var DocumentReader = class _DocumentReader {
|
|
|
39590
39626
|
async resolveSource(source) {
|
|
39591
39627
|
switch (source.type) {
|
|
39592
39628
|
case "file": {
|
|
39593
|
-
const buffer = await
|
|
39629
|
+
const buffer = await fs16.readFile(source.path);
|
|
39594
39630
|
const filename = source.path.split("/").pop() || source.path;
|
|
39595
39631
|
return { buffer, filename };
|
|
39596
39632
|
}
|
|
@@ -41909,11 +41945,11 @@ var FileContextStorage = class {
|
|
|
41909
41945
|
const data = this.prettyPrint ? JSON.stringify(storedSession, null, 2) : JSON.stringify(storedSession);
|
|
41910
41946
|
const tempPath = `${filePath}.tmp`;
|
|
41911
41947
|
try {
|
|
41912
|
-
await
|
|
41913
|
-
await
|
|
41948
|
+
await fs17.promises.writeFile(tempPath, data, "utf-8");
|
|
41949
|
+
await fs17.promises.rename(tempPath, filePath);
|
|
41914
41950
|
} catch (error) {
|
|
41915
41951
|
try {
|
|
41916
|
-
await
|
|
41952
|
+
await fs17.promises.unlink(tempPath);
|
|
41917
41953
|
} catch {
|
|
41918
41954
|
}
|
|
41919
41955
|
throw error;
|
|
@@ -41934,7 +41970,7 @@ var FileContextStorage = class {
|
|
|
41934
41970
|
const sanitizedSessionId = sanitizeId(sessionId);
|
|
41935
41971
|
const filePath = this.getFilePath(sanitizedSessionId);
|
|
41936
41972
|
try {
|
|
41937
|
-
await
|
|
41973
|
+
await fs17.promises.unlink(filePath);
|
|
41938
41974
|
} catch (error) {
|
|
41939
41975
|
if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
|
|
41940
41976
|
throw error;
|
|
@@ -41949,7 +41985,7 @@ var FileContextStorage = class {
|
|
|
41949
41985
|
const sanitizedSessionId = sanitizeId(sessionId);
|
|
41950
41986
|
const filePath = this.getFilePath(sanitizedSessionId);
|
|
41951
41987
|
try {
|
|
41952
|
-
await
|
|
41988
|
+
await fs17.promises.access(filePath);
|
|
41953
41989
|
return true;
|
|
41954
41990
|
} catch {
|
|
41955
41991
|
return false;
|
|
@@ -42014,7 +42050,7 @@ var FileContextStorage = class {
|
|
|
42014
42050
|
const sanitizedSessionId = sanitizeId(sessionId);
|
|
42015
42051
|
const filePath = this.getFilePath(sanitizedSessionId);
|
|
42016
42052
|
const data = this.prettyPrint ? JSON.stringify(stored, null, 2) : JSON.stringify(stored);
|
|
42017
|
-
await
|
|
42053
|
+
await fs17.promises.writeFile(filePath, data, "utf-8");
|
|
42018
42054
|
await this.updateIndex(stored);
|
|
42019
42055
|
}
|
|
42020
42056
|
/**
|
|
@@ -42042,13 +42078,13 @@ var FileContextStorage = class {
|
|
|
42042
42078
|
*/
|
|
42043
42079
|
async rebuildIndex() {
|
|
42044
42080
|
await this.ensureDirectory();
|
|
42045
|
-
const files = await
|
|
42081
|
+
const files = await fs17.promises.readdir(this.sessionsDirectory);
|
|
42046
42082
|
const sessionFiles = files.filter((f) => f.endsWith(".json") && !f.startsWith("_"));
|
|
42047
42083
|
const entries = [];
|
|
42048
42084
|
for (const file of sessionFiles) {
|
|
42049
42085
|
try {
|
|
42050
42086
|
const filePath = path2.join(this.sessionsDirectory, file);
|
|
42051
|
-
const data = await
|
|
42087
|
+
const data = await fs17.promises.readFile(filePath, "utf-8");
|
|
42052
42088
|
const stored = JSON.parse(data);
|
|
42053
42089
|
entries.push(this.storedToIndexEntry(stored));
|
|
42054
42090
|
} catch {
|
|
@@ -42070,7 +42106,7 @@ var FileContextStorage = class {
|
|
|
42070
42106
|
}
|
|
42071
42107
|
async ensureDirectory() {
|
|
42072
42108
|
try {
|
|
42073
|
-
await
|
|
42109
|
+
await fs17.promises.mkdir(this.sessionsDirectory, { recursive: true });
|
|
42074
42110
|
} catch (error) {
|
|
42075
42111
|
if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
|
|
42076
42112
|
throw error;
|
|
@@ -42080,7 +42116,7 @@ var FileContextStorage = class {
|
|
|
42080
42116
|
async loadRaw(sanitizedSessionId) {
|
|
42081
42117
|
const filePath = this.getFilePath(sanitizedSessionId);
|
|
42082
42118
|
try {
|
|
42083
|
-
const data = await
|
|
42119
|
+
const data = await fs17.promises.readFile(filePath, "utf-8");
|
|
42084
42120
|
return JSON.parse(data);
|
|
42085
42121
|
} catch (error) {
|
|
42086
42122
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -42098,7 +42134,7 @@ var FileContextStorage = class {
|
|
|
42098
42134
|
return this.index;
|
|
42099
42135
|
}
|
|
42100
42136
|
try {
|
|
42101
|
-
const data = await
|
|
42137
|
+
const data = await fs17.promises.readFile(this.indexPath, "utf-8");
|
|
42102
42138
|
this.index = JSON.parse(data);
|
|
42103
42139
|
return this.index;
|
|
42104
42140
|
} catch (error) {
|
|
@@ -42119,7 +42155,7 @@ var FileContextStorage = class {
|
|
|
42119
42155
|
await this.ensureDirectory();
|
|
42120
42156
|
this.index.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
42121
42157
|
const data = this.prettyPrint ? JSON.stringify(this.index, null, 2) : JSON.stringify(this.index);
|
|
42122
|
-
await
|
|
42158
|
+
await fs17.promises.writeFile(this.indexPath, data, "utf-8");
|
|
42123
42159
|
}
|
|
42124
42160
|
async updateIndex(stored) {
|
|
42125
42161
|
const index = await this.loadIndex();
|
|
@@ -42193,11 +42229,11 @@ var FileAgentDefinitionStorage = class {
|
|
|
42193
42229
|
const data = this.prettyPrint ? JSON.stringify(definition, null, 2) : JSON.stringify(definition);
|
|
42194
42230
|
const tempPath = `${filePath}.tmp`;
|
|
42195
42231
|
try {
|
|
42196
|
-
await
|
|
42197
|
-
await
|
|
42232
|
+
await fs17.promises.writeFile(tempPath, data, "utf-8");
|
|
42233
|
+
await fs17.promises.rename(tempPath, filePath);
|
|
42198
42234
|
} catch (error) {
|
|
42199
42235
|
try {
|
|
42200
|
-
await
|
|
42236
|
+
await fs17.promises.unlink(tempPath);
|
|
42201
42237
|
} catch {
|
|
42202
42238
|
}
|
|
42203
42239
|
throw error;
|
|
@@ -42219,7 +42255,7 @@ var FileAgentDefinitionStorage = class {
|
|
|
42219
42255
|
const agentDir = path2.join(this.baseDirectory, sanitizedId);
|
|
42220
42256
|
const filePath = path2.join(agentDir, "definition.json");
|
|
42221
42257
|
try {
|
|
42222
|
-
await
|
|
42258
|
+
await fs17.promises.unlink(filePath);
|
|
42223
42259
|
} catch (error) {
|
|
42224
42260
|
if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
|
|
42225
42261
|
throw error;
|
|
@@ -42234,7 +42270,7 @@ var FileAgentDefinitionStorage = class {
|
|
|
42234
42270
|
const sanitizedId = sanitizeAgentId2(agentId);
|
|
42235
42271
|
const filePath = path2.join(this.baseDirectory, sanitizedId, "definition.json");
|
|
42236
42272
|
try {
|
|
42237
|
-
await
|
|
42273
|
+
await fs17.promises.access(filePath);
|
|
42238
42274
|
return true;
|
|
42239
42275
|
} catch {
|
|
42240
42276
|
return false;
|
|
@@ -42296,13 +42332,13 @@ var FileAgentDefinitionStorage = class {
|
|
|
42296
42332
|
*/
|
|
42297
42333
|
async rebuildIndex() {
|
|
42298
42334
|
await this.ensureDirectory(this.baseDirectory);
|
|
42299
|
-
const entries = await
|
|
42335
|
+
const entries = await fs17.promises.readdir(this.baseDirectory, { withFileTypes: true });
|
|
42300
42336
|
const agentDirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith("_"));
|
|
42301
42337
|
const indexEntries = [];
|
|
42302
42338
|
for (const dir of agentDirs) {
|
|
42303
42339
|
try {
|
|
42304
42340
|
const filePath = path2.join(this.baseDirectory, dir.name, "definition.json");
|
|
42305
|
-
const data = await
|
|
42341
|
+
const data = await fs17.promises.readFile(filePath, "utf-8");
|
|
42306
42342
|
const definition = JSON.parse(data);
|
|
42307
42343
|
indexEntries.push(this.definitionToIndexEntry(definition));
|
|
42308
42344
|
} catch {
|
|
@@ -42320,7 +42356,7 @@ var FileAgentDefinitionStorage = class {
|
|
|
42320
42356
|
// ==========================================================================
|
|
42321
42357
|
async ensureDirectory(dir) {
|
|
42322
42358
|
try {
|
|
42323
|
-
await
|
|
42359
|
+
await fs17.promises.mkdir(dir, { recursive: true });
|
|
42324
42360
|
} catch (error) {
|
|
42325
42361
|
if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
|
|
42326
42362
|
throw error;
|
|
@@ -42330,7 +42366,7 @@ var FileAgentDefinitionStorage = class {
|
|
|
42330
42366
|
async loadRaw(sanitizedId) {
|
|
42331
42367
|
const filePath = path2.join(this.baseDirectory, sanitizedId, "definition.json");
|
|
42332
42368
|
try {
|
|
42333
|
-
const data = await
|
|
42369
|
+
const data = await fs17.promises.readFile(filePath, "utf-8");
|
|
42334
42370
|
return JSON.parse(data);
|
|
42335
42371
|
} catch (error) {
|
|
42336
42372
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -42348,7 +42384,7 @@ var FileAgentDefinitionStorage = class {
|
|
|
42348
42384
|
return this.index;
|
|
42349
42385
|
}
|
|
42350
42386
|
try {
|
|
42351
|
-
const data = await
|
|
42387
|
+
const data = await fs17.promises.readFile(this.indexPath, "utf-8");
|
|
42352
42388
|
this.index = JSON.parse(data);
|
|
42353
42389
|
return this.index;
|
|
42354
42390
|
} catch (error) {
|
|
@@ -42368,7 +42404,7 @@ var FileAgentDefinitionStorage = class {
|
|
|
42368
42404
|
await this.ensureDirectory(this.baseDirectory);
|
|
42369
42405
|
this.index.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
42370
42406
|
const data = this.prettyPrint ? JSON.stringify(this.index, null, 2) : JSON.stringify(this.index);
|
|
42371
|
-
await
|
|
42407
|
+
await fs17.promises.writeFile(this.indexPath, data, "utf-8");
|
|
42372
42408
|
}
|
|
42373
42409
|
async updateIndex(definition) {
|
|
42374
42410
|
const index = await this.loadIndex();
|
|
@@ -42426,10 +42462,10 @@ var FileMediaStorage = class {
|
|
|
42426
42462
|
}
|
|
42427
42463
|
async save(data, metadata) {
|
|
42428
42464
|
const dir = metadata.userId ? path2__namespace.join(this.outputDir, metadata.userId) : this.outputDir;
|
|
42429
|
-
await
|
|
42465
|
+
await fs16__namespace.mkdir(dir, { recursive: true });
|
|
42430
42466
|
const filename = metadata.suggestedFilename ?? this.generateFilename(metadata);
|
|
42431
42467
|
const filePath = path2__namespace.join(dir, filename);
|
|
42432
|
-
await
|
|
42468
|
+
await fs16__namespace.writeFile(filePath, data);
|
|
42433
42469
|
const format = metadata.format.toLowerCase();
|
|
42434
42470
|
const mimeType = MIME_TYPES2[format] ?? "application/octet-stream";
|
|
42435
42471
|
return {
|
|
@@ -42440,7 +42476,7 @@ var FileMediaStorage = class {
|
|
|
42440
42476
|
}
|
|
42441
42477
|
async read(location) {
|
|
42442
42478
|
try {
|
|
42443
|
-
return await
|
|
42479
|
+
return await fs16__namespace.readFile(location);
|
|
42444
42480
|
} catch (err) {
|
|
42445
42481
|
if (err.code === "ENOENT") {
|
|
42446
42482
|
return null;
|
|
@@ -42450,7 +42486,7 @@ var FileMediaStorage = class {
|
|
|
42450
42486
|
}
|
|
42451
42487
|
async delete(location) {
|
|
42452
42488
|
try {
|
|
42453
|
-
await
|
|
42489
|
+
await fs16__namespace.unlink(location);
|
|
42454
42490
|
} catch (err) {
|
|
42455
42491
|
if (err.code === "ENOENT") {
|
|
42456
42492
|
return;
|
|
@@ -42460,7 +42496,7 @@ var FileMediaStorage = class {
|
|
|
42460
42496
|
}
|
|
42461
42497
|
async exists(location) {
|
|
42462
42498
|
try {
|
|
42463
|
-
await
|
|
42499
|
+
await fs16__namespace.access(location);
|
|
42464
42500
|
return true;
|
|
42465
42501
|
} catch {
|
|
42466
42502
|
return false;
|
|
@@ -42469,11 +42505,11 @@ var FileMediaStorage = class {
|
|
|
42469
42505
|
async list(options) {
|
|
42470
42506
|
await this.ensureDir();
|
|
42471
42507
|
let entries = [];
|
|
42472
|
-
const files = await
|
|
42508
|
+
const files = await fs16__namespace.readdir(this.outputDir);
|
|
42473
42509
|
for (const file of files) {
|
|
42474
42510
|
const filePath = path2__namespace.join(this.outputDir, file);
|
|
42475
42511
|
try {
|
|
42476
|
-
const stat6 = await
|
|
42512
|
+
const stat6 = await fs16__namespace.stat(filePath);
|
|
42477
42513
|
if (!stat6.isFile()) continue;
|
|
42478
42514
|
const ext = path2__namespace.extname(file).slice(1).toLowerCase();
|
|
42479
42515
|
const mimeType = MIME_TYPES2[ext] ?? "application/octet-stream";
|
|
@@ -42513,7 +42549,7 @@ var FileMediaStorage = class {
|
|
|
42513
42549
|
}
|
|
42514
42550
|
async ensureDir() {
|
|
42515
42551
|
if (!this.initialized) {
|
|
42516
|
-
await
|
|
42552
|
+
await fs16__namespace.mkdir(this.outputDir, { recursive: true });
|
|
42517
42553
|
this.initialized = true;
|
|
42518
42554
|
}
|
|
42519
42555
|
}
|
|
@@ -42521,6 +42557,230 @@ var FileMediaStorage = class {
|
|
|
42521
42557
|
function createFileMediaStorage(config) {
|
|
42522
42558
|
return new FileMediaStorage(config);
|
|
42523
42559
|
}
|
|
42560
|
+
function getDefaultBaseDirectory4() {
|
|
42561
|
+
const platform2 = process.platform;
|
|
42562
|
+
if (platform2 === "win32") {
|
|
42563
|
+
const appData = process.env.APPDATA || process.env.LOCALAPPDATA;
|
|
42564
|
+
if (appData) {
|
|
42565
|
+
return path2.join(appData, "oneringai", "custom-tools");
|
|
42566
|
+
}
|
|
42567
|
+
}
|
|
42568
|
+
return path2.join(os2.homedir(), ".oneringai", "custom-tools");
|
|
42569
|
+
}
|
|
42570
|
+
function sanitizeName(name) {
|
|
42571
|
+
return name.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase() || "default";
|
|
42572
|
+
}
|
|
42573
|
+
var FileCustomToolStorage = class {
|
|
42574
|
+
baseDirectory;
|
|
42575
|
+
indexPath;
|
|
42576
|
+
prettyPrint;
|
|
42577
|
+
index = null;
|
|
42578
|
+
constructor(config = {}) {
|
|
42579
|
+
this.baseDirectory = config.baseDirectory ?? getDefaultBaseDirectory4();
|
|
42580
|
+
this.prettyPrint = config.prettyPrint ?? true;
|
|
42581
|
+
this.indexPath = path2.join(this.baseDirectory, "_index.json");
|
|
42582
|
+
}
|
|
42583
|
+
/**
|
|
42584
|
+
* Save a custom tool definition
|
|
42585
|
+
*/
|
|
42586
|
+
async save(definition) {
|
|
42587
|
+
const sanitized = sanitizeName(definition.name);
|
|
42588
|
+
const filePath = path2.join(this.baseDirectory, `${sanitized}.json`);
|
|
42589
|
+
await this.ensureDirectory(this.baseDirectory);
|
|
42590
|
+
const data = this.prettyPrint ? JSON.stringify(definition, null, 2) : JSON.stringify(definition);
|
|
42591
|
+
const tempPath = `${filePath}.tmp`;
|
|
42592
|
+
try {
|
|
42593
|
+
await fs17.promises.writeFile(tempPath, data, "utf-8");
|
|
42594
|
+
await fs17.promises.rename(tempPath, filePath);
|
|
42595
|
+
} catch (error) {
|
|
42596
|
+
try {
|
|
42597
|
+
await fs17.promises.unlink(tempPath);
|
|
42598
|
+
} catch {
|
|
42599
|
+
}
|
|
42600
|
+
throw error;
|
|
42601
|
+
}
|
|
42602
|
+
await this.updateIndex(definition);
|
|
42603
|
+
}
|
|
42604
|
+
/**
|
|
42605
|
+
* Load a custom tool definition by name
|
|
42606
|
+
*/
|
|
42607
|
+
async load(name) {
|
|
42608
|
+
const sanitized = sanitizeName(name);
|
|
42609
|
+
const filePath = path2.join(this.baseDirectory, `${sanitized}.json`);
|
|
42610
|
+
try {
|
|
42611
|
+
const data = await fs17.promises.readFile(filePath, "utf-8");
|
|
42612
|
+
return JSON.parse(data);
|
|
42613
|
+
} catch (error) {
|
|
42614
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
42615
|
+
return null;
|
|
42616
|
+
}
|
|
42617
|
+
if (error instanceof SyntaxError) {
|
|
42618
|
+
return null;
|
|
42619
|
+
}
|
|
42620
|
+
throw error;
|
|
42621
|
+
}
|
|
42622
|
+
}
|
|
42623
|
+
/**
|
|
42624
|
+
* Delete a custom tool definition
|
|
42625
|
+
*/
|
|
42626
|
+
async delete(name) {
|
|
42627
|
+
const sanitized = sanitizeName(name);
|
|
42628
|
+
const filePath = path2.join(this.baseDirectory, `${sanitized}.json`);
|
|
42629
|
+
try {
|
|
42630
|
+
await fs17.promises.unlink(filePath);
|
|
42631
|
+
} catch (error) {
|
|
42632
|
+
if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
|
|
42633
|
+
throw error;
|
|
42634
|
+
}
|
|
42635
|
+
}
|
|
42636
|
+
await this.removeFromIndex(name);
|
|
42637
|
+
}
|
|
42638
|
+
/**
|
|
42639
|
+
* Check if a custom tool exists
|
|
42640
|
+
*/
|
|
42641
|
+
async exists(name) {
|
|
42642
|
+
const sanitized = sanitizeName(name);
|
|
42643
|
+
const filePath = path2.join(this.baseDirectory, `${sanitized}.json`);
|
|
42644
|
+
try {
|
|
42645
|
+
await fs17.promises.access(filePath);
|
|
42646
|
+
return true;
|
|
42647
|
+
} catch {
|
|
42648
|
+
return false;
|
|
42649
|
+
}
|
|
42650
|
+
}
|
|
42651
|
+
/**
|
|
42652
|
+
* List custom tools (summaries only)
|
|
42653
|
+
*/
|
|
42654
|
+
async list(options) {
|
|
42655
|
+
const index = await this.loadIndex();
|
|
42656
|
+
let entries = [...index.tools];
|
|
42657
|
+
if (options?.tags && options.tags.length > 0) {
|
|
42658
|
+
entries = entries.filter((e) => {
|
|
42659
|
+
const entryTags = e.tags ?? [];
|
|
42660
|
+
return options.tags.some((t) => entryTags.includes(t));
|
|
42661
|
+
});
|
|
42662
|
+
}
|
|
42663
|
+
if (options?.category) {
|
|
42664
|
+
entries = entries.filter((e) => e.category === options.category);
|
|
42665
|
+
}
|
|
42666
|
+
if (options?.search) {
|
|
42667
|
+
const searchLower = options.search.toLowerCase();
|
|
42668
|
+
entries = entries.filter(
|
|
42669
|
+
(e) => e.name.toLowerCase().includes(searchLower) || e.description.toLowerCase().includes(searchLower)
|
|
42670
|
+
);
|
|
42671
|
+
}
|
|
42672
|
+
entries.sort(
|
|
42673
|
+
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
42674
|
+
);
|
|
42675
|
+
if (options?.offset) {
|
|
42676
|
+
entries = entries.slice(options.offset);
|
|
42677
|
+
}
|
|
42678
|
+
if (options?.limit) {
|
|
42679
|
+
entries = entries.slice(0, options.limit);
|
|
42680
|
+
}
|
|
42681
|
+
return entries.map((e) => ({
|
|
42682
|
+
name: e.name,
|
|
42683
|
+
displayName: e.displayName,
|
|
42684
|
+
description: e.description,
|
|
42685
|
+
createdAt: e.createdAt,
|
|
42686
|
+
updatedAt: e.updatedAt,
|
|
42687
|
+
metadata: {
|
|
42688
|
+
tags: e.tags,
|
|
42689
|
+
category: e.category
|
|
42690
|
+
}
|
|
42691
|
+
}));
|
|
42692
|
+
}
|
|
42693
|
+
/**
|
|
42694
|
+
* Update metadata without loading full definition
|
|
42695
|
+
*/
|
|
42696
|
+
async updateMetadata(name, metadata) {
|
|
42697
|
+
const definition = await this.load(name);
|
|
42698
|
+
if (!definition) {
|
|
42699
|
+
throw new Error(`Custom tool '${name}' not found`);
|
|
42700
|
+
}
|
|
42701
|
+
definition.metadata = { ...definition.metadata, ...metadata };
|
|
42702
|
+
definition.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
42703
|
+
await this.save(definition);
|
|
42704
|
+
}
|
|
42705
|
+
/**
|
|
42706
|
+
* Get storage path
|
|
42707
|
+
*/
|
|
42708
|
+
getPath() {
|
|
42709
|
+
return this.baseDirectory;
|
|
42710
|
+
}
|
|
42711
|
+
// ==========================================================================
|
|
42712
|
+
// Private Helpers
|
|
42713
|
+
// ==========================================================================
|
|
42714
|
+
async ensureDirectory(dir) {
|
|
42715
|
+
try {
|
|
42716
|
+
await fs17.promises.mkdir(dir, { recursive: true });
|
|
42717
|
+
} catch (error) {
|
|
42718
|
+
if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
|
|
42719
|
+
throw error;
|
|
42720
|
+
}
|
|
42721
|
+
}
|
|
42722
|
+
}
|
|
42723
|
+
async loadIndex() {
|
|
42724
|
+
if (this.index) {
|
|
42725
|
+
return this.index;
|
|
42726
|
+
}
|
|
42727
|
+
try {
|
|
42728
|
+
const data = await fs17.promises.readFile(this.indexPath, "utf-8");
|
|
42729
|
+
this.index = JSON.parse(data);
|
|
42730
|
+
return this.index;
|
|
42731
|
+
} catch (error) {
|
|
42732
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
42733
|
+
this.index = {
|
|
42734
|
+
version: 1,
|
|
42735
|
+
tools: [],
|
|
42736
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
42737
|
+
};
|
|
42738
|
+
return this.index;
|
|
42739
|
+
}
|
|
42740
|
+
throw error;
|
|
42741
|
+
}
|
|
42742
|
+
}
|
|
42743
|
+
async saveIndex() {
|
|
42744
|
+
if (!this.index) return;
|
|
42745
|
+
await this.ensureDirectory(this.baseDirectory);
|
|
42746
|
+
this.index.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
42747
|
+
const data = this.prettyPrint ? JSON.stringify(this.index, null, 2) : JSON.stringify(this.index);
|
|
42748
|
+
await fs17.promises.writeFile(this.indexPath, data, "utf-8");
|
|
42749
|
+
}
|
|
42750
|
+
async updateIndex(definition) {
|
|
42751
|
+
const index = await this.loadIndex();
|
|
42752
|
+
const entry = this.definitionToIndexEntry(definition);
|
|
42753
|
+
const existingIdx = index.tools.findIndex((e) => e.name === definition.name);
|
|
42754
|
+
if (existingIdx >= 0) {
|
|
42755
|
+
index.tools[existingIdx] = entry;
|
|
42756
|
+
} else {
|
|
42757
|
+
index.tools.push(entry);
|
|
42758
|
+
}
|
|
42759
|
+
await this.saveIndex();
|
|
42760
|
+
}
|
|
42761
|
+
async removeFromIndex(name) {
|
|
42762
|
+
const index = await this.loadIndex();
|
|
42763
|
+
index.tools = index.tools.filter((e) => e.name !== name);
|
|
42764
|
+
await this.saveIndex();
|
|
42765
|
+
}
|
|
42766
|
+
definitionToIndexEntry(definition) {
|
|
42767
|
+
return {
|
|
42768
|
+
name: definition.name,
|
|
42769
|
+
displayName: definition.displayName,
|
|
42770
|
+
description: definition.description,
|
|
42771
|
+
createdAt: definition.createdAt,
|
|
42772
|
+
updatedAt: definition.updatedAt,
|
|
42773
|
+
tags: definition.metadata?.tags,
|
|
42774
|
+
category: definition.metadata?.category
|
|
42775
|
+
};
|
|
42776
|
+
}
|
|
42777
|
+
};
|
|
42778
|
+
function createFileCustomToolStorage(config) {
|
|
42779
|
+
return new FileCustomToolStorage(config);
|
|
42780
|
+
}
|
|
42781
|
+
|
|
42782
|
+
// src/domain/entities/CustomToolDefinition.ts
|
|
42783
|
+
var CUSTOM_TOOL_DEFINITION_VERSION = 1;
|
|
42524
42784
|
|
|
42525
42785
|
// src/capabilities/agents/StreamHelpers.ts
|
|
42526
42786
|
var StreamHelpers = class {
|
|
@@ -43617,8 +43877,8 @@ var FileStorage = class {
|
|
|
43617
43877
|
}
|
|
43618
43878
|
async ensureDirectory() {
|
|
43619
43879
|
try {
|
|
43620
|
-
await
|
|
43621
|
-
await
|
|
43880
|
+
await fs16__namespace.mkdir(this.directory, { recursive: true });
|
|
43881
|
+
await fs16__namespace.chmod(this.directory, 448);
|
|
43622
43882
|
} catch (error) {
|
|
43623
43883
|
}
|
|
43624
43884
|
}
|
|
@@ -43634,13 +43894,13 @@ var FileStorage = class {
|
|
|
43634
43894
|
const filePath = this.getFilePath(key);
|
|
43635
43895
|
const plaintext = JSON.stringify(token);
|
|
43636
43896
|
const encrypted = encrypt(plaintext, this.encryptionKey);
|
|
43637
|
-
await
|
|
43638
|
-
await
|
|
43897
|
+
await fs16__namespace.writeFile(filePath, encrypted, "utf8");
|
|
43898
|
+
await fs16__namespace.chmod(filePath, 384);
|
|
43639
43899
|
}
|
|
43640
43900
|
async getToken(key) {
|
|
43641
43901
|
const filePath = this.getFilePath(key);
|
|
43642
43902
|
try {
|
|
43643
|
-
const encrypted = await
|
|
43903
|
+
const encrypted = await fs16__namespace.readFile(filePath, "utf8");
|
|
43644
43904
|
const decrypted = decrypt(encrypted, this.encryptionKey);
|
|
43645
43905
|
return JSON.parse(decrypted);
|
|
43646
43906
|
} catch (error) {
|
|
@@ -43649,7 +43909,7 @@ var FileStorage = class {
|
|
|
43649
43909
|
}
|
|
43650
43910
|
console.error("Failed to read/decrypt token file:", error);
|
|
43651
43911
|
try {
|
|
43652
|
-
await
|
|
43912
|
+
await fs16__namespace.unlink(filePath);
|
|
43653
43913
|
} catch {
|
|
43654
43914
|
}
|
|
43655
43915
|
return null;
|
|
@@ -43658,7 +43918,7 @@ var FileStorage = class {
|
|
|
43658
43918
|
async deleteToken(key) {
|
|
43659
43919
|
const filePath = this.getFilePath(key);
|
|
43660
43920
|
try {
|
|
43661
|
-
await
|
|
43921
|
+
await fs16__namespace.unlink(filePath);
|
|
43662
43922
|
} catch (error) {
|
|
43663
43923
|
if (error.code !== "ENOENT") {
|
|
43664
43924
|
throw error;
|
|
@@ -43668,7 +43928,7 @@ var FileStorage = class {
|
|
|
43668
43928
|
async hasToken(key) {
|
|
43669
43929
|
const filePath = this.getFilePath(key);
|
|
43670
43930
|
try {
|
|
43671
|
-
await
|
|
43931
|
+
await fs16__namespace.access(filePath);
|
|
43672
43932
|
return true;
|
|
43673
43933
|
} catch {
|
|
43674
43934
|
return false;
|
|
@@ -43679,7 +43939,7 @@ var FileStorage = class {
|
|
|
43679
43939
|
*/
|
|
43680
43940
|
async listTokens() {
|
|
43681
43941
|
try {
|
|
43682
|
-
const files = await
|
|
43942
|
+
const files = await fs16__namespace.readdir(this.directory);
|
|
43683
43943
|
return files.filter((f) => f.endsWith(".token")).map((f) => f.replace(".token", ""));
|
|
43684
43944
|
} catch {
|
|
43685
43945
|
return [];
|
|
@@ -43690,10 +43950,10 @@ var FileStorage = class {
|
|
|
43690
43950
|
*/
|
|
43691
43951
|
async clearAll() {
|
|
43692
43952
|
try {
|
|
43693
|
-
const files = await
|
|
43953
|
+
const files = await fs16__namespace.readdir(this.directory);
|
|
43694
43954
|
const tokenFiles = files.filter((f) => f.endsWith(".token"));
|
|
43695
43955
|
await Promise.all(
|
|
43696
|
-
tokenFiles.map((f) =>
|
|
43956
|
+
tokenFiles.map((f) => fs16__namespace.unlink(path2__namespace.join(this.directory, f)).catch(() => {
|
|
43697
43957
|
}))
|
|
43698
43958
|
);
|
|
43699
43959
|
} catch {
|
|
@@ -44120,14 +44380,14 @@ var FileConnectorStorage = class {
|
|
|
44120
44380
|
await this.ensureDirectory();
|
|
44121
44381
|
const filePath = this.getFilePath(name);
|
|
44122
44382
|
const json = JSON.stringify(stored, null, 2);
|
|
44123
|
-
await
|
|
44124
|
-
await
|
|
44383
|
+
await fs16__namespace.writeFile(filePath, json, "utf8");
|
|
44384
|
+
await fs16__namespace.chmod(filePath, 384);
|
|
44125
44385
|
await this.updateIndex(name, "add");
|
|
44126
44386
|
}
|
|
44127
44387
|
async get(name) {
|
|
44128
44388
|
const filePath = this.getFilePath(name);
|
|
44129
44389
|
try {
|
|
44130
|
-
const json = await
|
|
44390
|
+
const json = await fs16__namespace.readFile(filePath, "utf8");
|
|
44131
44391
|
return JSON.parse(json);
|
|
44132
44392
|
} catch (error) {
|
|
44133
44393
|
const err = error;
|
|
@@ -44140,7 +44400,7 @@ var FileConnectorStorage = class {
|
|
|
44140
44400
|
async delete(name) {
|
|
44141
44401
|
const filePath = this.getFilePath(name);
|
|
44142
44402
|
try {
|
|
44143
|
-
await
|
|
44403
|
+
await fs16__namespace.unlink(filePath);
|
|
44144
44404
|
await this.updateIndex(name, "remove");
|
|
44145
44405
|
return true;
|
|
44146
44406
|
} catch (error) {
|
|
@@ -44154,7 +44414,7 @@ var FileConnectorStorage = class {
|
|
|
44154
44414
|
async has(name) {
|
|
44155
44415
|
const filePath = this.getFilePath(name);
|
|
44156
44416
|
try {
|
|
44157
|
-
await
|
|
44417
|
+
await fs16__namespace.access(filePath);
|
|
44158
44418
|
return true;
|
|
44159
44419
|
} catch {
|
|
44160
44420
|
return false;
|
|
@@ -44180,13 +44440,13 @@ var FileConnectorStorage = class {
|
|
|
44180
44440
|
*/
|
|
44181
44441
|
async clear() {
|
|
44182
44442
|
try {
|
|
44183
|
-
const files = await
|
|
44443
|
+
const files = await fs16__namespace.readdir(this.directory);
|
|
44184
44444
|
const connectorFiles = files.filter(
|
|
44185
44445
|
(f) => f.endsWith(".connector.json") || f === "_index.json"
|
|
44186
44446
|
);
|
|
44187
44447
|
await Promise.all(
|
|
44188
44448
|
connectorFiles.map(
|
|
44189
|
-
(f) =>
|
|
44449
|
+
(f) => fs16__namespace.unlink(path2__namespace.join(this.directory, f)).catch(() => {
|
|
44190
44450
|
})
|
|
44191
44451
|
)
|
|
44192
44452
|
);
|
|
@@ -44213,8 +44473,8 @@ var FileConnectorStorage = class {
|
|
|
44213
44473
|
async ensureDirectory() {
|
|
44214
44474
|
if (this.initialized) return;
|
|
44215
44475
|
try {
|
|
44216
|
-
await
|
|
44217
|
-
await
|
|
44476
|
+
await fs16__namespace.mkdir(this.directory, { recursive: true });
|
|
44477
|
+
await fs16__namespace.chmod(this.directory, 448);
|
|
44218
44478
|
this.initialized = true;
|
|
44219
44479
|
} catch {
|
|
44220
44480
|
this.initialized = true;
|
|
@@ -44225,7 +44485,7 @@ var FileConnectorStorage = class {
|
|
|
44225
44485
|
*/
|
|
44226
44486
|
async loadIndex() {
|
|
44227
44487
|
try {
|
|
44228
|
-
const json = await
|
|
44488
|
+
const json = await fs16__namespace.readFile(this.indexPath, "utf8");
|
|
44229
44489
|
return JSON.parse(json);
|
|
44230
44490
|
} catch {
|
|
44231
44491
|
return { connectors: {} };
|
|
@@ -44243,8 +44503,8 @@ var FileConnectorStorage = class {
|
|
|
44243
44503
|
delete index.connectors[hash];
|
|
44244
44504
|
}
|
|
44245
44505
|
const json = JSON.stringify(index, null, 2);
|
|
44246
|
-
await
|
|
44247
|
-
await
|
|
44506
|
+
await fs16__namespace.writeFile(this.indexPath, json, "utf8");
|
|
44507
|
+
await fs16__namespace.chmod(this.indexPath, 384);
|
|
44248
44508
|
}
|
|
44249
44509
|
};
|
|
44250
44510
|
|
|
@@ -46699,8 +46959,8 @@ function createMessageWithImages(text, imageUrls, role = "user" /* USER */) {
|
|
|
46699
46959
|
var execAsync = util.promisify(child_process.exec);
|
|
46700
46960
|
function cleanupTempFile(filePath) {
|
|
46701
46961
|
try {
|
|
46702
|
-
if (
|
|
46703
|
-
|
|
46962
|
+
if (fs17__namespace.existsSync(filePath)) {
|
|
46963
|
+
fs17__namespace.unlinkSync(filePath);
|
|
46704
46964
|
}
|
|
46705
46965
|
} catch {
|
|
46706
46966
|
}
|
|
@@ -46751,7 +47011,7 @@ async function readClipboardImageMac() {
|
|
|
46751
47011
|
end try
|
|
46752
47012
|
`;
|
|
46753
47013
|
const { stdout } = await execAsync(`osascript -e '${script}'`);
|
|
46754
|
-
if (stdout.includes("success") ||
|
|
47014
|
+
if (stdout.includes("success") || fs17__namespace.existsSync(tempFile)) {
|
|
46755
47015
|
return await convertFileToDataUri(tempFile);
|
|
46756
47016
|
}
|
|
46757
47017
|
return {
|
|
@@ -46768,14 +47028,14 @@ async function readClipboardImageLinux() {
|
|
|
46768
47028
|
try {
|
|
46769
47029
|
try {
|
|
46770
47030
|
await execAsync(`xclip -selection clipboard -t image/png -o > "${tempFile}"`);
|
|
46771
|
-
if (
|
|
47031
|
+
if (fs17__namespace.existsSync(tempFile) && fs17__namespace.statSync(tempFile).size > 0) {
|
|
46772
47032
|
return await convertFileToDataUri(tempFile);
|
|
46773
47033
|
}
|
|
46774
47034
|
} catch {
|
|
46775
47035
|
}
|
|
46776
47036
|
try {
|
|
46777
47037
|
await execAsync(`wl-paste -t image/png > "${tempFile}"`);
|
|
46778
|
-
if (
|
|
47038
|
+
if (fs17__namespace.existsSync(tempFile) && fs17__namespace.statSync(tempFile).size > 0) {
|
|
46779
47039
|
return await convertFileToDataUri(tempFile);
|
|
46780
47040
|
}
|
|
46781
47041
|
} catch {
|
|
@@ -46802,7 +47062,7 @@ async function readClipboardImageWindows() {
|
|
|
46802
47062
|
}
|
|
46803
47063
|
`;
|
|
46804
47064
|
await execAsync(`powershell -Command "${psScript}"`);
|
|
46805
|
-
if (
|
|
47065
|
+
if (fs17__namespace.existsSync(tempFile) && fs17__namespace.statSync(tempFile).size > 0) {
|
|
46806
47066
|
return await convertFileToDataUri(tempFile);
|
|
46807
47067
|
}
|
|
46808
47068
|
return {
|
|
@@ -46815,7 +47075,7 @@ async function readClipboardImageWindows() {
|
|
|
46815
47075
|
}
|
|
46816
47076
|
async function convertFileToDataUri(filePath) {
|
|
46817
47077
|
try {
|
|
46818
|
-
const imageBuffer =
|
|
47078
|
+
const imageBuffer = fs17__namespace.readFileSync(filePath);
|
|
46819
47079
|
const base64Image = imageBuffer.toString("base64");
|
|
46820
47080
|
const magic = imageBuffer.slice(0, 4).toString("hex");
|
|
46821
47081
|
let mimeType = "image/png";
|
|
@@ -47071,6 +47331,13 @@ __export(tools_exports, {
|
|
|
47071
47331
|
bash: () => bash,
|
|
47072
47332
|
createBashTool: () => createBashTool,
|
|
47073
47333
|
createCreatePRTool: () => createCreatePRTool,
|
|
47334
|
+
createCustomToolDelete: () => createCustomToolDelete,
|
|
47335
|
+
createCustomToolDraft: () => createCustomToolDraft,
|
|
47336
|
+
createCustomToolList: () => createCustomToolList,
|
|
47337
|
+
createCustomToolLoad: () => createCustomToolLoad,
|
|
47338
|
+
createCustomToolMetaTools: () => createCustomToolMetaTools,
|
|
47339
|
+
createCustomToolSave: () => createCustomToolSave,
|
|
47340
|
+
createCustomToolTest: () => createCustomToolTest,
|
|
47074
47341
|
createDesktopGetCursorTool: () => createDesktopGetCursorTool,
|
|
47075
47342
|
createDesktopGetScreenSizeTool: () => createDesktopGetScreenSizeTool,
|
|
47076
47343
|
createDesktopKeyboardKeyTool: () => createDesktopKeyboardKeyTool,
|
|
@@ -47101,6 +47368,12 @@ __export(tools_exports, {
|
|
|
47101
47368
|
createWebScrapeTool: () => createWebScrapeTool,
|
|
47102
47369
|
createWebSearchTool: () => createWebSearchTool,
|
|
47103
47370
|
createWriteFileTool: () => createWriteFileTool,
|
|
47371
|
+
customToolDelete: () => customToolDelete,
|
|
47372
|
+
customToolDraft: () => customToolDraft,
|
|
47373
|
+
customToolList: () => customToolList,
|
|
47374
|
+
customToolLoad: () => customToolLoad,
|
|
47375
|
+
customToolSave: () => customToolSave,
|
|
47376
|
+
customToolTest: () => customToolTest,
|
|
47104
47377
|
desktopGetCursor: () => desktopGetCursor,
|
|
47105
47378
|
desktopGetScreenSize: () => desktopGetScreenSize,
|
|
47106
47379
|
desktopKeyboardKey: () => desktopKeyboardKey,
|
|
@@ -47115,6 +47388,7 @@ __export(tools_exports, {
|
|
|
47115
47388
|
desktopWindowList: () => desktopWindowList,
|
|
47116
47389
|
developerTools: () => developerTools,
|
|
47117
47390
|
editFile: () => editFile,
|
|
47391
|
+
executeInVM: () => executeInVM,
|
|
47118
47392
|
executeJavaScript: () => executeJavaScript,
|
|
47119
47393
|
expandTilde: () => expandTilde,
|
|
47120
47394
|
getAllBuiltInTools: () => getAllBuiltInTools,
|
|
@@ -47129,6 +47403,7 @@ __export(tools_exports, {
|
|
|
47129
47403
|
getToolsRequiringConnector: () => getToolsRequiringConnector,
|
|
47130
47404
|
glob: () => glob,
|
|
47131
47405
|
grep: () => grep,
|
|
47406
|
+
hydrateCustomTool: () => hydrateCustomTool,
|
|
47132
47407
|
isBlockedCommand: () => isBlockedCommand,
|
|
47133
47408
|
isExcludedExtension: () => isExcludedExtension,
|
|
47134
47409
|
jsonManipulator: () => jsonManipulator,
|
|
@@ -47349,7 +47624,7 @@ EXAMPLES:
|
|
|
47349
47624
|
};
|
|
47350
47625
|
}
|
|
47351
47626
|
const resolvedPath = validation.resolvedPath;
|
|
47352
|
-
if (!
|
|
47627
|
+
if (!fs17.existsSync(resolvedPath)) {
|
|
47353
47628
|
return {
|
|
47354
47629
|
success: false,
|
|
47355
47630
|
error: `File not found: ${file_path}`,
|
|
@@ -47357,7 +47632,7 @@ EXAMPLES:
|
|
|
47357
47632
|
};
|
|
47358
47633
|
}
|
|
47359
47634
|
try {
|
|
47360
|
-
const stats = await
|
|
47635
|
+
const stats = await fs16.stat(resolvedPath);
|
|
47361
47636
|
if (!stats.isFile()) {
|
|
47362
47637
|
return {
|
|
47363
47638
|
success: false,
|
|
@@ -47399,7 +47674,7 @@ EXAMPLES:
|
|
|
47399
47674
|
} catch {
|
|
47400
47675
|
}
|
|
47401
47676
|
}
|
|
47402
|
-
const content = await
|
|
47677
|
+
const content = await fs16.readFile(resolvedPath, "utf-8");
|
|
47403
47678
|
const allLines = content.split("\n");
|
|
47404
47679
|
const totalLines = allLines.length;
|
|
47405
47680
|
const startIndex = Math.max(0, offset - 1);
|
|
@@ -47504,13 +47779,13 @@ EXAMPLES:
|
|
|
47504
47779
|
};
|
|
47505
47780
|
}
|
|
47506
47781
|
const resolvedPath = validation.resolvedPath;
|
|
47507
|
-
const fileExists =
|
|
47782
|
+
const fileExists = fs17.existsSync(resolvedPath);
|
|
47508
47783
|
try {
|
|
47509
47784
|
const parentDir = path2.dirname(resolvedPath);
|
|
47510
|
-
if (!
|
|
47511
|
-
await
|
|
47785
|
+
if (!fs17.existsSync(parentDir)) {
|
|
47786
|
+
await fs16.mkdir(parentDir, { recursive: true });
|
|
47512
47787
|
}
|
|
47513
|
-
await
|
|
47788
|
+
await fs16.writeFile(resolvedPath, content, "utf-8");
|
|
47514
47789
|
return {
|
|
47515
47790
|
success: true,
|
|
47516
47791
|
path: file_path,
|
|
@@ -47613,7 +47888,7 @@ EXAMPLES:
|
|
|
47613
47888
|
};
|
|
47614
47889
|
}
|
|
47615
47890
|
const resolvedPath = validation.resolvedPath;
|
|
47616
|
-
if (!
|
|
47891
|
+
if (!fs17.existsSync(resolvedPath)) {
|
|
47617
47892
|
return {
|
|
47618
47893
|
success: false,
|
|
47619
47894
|
error: `File not found: ${file_path}`,
|
|
@@ -47621,7 +47896,7 @@ EXAMPLES:
|
|
|
47621
47896
|
};
|
|
47622
47897
|
}
|
|
47623
47898
|
try {
|
|
47624
|
-
const content = await
|
|
47899
|
+
const content = await fs16.readFile(resolvedPath, "utf-8");
|
|
47625
47900
|
let occurrences = 0;
|
|
47626
47901
|
let searchIndex = 0;
|
|
47627
47902
|
while (true) {
|
|
@@ -47660,7 +47935,7 @@ EXAMPLES:
|
|
|
47660
47935
|
} else {
|
|
47661
47936
|
newContent = content.replace(old_string, new_string);
|
|
47662
47937
|
}
|
|
47663
|
-
await
|
|
47938
|
+
await fs16.writeFile(resolvedPath, newContent, "utf-8");
|
|
47664
47939
|
const diffPreview = generateDiffPreview(old_string, new_string);
|
|
47665
47940
|
return {
|
|
47666
47941
|
success: true,
|
|
@@ -47716,7 +47991,7 @@ async function findFiles(dir, pattern, baseDir, config, results = [], depth = 0)
|
|
|
47716
47991
|
return results;
|
|
47717
47992
|
}
|
|
47718
47993
|
try {
|
|
47719
|
-
const entries = await
|
|
47994
|
+
const entries = await fs16.readdir(dir, { withFileTypes: true });
|
|
47720
47995
|
for (const entry of entries) {
|
|
47721
47996
|
if (results.length >= config.maxResults) break;
|
|
47722
47997
|
const fullPath = path2.join(dir, entry.name);
|
|
@@ -47730,7 +48005,7 @@ async function findFiles(dir, pattern, baseDir, config, results = [], depth = 0)
|
|
|
47730
48005
|
} else if (entry.isFile()) {
|
|
47731
48006
|
if (matchGlobPattern(pattern, relativePath)) {
|
|
47732
48007
|
try {
|
|
47733
|
-
const stats = await
|
|
48008
|
+
const stats = await fs16.stat(fullPath);
|
|
47734
48009
|
results.push({
|
|
47735
48010
|
path: relativePath,
|
|
47736
48011
|
mtime: stats.mtimeMs
|
|
@@ -47812,7 +48087,7 @@ WHEN TO USE:
|
|
|
47812
48087
|
};
|
|
47813
48088
|
}
|
|
47814
48089
|
const resolvedDir = validation.resolvedPath;
|
|
47815
|
-
if (!
|
|
48090
|
+
if (!fs17.existsSync(resolvedDir)) {
|
|
47816
48091
|
return {
|
|
47817
48092
|
success: false,
|
|
47818
48093
|
error: `Directory not found: ${searchDir}`
|
|
@@ -47867,7 +48142,7 @@ async function findFilesToSearch(dir, baseDir, config, globPattern, fileType, fi
|
|
|
47867
48142
|
return files;
|
|
47868
48143
|
}
|
|
47869
48144
|
try {
|
|
47870
|
-
const entries = await
|
|
48145
|
+
const entries = await fs16.readdir(dir, { withFileTypes: true });
|
|
47871
48146
|
for (const entry of entries) {
|
|
47872
48147
|
const fullPath = path2.join(dir, entry.name);
|
|
47873
48148
|
if (entry.isDirectory()) {
|
|
@@ -47900,7 +48175,7 @@ async function findFilesToSearch(dir, baseDir, config, globPattern, fileType, fi
|
|
|
47900
48175
|
async function searchFile(filePath, regex, contextBefore, contextAfter) {
|
|
47901
48176
|
const matches = [];
|
|
47902
48177
|
try {
|
|
47903
|
-
const content = await
|
|
48178
|
+
const content = await fs16.readFile(filePath, "utf-8");
|
|
47904
48179
|
const lines = content.split("\n");
|
|
47905
48180
|
for (let i = 0; i < lines.length; i++) {
|
|
47906
48181
|
const line = lines[i] ?? "";
|
|
@@ -48041,7 +48316,7 @@ WHEN TO USE:
|
|
|
48041
48316
|
};
|
|
48042
48317
|
}
|
|
48043
48318
|
const resolvedPath = validation.resolvedPath;
|
|
48044
|
-
if (!
|
|
48319
|
+
if (!fs17.existsSync(resolvedPath)) {
|
|
48045
48320
|
return {
|
|
48046
48321
|
success: false,
|
|
48047
48322
|
error: `Path not found: ${searchPath}`
|
|
@@ -48057,7 +48332,7 @@ WHEN TO USE:
|
|
|
48057
48332
|
};
|
|
48058
48333
|
}
|
|
48059
48334
|
try {
|
|
48060
|
-
const stats = await
|
|
48335
|
+
const stats = await fs16.stat(resolvedPath);
|
|
48061
48336
|
let filesToSearch;
|
|
48062
48337
|
if (stats.isFile()) {
|
|
48063
48338
|
filesToSearch = [resolvedPath];
|
|
@@ -48145,7 +48420,7 @@ async function listDir(dir, baseDir, config, recursive, filter, maxDepth = 3, cu
|
|
|
48145
48420
|
return entries;
|
|
48146
48421
|
}
|
|
48147
48422
|
try {
|
|
48148
|
-
const dirEntries = await
|
|
48423
|
+
const dirEntries = await fs16.readdir(dir, { withFileTypes: true });
|
|
48149
48424
|
for (const entry of dirEntries) {
|
|
48150
48425
|
if (entries.length >= config.maxResults) break;
|
|
48151
48426
|
const fullPath = path2.join(dir, entry.name);
|
|
@@ -48163,7 +48438,7 @@ async function listDir(dir, baseDir, config, recursive, filter, maxDepth = 3, cu
|
|
|
48163
48438
|
}
|
|
48164
48439
|
if (filter === "directories" && !isDir) continue;
|
|
48165
48440
|
try {
|
|
48166
|
-
const stats = await
|
|
48441
|
+
const stats = await fs16.stat(fullPath);
|
|
48167
48442
|
const dirEntry = {
|
|
48168
48443
|
name: entry.name,
|
|
48169
48444
|
path: relativePath,
|
|
@@ -48259,14 +48534,14 @@ EXAMPLES:
|
|
|
48259
48534
|
};
|
|
48260
48535
|
}
|
|
48261
48536
|
const resolvedPath = validation.resolvedPath;
|
|
48262
|
-
if (!
|
|
48537
|
+
if (!fs17.existsSync(resolvedPath)) {
|
|
48263
48538
|
return {
|
|
48264
48539
|
success: false,
|
|
48265
48540
|
error: `Directory not found: ${path6}`
|
|
48266
48541
|
};
|
|
48267
48542
|
}
|
|
48268
48543
|
try {
|
|
48269
|
-
const stats = await
|
|
48544
|
+
const stats = await fs16.stat(resolvedPath);
|
|
48270
48545
|
if (!stats.isDirectory()) {
|
|
48271
48546
|
return {
|
|
48272
48547
|
success: false,
|
|
@@ -52036,6 +52311,498 @@ var desktopTools = [
|
|
|
52036
52311
|
desktopWindowFocus
|
|
52037
52312
|
];
|
|
52038
52313
|
|
|
52314
|
+
// src/tools/custom-tools/customToolDelete.ts
|
|
52315
|
+
function createCustomToolDelete(storage) {
|
|
52316
|
+
return {
|
|
52317
|
+
definition: {
|
|
52318
|
+
type: "function",
|
|
52319
|
+
function: {
|
|
52320
|
+
name: "custom_tool_delete",
|
|
52321
|
+
description: "Delete a custom tool from persistent storage.",
|
|
52322
|
+
parameters: {
|
|
52323
|
+
type: "object",
|
|
52324
|
+
properties: {
|
|
52325
|
+
name: {
|
|
52326
|
+
type: "string",
|
|
52327
|
+
description: "Name of the tool to delete"
|
|
52328
|
+
}
|
|
52329
|
+
},
|
|
52330
|
+
required: ["name"]
|
|
52331
|
+
}
|
|
52332
|
+
}
|
|
52333
|
+
},
|
|
52334
|
+
permission: { scope: "session", riskLevel: "medium" },
|
|
52335
|
+
execute: async (args) => {
|
|
52336
|
+
try {
|
|
52337
|
+
const exists = await storage.exists(args.name);
|
|
52338
|
+
if (!exists) {
|
|
52339
|
+
return { success: false, name: args.name, error: `Custom tool '${args.name}' not found` };
|
|
52340
|
+
}
|
|
52341
|
+
await storage.delete(args.name);
|
|
52342
|
+
return { success: true, name: args.name };
|
|
52343
|
+
} catch (error) {
|
|
52344
|
+
return { success: false, name: args.name, error: error.message };
|
|
52345
|
+
}
|
|
52346
|
+
},
|
|
52347
|
+
describeCall: (args) => args.name
|
|
52348
|
+
};
|
|
52349
|
+
}
|
|
52350
|
+
var customToolDelete = createCustomToolDelete(new FileCustomToolStorage());
|
|
52351
|
+
|
|
52352
|
+
// src/tools/custom-tools/sandboxDescription.ts
|
|
52353
|
+
init_Connector();
|
|
52354
|
+
function formatConnectorEntry2(c) {
|
|
52355
|
+
const parts = [];
|
|
52356
|
+
const serviceOrVendor = c.serviceType ?? c.vendor ?? void 0;
|
|
52357
|
+
if (serviceOrVendor) parts.push(`Service: ${serviceOrVendor}`);
|
|
52358
|
+
if (c.config.description) parts.push(c.config.description);
|
|
52359
|
+
if (c.baseURL) parts.push(`URL: ${c.baseURL}`);
|
|
52360
|
+
const details = parts.map((p) => ` ${p}`).join("\n");
|
|
52361
|
+
return ` \u2022 "${c.name}" (${c.displayName})
|
|
52362
|
+
${details}`;
|
|
52363
|
+
}
|
|
52364
|
+
function buildConnectorList(context) {
|
|
52365
|
+
const registry = context?.connectorRegistry ?? exports.Connector.asRegistry();
|
|
52366
|
+
const connectors = registry.listAll();
|
|
52367
|
+
if (connectors.length === 0) {
|
|
52368
|
+
return " No connectors registered.";
|
|
52369
|
+
}
|
|
52370
|
+
return connectors.map(formatConnectorEntry2).join("\n\n");
|
|
52371
|
+
}
|
|
52372
|
+
var SANDBOX_API_REFERENCE = `SANDBOX API (available inside custom tool code):
|
|
52373
|
+
|
|
52374
|
+
1. authenticatedFetch(url, options, connectorName)
|
|
52375
|
+
Makes authenticated HTTP requests using the connector's credentials.
|
|
52376
|
+
Auth headers are added automatically \u2014 DO NOT set Authorization header manually.
|
|
52377
|
+
|
|
52378
|
+
Parameters:
|
|
52379
|
+
\u2022 url: Full URL or path relative to the connector's base URL
|
|
52380
|
+
- Full: "https://api.github.com/user/repos"
|
|
52381
|
+
- Relative: "/user/repos" (resolved against connector's base URL)
|
|
52382
|
+
\u2022 options: Standard fetch options { method, headers, body }
|
|
52383
|
+
- For POST/PUT: set body to JSON.stringify(data) and headers to { 'Content-Type': 'application/json' }
|
|
52384
|
+
\u2022 connectorName: Name of a registered connector (see REGISTERED CONNECTORS below)
|
|
52385
|
+
|
|
52386
|
+
Returns: Promise<Response>
|
|
52387
|
+
\u2022 response.ok \u2014 true if status 200-299
|
|
52388
|
+
\u2022 response.status \u2014 HTTP status code
|
|
52389
|
+
\u2022 await response.json() \u2014 parse JSON body
|
|
52390
|
+
\u2022 await response.text() \u2014 get text body
|
|
52391
|
+
|
|
52392
|
+
2. fetch(url, options) \u2014 Standard fetch without authentication
|
|
52393
|
+
|
|
52394
|
+
3. connectors.list() \u2014 Array of available connector names
|
|
52395
|
+
4. connectors.get(name) \u2014 Connector info: { displayName, description, baseURL, serviceType }
|
|
52396
|
+
|
|
52397
|
+
VARIABLES:
|
|
52398
|
+
\u2022 input \u2014 the tool's input arguments (matches inputSchema)
|
|
52399
|
+
\u2022 output \u2014 SET THIS to return the tool's result to the caller
|
|
52400
|
+
|
|
52401
|
+
GLOBALS: console.log/error/warn, JSON, Math, Date, Buffer, Promise, Array, Object, String, Number, Boolean, setTimeout, setInterval, URL, URLSearchParams, RegExp, Map, Set, Error, TextEncoder, TextDecoder
|
|
52402
|
+
|
|
52403
|
+
LIMITS: No file system access, no require/import. Code runs in async context (await is available).`;
|
|
52404
|
+
function buildDraftDescription(context) {
|
|
52405
|
+
const connectorList = buildConnectorList(context);
|
|
52406
|
+
return `Validate a draft custom tool definition. Checks name format, schema structure, and code syntax.
|
|
52407
|
+
|
|
52408
|
+
When writing the "code" field, you have access to the full VM sandbox:
|
|
52409
|
+
|
|
52410
|
+
${SANDBOX_API_REFERENCE}
|
|
52411
|
+
|
|
52412
|
+
REGISTERED CONNECTORS:
|
|
52413
|
+
${connectorList}
|
|
52414
|
+
|
|
52415
|
+
CODE EXAMPLES:
|
|
52416
|
+
|
|
52417
|
+
// Simple data processing tool
|
|
52418
|
+
const items = input.data;
|
|
52419
|
+
output = items.filter(i => i.score > 0.8).sort((a, b) => b.score - a.score);
|
|
52420
|
+
|
|
52421
|
+
// API tool using a connector
|
|
52422
|
+
const resp = await authenticatedFetch('/user/repos', { method: 'GET' }, 'github');
|
|
52423
|
+
const repos = await resp.json();
|
|
52424
|
+
output = repos.map(r => ({ name: r.full_name, stars: r.stargazers_count }));
|
|
52425
|
+
|
|
52426
|
+
// Tool that chains multiple API calls
|
|
52427
|
+
const users = await (await authenticatedFetch('/users', {}, 'my-api')).json();
|
|
52428
|
+
const enriched = await Promise.all(users.map(async u => {
|
|
52429
|
+
const details = await (await authenticatedFetch(\`/users/\${u.id}\`, {}, 'my-api')).json();
|
|
52430
|
+
return { ...u, ...details };
|
|
52431
|
+
}));
|
|
52432
|
+
output = enriched;`;
|
|
52433
|
+
}
|
|
52434
|
+
function buildTestDescription(context) {
|
|
52435
|
+
const connectorList = buildConnectorList(context);
|
|
52436
|
+
return `Test custom tool code by executing it in the VM sandbox with provided test input. Returns execution result, captured logs, and timing.
|
|
52437
|
+
|
|
52438
|
+
The code runs in the same sandbox as execute_javascript:
|
|
52439
|
+
|
|
52440
|
+
${SANDBOX_API_REFERENCE}
|
|
52441
|
+
|
|
52442
|
+
REGISTERED CONNECTORS:
|
|
52443
|
+
${connectorList}
|
|
52444
|
+
|
|
52445
|
+
The testInput you provide will be available as the \`input\` variable in the code.
|
|
52446
|
+
Set \`output\` to the value you want returned.`;
|
|
52447
|
+
}
|
|
52448
|
+
|
|
52449
|
+
// src/tools/custom-tools/customToolDraft.ts
|
|
52450
|
+
var NAME_PATTERN = /^[a-z][a-z0-9_]*$/;
|
|
52451
|
+
function createCustomToolDraft() {
|
|
52452
|
+
return {
|
|
52453
|
+
definition: {
|
|
52454
|
+
type: "function",
|
|
52455
|
+
function: {
|
|
52456
|
+
name: "custom_tool_draft",
|
|
52457
|
+
description: "Validate a draft custom tool definition. Checks name format, schema structure, and code syntax.",
|
|
52458
|
+
parameters: {
|
|
52459
|
+
type: "object",
|
|
52460
|
+
properties: {
|
|
52461
|
+
name: {
|
|
52462
|
+
type: "string",
|
|
52463
|
+
description: 'Tool name (lowercase, underscores, must start with letter). Example: "fetch_weather"'
|
|
52464
|
+
},
|
|
52465
|
+
description: {
|
|
52466
|
+
type: "string",
|
|
52467
|
+
description: "What the tool does"
|
|
52468
|
+
},
|
|
52469
|
+
inputSchema: {
|
|
52470
|
+
type: "object",
|
|
52471
|
+
description: 'JSON Schema for the tool input (must have type: "object")'
|
|
52472
|
+
},
|
|
52473
|
+
outputSchema: {
|
|
52474
|
+
type: "object",
|
|
52475
|
+
description: "Optional JSON Schema for the tool output (documentation only)"
|
|
52476
|
+
},
|
|
52477
|
+
code: {
|
|
52478
|
+
type: "string",
|
|
52479
|
+
description: "JavaScript code that reads `input` and sets `output`. Runs in the same sandbox as execute_javascript. See tool description for full API reference."
|
|
52480
|
+
},
|
|
52481
|
+
tags: {
|
|
52482
|
+
type: "array",
|
|
52483
|
+
description: "Optional tags for categorization",
|
|
52484
|
+
items: { type: "string" }
|
|
52485
|
+
},
|
|
52486
|
+
connectorName: {
|
|
52487
|
+
type: "string",
|
|
52488
|
+
description: "Optional connector name if the tool requires API access"
|
|
52489
|
+
}
|
|
52490
|
+
},
|
|
52491
|
+
required: ["name", "description", "inputSchema", "code"]
|
|
52492
|
+
}
|
|
52493
|
+
}
|
|
52494
|
+
},
|
|
52495
|
+
descriptionFactory: (context) => buildDraftDescription(context),
|
|
52496
|
+
permission: { scope: "always", riskLevel: "low" },
|
|
52497
|
+
execute: async (args) => {
|
|
52498
|
+
const errors = [];
|
|
52499
|
+
if (!args.name || typeof args.name !== "string") {
|
|
52500
|
+
errors.push("name is required and must be a string");
|
|
52501
|
+
} else if (!NAME_PATTERN.test(args.name)) {
|
|
52502
|
+
errors.push(
|
|
52503
|
+
`name "${args.name}" is invalid. Must match /^[a-z][a-z0-9_]*$/ (lowercase, underscores, start with letter)`
|
|
52504
|
+
);
|
|
52505
|
+
}
|
|
52506
|
+
if (!args.description || typeof args.description !== "string" || args.description.trim().length === 0) {
|
|
52507
|
+
errors.push("description is required and must be a non-empty string");
|
|
52508
|
+
}
|
|
52509
|
+
if (!args.inputSchema || typeof args.inputSchema !== "object") {
|
|
52510
|
+
errors.push("inputSchema is required and must be an object");
|
|
52511
|
+
} else if (args.inputSchema.type !== "object") {
|
|
52512
|
+
errors.push('inputSchema.type must be "object"');
|
|
52513
|
+
}
|
|
52514
|
+
if (!args.code || typeof args.code !== "string" || args.code.trim().length === 0) {
|
|
52515
|
+
errors.push("code is required and must be a non-empty string");
|
|
52516
|
+
} else {
|
|
52517
|
+
try {
|
|
52518
|
+
new Function(args.code);
|
|
52519
|
+
} catch (e) {
|
|
52520
|
+
errors.push(`code has syntax error: ${e.message}`);
|
|
52521
|
+
}
|
|
52522
|
+
}
|
|
52523
|
+
if (errors.length > 0) {
|
|
52524
|
+
return { success: false, errors };
|
|
52525
|
+
}
|
|
52526
|
+
return {
|
|
52527
|
+
success: true,
|
|
52528
|
+
validated: {
|
|
52529
|
+
name: args.name,
|
|
52530
|
+
description: args.description,
|
|
52531
|
+
inputSchema: args.inputSchema,
|
|
52532
|
+
outputSchema: args.outputSchema,
|
|
52533
|
+
code: args.code,
|
|
52534
|
+
tags: args.tags,
|
|
52535
|
+
connectorName: args.connectorName
|
|
52536
|
+
}
|
|
52537
|
+
};
|
|
52538
|
+
},
|
|
52539
|
+
describeCall: (args) => args.name ?? "unknown"
|
|
52540
|
+
};
|
|
52541
|
+
}
|
|
52542
|
+
var customToolDraft = createCustomToolDraft();
|
|
52543
|
+
|
|
52544
|
+
// src/tools/custom-tools/customToolList.ts
|
|
52545
|
+
function createCustomToolList(storage) {
|
|
52546
|
+
return {
|
|
52547
|
+
definition: {
|
|
52548
|
+
type: "function",
|
|
52549
|
+
function: {
|
|
52550
|
+
name: "custom_tool_list",
|
|
52551
|
+
description: "List saved custom tools from persistent storage. Supports filtering by search text, tags, and category.",
|
|
52552
|
+
parameters: {
|
|
52553
|
+
type: "object",
|
|
52554
|
+
properties: {
|
|
52555
|
+
search: {
|
|
52556
|
+
type: "string",
|
|
52557
|
+
description: "Search text (case-insensitive substring match on name + description)"
|
|
52558
|
+
},
|
|
52559
|
+
tags: {
|
|
52560
|
+
type: "array",
|
|
52561
|
+
description: "Filter by tags (any match)",
|
|
52562
|
+
items: { type: "string" }
|
|
52563
|
+
},
|
|
52564
|
+
category: {
|
|
52565
|
+
type: "string",
|
|
52566
|
+
description: "Filter by category"
|
|
52567
|
+
},
|
|
52568
|
+
limit: {
|
|
52569
|
+
type: "number",
|
|
52570
|
+
description: "Maximum number of results"
|
|
52571
|
+
},
|
|
52572
|
+
offset: {
|
|
52573
|
+
type: "number",
|
|
52574
|
+
description: "Offset for pagination"
|
|
52575
|
+
}
|
|
52576
|
+
}
|
|
52577
|
+
}
|
|
52578
|
+
}
|
|
52579
|
+
},
|
|
52580
|
+
permission: { scope: "always", riskLevel: "low" },
|
|
52581
|
+
execute: async (args) => {
|
|
52582
|
+
const tools = await storage.list({
|
|
52583
|
+
search: args.search,
|
|
52584
|
+
tags: args.tags,
|
|
52585
|
+
category: args.category,
|
|
52586
|
+
limit: args.limit,
|
|
52587
|
+
offset: args.offset
|
|
52588
|
+
});
|
|
52589
|
+
return { tools, total: tools.length };
|
|
52590
|
+
},
|
|
52591
|
+
describeCall: (args) => args.search ?? "all tools"
|
|
52592
|
+
};
|
|
52593
|
+
}
|
|
52594
|
+
var customToolList = createCustomToolList(new FileCustomToolStorage());
|
|
52595
|
+
|
|
52596
|
+
// src/tools/custom-tools/customToolLoad.ts
|
|
52597
|
+
function createCustomToolLoad(storage) {
|
|
52598
|
+
return {
|
|
52599
|
+
definition: {
|
|
52600
|
+
type: "function",
|
|
52601
|
+
function: {
|
|
52602
|
+
name: "custom_tool_load",
|
|
52603
|
+
description: "Load a full custom tool definition from storage (including code). Use this to inspect, modify, or hydrate a saved tool.",
|
|
52604
|
+
parameters: {
|
|
52605
|
+
type: "object",
|
|
52606
|
+
properties: {
|
|
52607
|
+
name: {
|
|
52608
|
+
type: "string",
|
|
52609
|
+
description: "Name of the tool to load"
|
|
52610
|
+
}
|
|
52611
|
+
},
|
|
52612
|
+
required: ["name"]
|
|
52613
|
+
}
|
|
52614
|
+
}
|
|
52615
|
+
},
|
|
52616
|
+
permission: { scope: "always", riskLevel: "low" },
|
|
52617
|
+
execute: async (args) => {
|
|
52618
|
+
const tool = await storage.load(args.name);
|
|
52619
|
+
if (!tool) {
|
|
52620
|
+
return { success: false, error: `Custom tool '${args.name}' not found` };
|
|
52621
|
+
}
|
|
52622
|
+
return { success: true, tool };
|
|
52623
|
+
},
|
|
52624
|
+
describeCall: (args) => args.name
|
|
52625
|
+
};
|
|
52626
|
+
}
|
|
52627
|
+
var customToolLoad = createCustomToolLoad(new FileCustomToolStorage());
|
|
52628
|
+
|
|
52629
|
+
// src/tools/custom-tools/customToolSave.ts
|
|
52630
|
+
function createCustomToolSave(storage) {
|
|
52631
|
+
return {
|
|
52632
|
+
definition: {
|
|
52633
|
+
type: "function",
|
|
52634
|
+
function: {
|
|
52635
|
+
name: "custom_tool_save",
|
|
52636
|
+
description: "Save a custom tool definition to persistent storage. The tool can later be loaded, hydrated, and registered on any agent.",
|
|
52637
|
+
parameters: {
|
|
52638
|
+
type: "object",
|
|
52639
|
+
properties: {
|
|
52640
|
+
name: {
|
|
52641
|
+
type: "string",
|
|
52642
|
+
description: "Tool name (must match /^[a-z][a-z0-9_]*$/)"
|
|
52643
|
+
},
|
|
52644
|
+
description: {
|
|
52645
|
+
type: "string",
|
|
52646
|
+
description: "What the tool does"
|
|
52647
|
+
},
|
|
52648
|
+
displayName: {
|
|
52649
|
+
type: "string",
|
|
52650
|
+
description: "Optional human-readable display name"
|
|
52651
|
+
},
|
|
52652
|
+
inputSchema: {
|
|
52653
|
+
type: "object",
|
|
52654
|
+
description: "JSON Schema for input parameters"
|
|
52655
|
+
},
|
|
52656
|
+
outputSchema: {
|
|
52657
|
+
type: "object",
|
|
52658
|
+
description: "Optional JSON Schema for output"
|
|
52659
|
+
},
|
|
52660
|
+
code: {
|
|
52661
|
+
type: "string",
|
|
52662
|
+
description: "JavaScript code (same sandbox as execute_javascript)"
|
|
52663
|
+
},
|
|
52664
|
+
tags: {
|
|
52665
|
+
type: "array",
|
|
52666
|
+
description: "Tags for categorization",
|
|
52667
|
+
items: { type: "string" }
|
|
52668
|
+
},
|
|
52669
|
+
category: {
|
|
52670
|
+
type: "string",
|
|
52671
|
+
description: "Category grouping"
|
|
52672
|
+
},
|
|
52673
|
+
generationPrompt: {
|
|
52674
|
+
type: "string",
|
|
52675
|
+
description: "The prompt that was used to generate this tool (for reference)"
|
|
52676
|
+
},
|
|
52677
|
+
connectorNames: {
|
|
52678
|
+
type: "array",
|
|
52679
|
+
description: "Connector names this tool uses",
|
|
52680
|
+
items: { type: "string" }
|
|
52681
|
+
}
|
|
52682
|
+
},
|
|
52683
|
+
required: ["name", "description", "inputSchema", "code"]
|
|
52684
|
+
}
|
|
52685
|
+
}
|
|
52686
|
+
},
|
|
52687
|
+
permission: { scope: "session", riskLevel: "medium" },
|
|
52688
|
+
execute: async (args) => {
|
|
52689
|
+
try {
|
|
52690
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
52691
|
+
const existing = await storage.load(args.name);
|
|
52692
|
+
const definition = {
|
|
52693
|
+
version: CUSTOM_TOOL_DEFINITION_VERSION,
|
|
52694
|
+
name: args.name,
|
|
52695
|
+
displayName: args.displayName,
|
|
52696
|
+
description: args.description,
|
|
52697
|
+
inputSchema: args.inputSchema,
|
|
52698
|
+
outputSchema: args.outputSchema,
|
|
52699
|
+
code: args.code,
|
|
52700
|
+
createdAt: existing?.createdAt ?? now,
|
|
52701
|
+
updatedAt: now,
|
|
52702
|
+
metadata: {
|
|
52703
|
+
tags: args.tags,
|
|
52704
|
+
category: args.category,
|
|
52705
|
+
generationPrompt: args.generationPrompt,
|
|
52706
|
+
connectorNames: args.connectorNames,
|
|
52707
|
+
requiresConnector: (args.connectorNames?.length ?? 0) > 0
|
|
52708
|
+
}
|
|
52709
|
+
};
|
|
52710
|
+
await storage.save(definition);
|
|
52711
|
+
return {
|
|
52712
|
+
success: true,
|
|
52713
|
+
name: args.name,
|
|
52714
|
+
storagePath: storage.getPath()
|
|
52715
|
+
};
|
|
52716
|
+
} catch (error) {
|
|
52717
|
+
return {
|
|
52718
|
+
success: false,
|
|
52719
|
+
name: args.name,
|
|
52720
|
+
storagePath: storage.getPath(),
|
|
52721
|
+
error: error.message
|
|
52722
|
+
};
|
|
52723
|
+
}
|
|
52724
|
+
},
|
|
52725
|
+
describeCall: (args) => args.name
|
|
52726
|
+
};
|
|
52727
|
+
}
|
|
52728
|
+
var customToolSave = createCustomToolSave(new FileCustomToolStorage());
|
|
52729
|
+
|
|
52730
|
+
// src/tools/custom-tools/customToolTest.ts
|
|
52731
|
+
init_Connector();
|
|
52732
|
+
var DEFAULT_TEST_TIMEOUT = 1e4;
|
|
52733
|
+
var MAX_TEST_TIMEOUT = 3e4;
|
|
52734
|
+
function createCustomToolTest() {
|
|
52735
|
+
return {
|
|
52736
|
+
definition: {
|
|
52737
|
+
type: "function",
|
|
52738
|
+
function: {
|
|
52739
|
+
name: "custom_tool_test",
|
|
52740
|
+
description: "Test custom tool code by executing it in the VM sandbox with provided test input.",
|
|
52741
|
+
parameters: {
|
|
52742
|
+
type: "object",
|
|
52743
|
+
properties: {
|
|
52744
|
+
code: {
|
|
52745
|
+
type: "string",
|
|
52746
|
+
description: "JavaScript code to test. See tool description for full sandbox API reference."
|
|
52747
|
+
},
|
|
52748
|
+
inputSchema: {
|
|
52749
|
+
type: "object",
|
|
52750
|
+
description: "The input schema (for documentation, not enforced at test time)"
|
|
52751
|
+
},
|
|
52752
|
+
testInput: {
|
|
52753
|
+
description: "Test input data \u2014 available as `input` in the code"
|
|
52754
|
+
},
|
|
52755
|
+
connectorName: {
|
|
52756
|
+
type: "string",
|
|
52757
|
+
description: "Optional connector name for authenticated API access"
|
|
52758
|
+
},
|
|
52759
|
+
timeout: {
|
|
52760
|
+
type: "number",
|
|
52761
|
+
description: `Execution timeout in ms. Default: ${DEFAULT_TEST_TIMEOUT}, max: ${MAX_TEST_TIMEOUT}`
|
|
52762
|
+
}
|
|
52763
|
+
},
|
|
52764
|
+
required: ["code", "inputSchema", "testInput"]
|
|
52765
|
+
}
|
|
52766
|
+
},
|
|
52767
|
+
timeout: MAX_TEST_TIMEOUT + 5e3
|
|
52768
|
+
},
|
|
52769
|
+
descriptionFactory: (context) => buildTestDescription(context),
|
|
52770
|
+
permission: { scope: "session", riskLevel: "medium" },
|
|
52771
|
+
execute: async (args, context) => {
|
|
52772
|
+
const logs = [];
|
|
52773
|
+
const startTime = Date.now();
|
|
52774
|
+
const timeout = Math.min(Math.max(args.timeout || DEFAULT_TEST_TIMEOUT, 0), MAX_TEST_TIMEOUT);
|
|
52775
|
+
try {
|
|
52776
|
+
const registry = context?.connectorRegistry ?? exports.Connector.asRegistry();
|
|
52777
|
+
const result = await executeInVM(
|
|
52778
|
+
args.code,
|
|
52779
|
+
args.testInput,
|
|
52780
|
+
timeout,
|
|
52781
|
+
logs,
|
|
52782
|
+
context?.userId,
|
|
52783
|
+
registry
|
|
52784
|
+
);
|
|
52785
|
+
return {
|
|
52786
|
+
success: true,
|
|
52787
|
+
result,
|
|
52788
|
+
logs,
|
|
52789
|
+
executionTime: Date.now() - startTime
|
|
52790
|
+
};
|
|
52791
|
+
} catch (error) {
|
|
52792
|
+
return {
|
|
52793
|
+
success: false,
|
|
52794
|
+
result: null,
|
|
52795
|
+
logs,
|
|
52796
|
+
error: error.message,
|
|
52797
|
+
executionTime: Date.now() - startTime
|
|
52798
|
+
};
|
|
52799
|
+
}
|
|
52800
|
+
},
|
|
52801
|
+
describeCall: (args) => `testing code (${args.code.length} chars)`
|
|
52802
|
+
};
|
|
52803
|
+
}
|
|
52804
|
+
var customToolTest = createCustomToolTest();
|
|
52805
|
+
|
|
52039
52806
|
// src/tools/registry.generated.ts
|
|
52040
52807
|
var toolRegistry = [
|
|
52041
52808
|
{
|
|
@@ -52047,6 +52814,60 @@ var toolRegistry = [
|
|
|
52047
52814
|
tool: executeJavaScript,
|
|
52048
52815
|
safeByDefault: false
|
|
52049
52816
|
},
|
|
52817
|
+
{
|
|
52818
|
+
name: "custom_tool_delete",
|
|
52819
|
+
exportName: "customToolDelete",
|
|
52820
|
+
displayName: "Custom Tool Delete",
|
|
52821
|
+
category: "custom-tools",
|
|
52822
|
+
description: "Delete a custom tool from persistent storage.",
|
|
52823
|
+
tool: customToolDelete,
|
|
52824
|
+
safeByDefault: false
|
|
52825
|
+
},
|
|
52826
|
+
{
|
|
52827
|
+
name: "custom_tool_draft",
|
|
52828
|
+
exportName: "customToolDraft",
|
|
52829
|
+
displayName: "Custom Tool Draft",
|
|
52830
|
+
category: "custom-tools",
|
|
52831
|
+
description: "Validate a draft custom tool definition. Checks name format, schema structure, and code syntax.",
|
|
52832
|
+
tool: customToolDraft,
|
|
52833
|
+
safeByDefault: true
|
|
52834
|
+
},
|
|
52835
|
+
{
|
|
52836
|
+
name: "custom_tool_list",
|
|
52837
|
+
exportName: "customToolList",
|
|
52838
|
+
displayName: "Custom Tool List",
|
|
52839
|
+
category: "custom-tools",
|
|
52840
|
+
description: "List saved custom tools from persistent storage. Supports filtering by search text, tags, and category.",
|
|
52841
|
+
tool: customToolList,
|
|
52842
|
+
safeByDefault: true
|
|
52843
|
+
},
|
|
52844
|
+
{
|
|
52845
|
+
name: "custom_tool_load",
|
|
52846
|
+
exportName: "customToolLoad",
|
|
52847
|
+
displayName: "Custom Tool Load",
|
|
52848
|
+
category: "custom-tools",
|
|
52849
|
+
description: "Load a full custom tool definition from storage (including code).",
|
|
52850
|
+
tool: customToolLoad,
|
|
52851
|
+
safeByDefault: true
|
|
52852
|
+
},
|
|
52853
|
+
{
|
|
52854
|
+
name: "custom_tool_save",
|
|
52855
|
+
exportName: "customToolSave",
|
|
52856
|
+
displayName: "Custom Tool Save",
|
|
52857
|
+
category: "custom-tools",
|
|
52858
|
+
description: "Save a custom tool definition to persistent storage.",
|
|
52859
|
+
tool: customToolSave,
|
|
52860
|
+
safeByDefault: false
|
|
52861
|
+
},
|
|
52862
|
+
{
|
|
52863
|
+
name: "custom_tool_test",
|
|
52864
|
+
exportName: "customToolTest",
|
|
52865
|
+
displayName: "Custom Tool Test",
|
|
52866
|
+
category: "custom-tools",
|
|
52867
|
+
description: "Test custom tool code by executing it in the VM sandbox with provided test input.",
|
|
52868
|
+
tool: customToolTest,
|
|
52869
|
+
safeByDefault: false
|
|
52870
|
+
},
|
|
52050
52871
|
{
|
|
52051
52872
|
name: "desktop_get_cursor",
|
|
52052
52873
|
exportName: "desktopGetCursor",
|
|
@@ -52247,6 +53068,61 @@ function getToolCategories() {
|
|
|
52247
53068
|
return [...new Set(toolRegistry.map((entry) => entry.category))];
|
|
52248
53069
|
}
|
|
52249
53070
|
|
|
53071
|
+
// src/tools/custom-tools/factories.ts
|
|
53072
|
+
function createCustomToolMetaTools(options) {
|
|
53073
|
+
const storage = options?.storage ?? new FileCustomToolStorage();
|
|
53074
|
+
return [
|
|
53075
|
+
createCustomToolDraft(),
|
|
53076
|
+
createCustomToolTest(),
|
|
53077
|
+
createCustomToolSave(storage),
|
|
53078
|
+
createCustomToolList(storage),
|
|
53079
|
+
createCustomToolLoad(storage),
|
|
53080
|
+
createCustomToolDelete(storage)
|
|
53081
|
+
];
|
|
53082
|
+
}
|
|
53083
|
+
|
|
53084
|
+
// src/tools/custom-tools/hydrate.ts
|
|
53085
|
+
init_Connector();
|
|
53086
|
+
var DEFAULT_TIMEOUT2 = 1e4;
|
|
53087
|
+
var MAX_TIMEOUT = 3e4;
|
|
53088
|
+
function hydrateCustomTool(definition, options) {
|
|
53089
|
+
const defaultTimeout = options?.defaultTimeout ?? DEFAULT_TIMEOUT2;
|
|
53090
|
+
const maxTimeout = options?.maxTimeout ?? MAX_TIMEOUT;
|
|
53091
|
+
return {
|
|
53092
|
+
definition: {
|
|
53093
|
+
type: "function",
|
|
53094
|
+
function: {
|
|
53095
|
+
name: definition.name,
|
|
53096
|
+
description: definition.description,
|
|
53097
|
+
parameters: definition.inputSchema
|
|
53098
|
+
},
|
|
53099
|
+
timeout: maxTimeout + 5e3
|
|
53100
|
+
},
|
|
53101
|
+
permission: { scope: "session", riskLevel: "medium" },
|
|
53102
|
+
execute: async (args, context) => {
|
|
53103
|
+
const logs = [];
|
|
53104
|
+
const registry = context?.connectorRegistry ?? exports.Connector.asRegistry();
|
|
53105
|
+
const result = await executeInVM(
|
|
53106
|
+
definition.code,
|
|
53107
|
+
args,
|
|
53108
|
+
defaultTimeout,
|
|
53109
|
+
logs,
|
|
53110
|
+
context?.userId,
|
|
53111
|
+
registry
|
|
53112
|
+
);
|
|
53113
|
+
return result;
|
|
53114
|
+
},
|
|
53115
|
+
describeCall: (args) => {
|
|
53116
|
+
if (!args || typeof args !== "object") return definition.name;
|
|
53117
|
+
const firstKey = Object.keys(args)[0];
|
|
53118
|
+
if (!firstKey) return definition.name;
|
|
53119
|
+
const val = args[firstKey];
|
|
53120
|
+
const str = typeof val === "string" ? val : JSON.stringify(val);
|
|
53121
|
+
return str.length > 50 ? str.slice(0, 47) + "..." : str;
|
|
53122
|
+
}
|
|
53123
|
+
};
|
|
53124
|
+
}
|
|
53125
|
+
|
|
52250
53126
|
// src/tools/ToolRegistry.ts
|
|
52251
53127
|
init_Connector();
|
|
52252
53128
|
var ToolRegistry = class {
|
|
@@ -52596,6 +53472,7 @@ exports.BaseTextProvider = BaseTextProvider;
|
|
|
52596
53472
|
exports.BraveProvider = BraveProvider;
|
|
52597
53473
|
exports.CONNECTOR_CONFIG_VERSION = CONNECTOR_CONFIG_VERSION;
|
|
52598
53474
|
exports.CONTEXT_SESSION_FORMAT_VERSION = CONTEXT_SESSION_FORMAT_VERSION;
|
|
53475
|
+
exports.CUSTOM_TOOL_DEFINITION_VERSION = CUSTOM_TOOL_DEFINITION_VERSION;
|
|
52599
53476
|
exports.CheckpointManager = CheckpointManager;
|
|
52600
53477
|
exports.ConnectorConfigStore = ConnectorConfigStore;
|
|
52601
53478
|
exports.ConnectorTools = ConnectorTools;
|
|
@@ -52623,6 +53500,7 @@ exports.ExternalDependencyHandler = ExternalDependencyHandler;
|
|
|
52623
53500
|
exports.FileAgentDefinitionStorage = FileAgentDefinitionStorage;
|
|
52624
53501
|
exports.FileConnectorStorage = FileConnectorStorage;
|
|
52625
53502
|
exports.FileContextStorage = FileContextStorage;
|
|
53503
|
+
exports.FileCustomToolStorage = FileCustomToolStorage;
|
|
52626
53504
|
exports.FileMediaOutputHandler = FileMediaStorage;
|
|
52627
53505
|
exports.FileMediaStorage = FileMediaStorage;
|
|
52628
53506
|
exports.FilePersistentInstructionsStorage = FilePersistentInstructionsStorage;
|
|
@@ -52733,6 +53611,13 @@ exports.createAuthenticatedFetch = createAuthenticatedFetch;
|
|
|
52733
53611
|
exports.createBashTool = createBashTool;
|
|
52734
53612
|
exports.createConnectorFromTemplate = createConnectorFromTemplate;
|
|
52735
53613
|
exports.createCreatePRTool = createCreatePRTool;
|
|
53614
|
+
exports.createCustomToolDelete = createCustomToolDelete;
|
|
53615
|
+
exports.createCustomToolDraft = createCustomToolDraft;
|
|
53616
|
+
exports.createCustomToolList = createCustomToolList;
|
|
53617
|
+
exports.createCustomToolLoad = createCustomToolLoad;
|
|
53618
|
+
exports.createCustomToolMetaTools = createCustomToolMetaTools;
|
|
53619
|
+
exports.createCustomToolSave = createCustomToolSave;
|
|
53620
|
+
exports.createCustomToolTest = createCustomToolTest;
|
|
52736
53621
|
exports.createDesktopGetCursorTool = createDesktopGetCursorTool;
|
|
52737
53622
|
exports.createDesktopGetScreenSizeTool = createDesktopGetScreenSizeTool;
|
|
52738
53623
|
exports.createDesktopKeyboardKeyTool = createDesktopKeyboardKeyTool;
|
|
@@ -52749,6 +53634,7 @@ exports.createEstimator = createEstimator;
|
|
|
52749
53634
|
exports.createExecuteJavaScriptTool = createExecuteJavaScriptTool;
|
|
52750
53635
|
exports.createFileAgentDefinitionStorage = createFileAgentDefinitionStorage;
|
|
52751
53636
|
exports.createFileContextStorage = createFileContextStorage;
|
|
53637
|
+
exports.createFileCustomToolStorage = createFileCustomToolStorage;
|
|
52752
53638
|
exports.createFileMediaStorage = createFileMediaStorage;
|
|
52753
53639
|
exports.createGetPRTool = createGetPRTool;
|
|
52754
53640
|
exports.createGitHubReadFileTool = createGitHubReadFileTool;
|
|
@@ -52773,6 +53659,12 @@ exports.createTextToSpeechTool = createTextToSpeechTool;
|
|
|
52773
53659
|
exports.createVideoProvider = createVideoProvider;
|
|
52774
53660
|
exports.createVideoTools = createVideoTools;
|
|
52775
53661
|
exports.createWriteFileTool = createWriteFileTool;
|
|
53662
|
+
exports.customToolDelete = customToolDelete;
|
|
53663
|
+
exports.customToolDraft = customToolDraft;
|
|
53664
|
+
exports.customToolList = customToolList;
|
|
53665
|
+
exports.customToolLoad = customToolLoad;
|
|
53666
|
+
exports.customToolSave = customToolSave;
|
|
53667
|
+
exports.customToolTest = customToolTest;
|
|
52776
53668
|
exports.defaultDescribeCall = defaultDescribeCall;
|
|
52777
53669
|
exports.desktopGetCursor = desktopGetCursor;
|
|
52778
53670
|
exports.desktopGetScreenSize = desktopGetScreenSize;
|
|
@@ -52857,6 +53749,7 @@ exports.globalErrorHandler = globalErrorHandler;
|
|
|
52857
53749
|
exports.grep = grep;
|
|
52858
53750
|
exports.hasClipboardImage = hasClipboardImage;
|
|
52859
53751
|
exports.hasVendorLogo = hasVendorLogo;
|
|
53752
|
+
exports.hydrateCustomTool = hydrateCustomTool;
|
|
52860
53753
|
exports.isBlockedCommand = isBlockedCommand;
|
|
52861
53754
|
exports.isErrorEvent = isErrorEvent;
|
|
52862
53755
|
exports.isExcludedExtension = isExcludedExtension;
|