@everworker/oneringai 0.1.3 → 0.1.4
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 +26 -24
- package/dist/{ImageModel-DtN780fU.d.cts → ImageModel-DSY7SNsq.d.cts} +11 -31
- package/dist/{ImageModel-BkAX5Rr5.d.ts → ImageModel-qNJHPh4q.d.ts} +11 -31
- package/dist/Vendor-DYh_bzwo.d.cts +31 -0
- package/dist/Vendor-DYh_bzwo.d.ts +31 -0
- package/dist/capabilities/agents/index.d.cts +1 -1
- package/dist/capabilities/agents/index.d.ts +1 -1
- package/dist/capabilities/images/index.d.cts +2 -1
- package/dist/capabilities/images/index.d.ts +2 -1
- package/dist/{index-BmOYeqU7.d.ts → index-CEp1H4fV.d.ts} +2 -0
- package/dist/{index-DCzFlLoN.d.cts → index-NOV01LWF.d.cts} +2 -0
- package/dist/index.cjs +1437 -353
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +585 -340
- package/dist/index.d.ts +585 -340
- package/dist/index.js +1315 -245
- package/dist/index.js.map +1 -1
- package/dist/shared/index.cjs +1780 -0
- package/dist/shared/index.cjs.map +1 -0
- package/dist/shared/index.d.cts +266 -0
- package/dist/shared/index.d.ts +266 -0
- package/dist/shared/index.js +1760 -0
- package/dist/shared/index.js.map +1 -0
- package/package.json +6 -1
package/dist/index.cjs
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
var crypto2 = require('crypto');
|
|
4
4
|
var jose = require('jose');
|
|
5
|
-
var
|
|
5
|
+
var fs16 = require('fs');
|
|
6
6
|
var eventemitter3 = require('eventemitter3');
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
7
|
+
var path2 = require('path');
|
|
8
|
+
var os2 = require('os');
|
|
9
|
+
var OpenAI3 = require('openai');
|
|
10
10
|
var Anthropic = require('@anthropic-ai/sdk');
|
|
11
11
|
var genai = require('@google/genai');
|
|
12
12
|
require('zod/v3');
|
|
@@ -14,7 +14,7 @@ var z4mini = require('zod/v4-mini');
|
|
|
14
14
|
var z = require('zod/v4');
|
|
15
15
|
var process2 = require('process');
|
|
16
16
|
var stream = require('stream');
|
|
17
|
-
var
|
|
17
|
+
var fs15 = require('fs/promises');
|
|
18
18
|
var simpleIcons = require('simple-icons');
|
|
19
19
|
var child_process = require('child_process');
|
|
20
20
|
var util = require('util');
|
|
@@ -44,15 +44,15 @@ function _interopNamespace(e) {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
var crypto2__namespace = /*#__PURE__*/_interopNamespace(crypto2);
|
|
47
|
-
var
|
|
48
|
-
var
|
|
49
|
-
var
|
|
50
|
-
var
|
|
47
|
+
var fs16__namespace = /*#__PURE__*/_interopNamespace(fs16);
|
|
48
|
+
var path2__namespace = /*#__PURE__*/_interopNamespace(path2);
|
|
49
|
+
var os2__namespace = /*#__PURE__*/_interopNamespace(os2);
|
|
50
|
+
var OpenAI3__default = /*#__PURE__*/_interopDefault(OpenAI3);
|
|
51
51
|
var Anthropic__default = /*#__PURE__*/_interopDefault(Anthropic);
|
|
52
52
|
var z4mini__namespace = /*#__PURE__*/_interopNamespace(z4mini);
|
|
53
53
|
var z__namespace = /*#__PURE__*/_interopNamespace(z);
|
|
54
54
|
var process2__default = /*#__PURE__*/_interopDefault(process2);
|
|
55
|
-
var
|
|
55
|
+
var fs15__namespace = /*#__PURE__*/_interopNamespace(fs15);
|
|
56
56
|
var simpleIcons__namespace = /*#__PURE__*/_interopNamespace(simpleIcons);
|
|
57
57
|
var TurndownService__default = /*#__PURE__*/_interopDefault(TurndownService);
|
|
58
58
|
var vm__namespace = /*#__PURE__*/_interopNamespace(vm);
|
|
@@ -631,7 +631,7 @@ var init_JWTBearer = __esm({
|
|
|
631
631
|
this.privateKey = config.privateKey;
|
|
632
632
|
} else if (config.privateKeyPath) {
|
|
633
633
|
try {
|
|
634
|
-
this.privateKey =
|
|
634
|
+
this.privateKey = fs16__namespace.readFileSync(config.privateKeyPath, "utf8");
|
|
635
635
|
} catch (error) {
|
|
636
636
|
throw new Error(`Failed to read private key from ${config.privateKeyPath}: ${error.message}`);
|
|
637
637
|
}
|
|
@@ -1281,11 +1281,11 @@ var init_Logger = __esm({
|
|
|
1281
1281
|
*/
|
|
1282
1282
|
initFileStream(filePath) {
|
|
1283
1283
|
try {
|
|
1284
|
-
const dir =
|
|
1285
|
-
if (!
|
|
1286
|
-
|
|
1284
|
+
const dir = path2__namespace.dirname(filePath);
|
|
1285
|
+
if (!fs16__namespace.existsSync(dir)) {
|
|
1286
|
+
fs16__namespace.mkdirSync(dir, { recursive: true });
|
|
1287
1287
|
}
|
|
1288
|
-
this.fileStream =
|
|
1288
|
+
this.fileStream = fs16__namespace.createWriteStream(filePath, {
|
|
1289
1289
|
flags: "a",
|
|
1290
1290
|
// append mode
|
|
1291
1291
|
encoding: "utf8"
|
|
@@ -14555,12 +14555,12 @@ var require_dist = __commonJS({
|
|
|
14555
14555
|
throw new Error(`Unknown format "${name}"`);
|
|
14556
14556
|
return f;
|
|
14557
14557
|
};
|
|
14558
|
-
function addFormats(ajv, list,
|
|
14558
|
+
function addFormats(ajv, list, fs17, exportName) {
|
|
14559
14559
|
var _a;
|
|
14560
14560
|
var _b;
|
|
14561
14561
|
(_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
14562
14562
|
for (const f of list)
|
|
14563
|
-
ajv.addFormat(f,
|
|
14563
|
+
ajv.addFormat(f, fs17[f]);
|
|
14564
14564
|
}
|
|
14565
14565
|
module.exports = exports$1 = formatsPlugin;
|
|
14566
14566
|
Object.defineProperty(exports$1, "__esModule", { value: true });
|
|
@@ -14573,7 +14573,7 @@ var require_windows = __commonJS({
|
|
|
14573
14573
|
"node_modules/isexe/windows.js"(exports$1, module) {
|
|
14574
14574
|
module.exports = isexe;
|
|
14575
14575
|
isexe.sync = sync;
|
|
14576
|
-
var
|
|
14576
|
+
var fs17 = __require("fs");
|
|
14577
14577
|
function checkPathExt(path6, options) {
|
|
14578
14578
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
14579
14579
|
if (!pathext) {
|
|
@@ -14591,19 +14591,19 @@ var require_windows = __commonJS({
|
|
|
14591
14591
|
}
|
|
14592
14592
|
return false;
|
|
14593
14593
|
}
|
|
14594
|
-
function checkStat(
|
|
14595
|
-
if (!
|
|
14594
|
+
function checkStat(stat6, path6, options) {
|
|
14595
|
+
if (!stat6.isSymbolicLink() && !stat6.isFile()) {
|
|
14596
14596
|
return false;
|
|
14597
14597
|
}
|
|
14598
14598
|
return checkPathExt(path6, options);
|
|
14599
14599
|
}
|
|
14600
14600
|
function isexe(path6, options, cb) {
|
|
14601
|
-
|
|
14602
|
-
cb(er, er ? false : checkStat(
|
|
14601
|
+
fs17.stat(path6, function(er, stat6) {
|
|
14602
|
+
cb(er, er ? false : checkStat(stat6, path6, options));
|
|
14603
14603
|
});
|
|
14604
14604
|
}
|
|
14605
14605
|
function sync(path6, options) {
|
|
14606
|
-
return checkStat(
|
|
14606
|
+
return checkStat(fs17.statSync(path6), path6, options);
|
|
14607
14607
|
}
|
|
14608
14608
|
}
|
|
14609
14609
|
});
|
|
@@ -14613,22 +14613,22 @@ var require_mode = __commonJS({
|
|
|
14613
14613
|
"node_modules/isexe/mode.js"(exports$1, module) {
|
|
14614
14614
|
module.exports = isexe;
|
|
14615
14615
|
isexe.sync = sync;
|
|
14616
|
-
var
|
|
14616
|
+
var fs17 = __require("fs");
|
|
14617
14617
|
function isexe(path6, options, cb) {
|
|
14618
|
-
|
|
14619
|
-
cb(er, er ? false : checkStat(
|
|
14618
|
+
fs17.stat(path6, function(er, stat6) {
|
|
14619
|
+
cb(er, er ? false : checkStat(stat6, options));
|
|
14620
14620
|
});
|
|
14621
14621
|
}
|
|
14622
14622
|
function sync(path6, options) {
|
|
14623
|
-
return checkStat(
|
|
14623
|
+
return checkStat(fs17.statSync(path6), options);
|
|
14624
14624
|
}
|
|
14625
|
-
function checkStat(
|
|
14626
|
-
return
|
|
14625
|
+
function checkStat(stat6, options) {
|
|
14626
|
+
return stat6.isFile() && checkMode(stat6, options);
|
|
14627
14627
|
}
|
|
14628
|
-
function checkMode(
|
|
14629
|
-
var mod =
|
|
14630
|
-
var uid =
|
|
14631
|
-
var gid =
|
|
14628
|
+
function checkMode(stat6, options) {
|
|
14629
|
+
var mod = stat6.mode;
|
|
14630
|
+
var uid = stat6.uid;
|
|
14631
|
+
var gid = stat6.gid;
|
|
14632
14632
|
var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
|
|
14633
14633
|
var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
|
|
14634
14634
|
var u = parseInt("100", 8);
|
|
@@ -14902,16 +14902,16 @@ var require_shebang_command = __commonJS({
|
|
|
14902
14902
|
// node_modules/cross-spawn/lib/util/readShebang.js
|
|
14903
14903
|
var require_readShebang = __commonJS({
|
|
14904
14904
|
"node_modules/cross-spawn/lib/util/readShebang.js"(exports$1, module) {
|
|
14905
|
-
var
|
|
14905
|
+
var fs17 = __require("fs");
|
|
14906
14906
|
var shebangCommand = require_shebang_command();
|
|
14907
14907
|
function readShebang(command) {
|
|
14908
14908
|
const size = 150;
|
|
14909
14909
|
const buffer = Buffer.alloc(size);
|
|
14910
14910
|
let fd;
|
|
14911
14911
|
try {
|
|
14912
|
-
fd =
|
|
14913
|
-
|
|
14914
|
-
|
|
14912
|
+
fd = fs17.openSync(command, "r");
|
|
14913
|
+
fs17.readSync(fd, buffer, 0, size, 0);
|
|
14914
|
+
fs17.closeSync(fd);
|
|
14915
14915
|
} catch (e) {
|
|
14916
14916
|
}
|
|
14917
14917
|
return shebangCommand(buffer.toString());
|
|
@@ -16020,13 +16020,26 @@ var ToolManager = class extends eventemitter3.EventEmitter {
|
|
|
16020
16020
|
pipeline;
|
|
16021
16021
|
/** Optional tool context for execution (set by agent before runs) */
|
|
16022
16022
|
_toolContext;
|
|
16023
|
-
|
|
16023
|
+
/** Hard timeout for tool execution (0 = disabled) */
|
|
16024
|
+
_toolExecutionTimeout;
|
|
16025
|
+
constructor(config) {
|
|
16024
16026
|
super();
|
|
16027
|
+
this._toolExecutionTimeout = config?.toolExecutionTimeout ?? 0;
|
|
16025
16028
|
this.namespaceIndex.set("default", /* @__PURE__ */ new Set());
|
|
16026
16029
|
this.toolLogger = exports.logger.child({ component: "ToolManager" });
|
|
16027
16030
|
this.pipeline = new ToolExecutionPipeline();
|
|
16028
16031
|
this.pipeline.use(new ResultNormalizerPlugin());
|
|
16029
16032
|
}
|
|
16033
|
+
/**
|
|
16034
|
+
* Get or set the hard tool execution timeout in milliseconds.
|
|
16035
|
+
* 0 = disabled (relies on tool's own timeout).
|
|
16036
|
+
*/
|
|
16037
|
+
get toolExecutionTimeout() {
|
|
16038
|
+
return this._toolExecutionTimeout;
|
|
16039
|
+
}
|
|
16040
|
+
set toolExecutionTimeout(value) {
|
|
16041
|
+
this._toolExecutionTimeout = Math.max(0, value);
|
|
16042
|
+
}
|
|
16030
16043
|
/**
|
|
16031
16044
|
* Access the execution pipeline for plugin management.
|
|
16032
16045
|
*
|
|
@@ -16524,7 +16537,7 @@ var ToolManager = class extends eventemitter3.EventEmitter {
|
|
|
16524
16537
|
const startTime = Date.now();
|
|
16525
16538
|
exports.metrics.increment("tool.executed", 1, { tool: toolName });
|
|
16526
16539
|
try {
|
|
16527
|
-
const
|
|
16540
|
+
const executionPromise = breaker.execute(async () => {
|
|
16528
16541
|
const toolWithContext = {
|
|
16529
16542
|
...registration.tool,
|
|
16530
16543
|
execute: async (pipelineArgs) => {
|
|
@@ -16533,6 +16546,7 @@ var ToolManager = class extends eventemitter3.EventEmitter {
|
|
|
16533
16546
|
};
|
|
16534
16547
|
return await this.pipeline.execute(toolWithContext, args);
|
|
16535
16548
|
});
|
|
16549
|
+
const result = this._toolExecutionTimeout > 0 ? await this.withHardTimeout(executionPromise, toolName, this._toolExecutionTimeout) : await executionPromise;
|
|
16536
16550
|
const duration = Date.now() - startTime;
|
|
16537
16551
|
this.recordExecution(toolName, duration, true);
|
|
16538
16552
|
const resultSummary = this.summarizeResult(result);
|
|
@@ -16595,6 +16609,29 @@ var ToolManager = class extends eventemitter3.EventEmitter {
|
|
|
16595
16609
|
return this.list();
|
|
16596
16610
|
}
|
|
16597
16611
|
// ==========================================================================
|
|
16612
|
+
// Hard Timeout
|
|
16613
|
+
// ==========================================================================
|
|
16614
|
+
/**
|
|
16615
|
+
* Wrap a promise with a hard timeout safety net.
|
|
16616
|
+
* If the promise doesn't resolve within the timeout, throws ToolExecutionError.
|
|
16617
|
+
*/
|
|
16618
|
+
async withHardTimeout(promise, toolName, timeoutMs) {
|
|
16619
|
+
let timeoutId;
|
|
16620
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
16621
|
+
timeoutId = setTimeout(() => {
|
|
16622
|
+
reject(new ToolExecutionError(
|
|
16623
|
+
toolName,
|
|
16624
|
+
`Tool execution hard timeout after ${timeoutMs}ms (safety net - tool's own timeout may have failed)`
|
|
16625
|
+
));
|
|
16626
|
+
}, timeoutMs);
|
|
16627
|
+
});
|
|
16628
|
+
try {
|
|
16629
|
+
return await Promise.race([promise, timeoutPromise]);
|
|
16630
|
+
} finally {
|
|
16631
|
+
clearTimeout(timeoutId);
|
|
16632
|
+
}
|
|
16633
|
+
}
|
|
16634
|
+
// ==========================================================================
|
|
16598
16635
|
// Circuit Breaker Management
|
|
16599
16636
|
// ==========================================================================
|
|
16600
16637
|
/**
|
|
@@ -19653,10 +19690,10 @@ function getDefaultBaseDirectory() {
|
|
|
19653
19690
|
if (platform2 === "win32") {
|
|
19654
19691
|
const appData = process.env.APPDATA || process.env.LOCALAPPDATA;
|
|
19655
19692
|
if (appData) {
|
|
19656
|
-
return
|
|
19693
|
+
return path2.join(appData, "oneringai", "agents");
|
|
19657
19694
|
}
|
|
19658
19695
|
}
|
|
19659
|
-
return
|
|
19696
|
+
return path2.join(os2.homedir(), ".oneringai", "agents");
|
|
19660
19697
|
}
|
|
19661
19698
|
function sanitizeAgentId(agentId) {
|
|
19662
19699
|
return agentId.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase() || "default";
|
|
@@ -19671,9 +19708,9 @@ var FilePersistentInstructionsStorage = class {
|
|
|
19671
19708
|
const sanitizedId = sanitizeAgentId(config.agentId);
|
|
19672
19709
|
const baseDir = config.baseDirectory ?? getDefaultBaseDirectory();
|
|
19673
19710
|
const filename = config.filename ?? "custom_instructions.json";
|
|
19674
|
-
this.directory =
|
|
19675
|
-
this.filePath =
|
|
19676
|
-
this.legacyFilePath =
|
|
19711
|
+
this.directory = path2.join(baseDir, sanitizedId);
|
|
19712
|
+
this.filePath = path2.join(this.directory, filename);
|
|
19713
|
+
this.legacyFilePath = path2.join(this.directory, "custom_instructions.md");
|
|
19677
19714
|
}
|
|
19678
19715
|
/**
|
|
19679
19716
|
* Load instruction entries from file.
|
|
@@ -19681,7 +19718,7 @@ var FilePersistentInstructionsStorage = class {
|
|
|
19681
19718
|
*/
|
|
19682
19719
|
async load() {
|
|
19683
19720
|
try {
|
|
19684
|
-
const raw = await
|
|
19721
|
+
const raw = await fs16.promises.readFile(this.filePath, "utf-8");
|
|
19685
19722
|
const data = JSON.parse(raw);
|
|
19686
19723
|
if (data.version === 2 && Array.isArray(data.entries)) {
|
|
19687
19724
|
return data.entries.length > 0 ? data.entries : null;
|
|
@@ -19693,7 +19730,7 @@ var FilePersistentInstructionsStorage = class {
|
|
|
19693
19730
|
}
|
|
19694
19731
|
}
|
|
19695
19732
|
try {
|
|
19696
|
-
const content = await
|
|
19733
|
+
const content = await fs16.promises.readFile(this.legacyFilePath, "utf-8");
|
|
19697
19734
|
const trimmed = content.trim();
|
|
19698
19735
|
if (!trimmed) return null;
|
|
19699
19736
|
const now = Date.now();
|
|
@@ -19723,11 +19760,11 @@ var FilePersistentInstructionsStorage = class {
|
|
|
19723
19760
|
};
|
|
19724
19761
|
const tempPath = `${this.filePath}.tmp`;
|
|
19725
19762
|
try {
|
|
19726
|
-
await
|
|
19727
|
-
await
|
|
19763
|
+
await fs16.promises.writeFile(tempPath, JSON.stringify(data, null, 2), "utf-8");
|
|
19764
|
+
await fs16.promises.rename(tempPath, this.filePath);
|
|
19728
19765
|
} catch (error) {
|
|
19729
19766
|
try {
|
|
19730
|
-
await
|
|
19767
|
+
await fs16.promises.unlink(tempPath);
|
|
19731
19768
|
} catch {
|
|
19732
19769
|
}
|
|
19733
19770
|
throw error;
|
|
@@ -19739,7 +19776,7 @@ var FilePersistentInstructionsStorage = class {
|
|
|
19739
19776
|
*/
|
|
19740
19777
|
async delete() {
|
|
19741
19778
|
try {
|
|
19742
|
-
await
|
|
19779
|
+
await fs16.promises.unlink(this.filePath);
|
|
19743
19780
|
} catch (error) {
|
|
19744
19781
|
if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
|
|
19745
19782
|
throw error;
|
|
@@ -19752,11 +19789,11 @@ var FilePersistentInstructionsStorage = class {
|
|
|
19752
19789
|
*/
|
|
19753
19790
|
async exists() {
|
|
19754
19791
|
try {
|
|
19755
|
-
await
|
|
19792
|
+
await fs16.promises.access(this.filePath);
|
|
19756
19793
|
return true;
|
|
19757
19794
|
} catch {
|
|
19758
19795
|
try {
|
|
19759
|
-
await
|
|
19796
|
+
await fs16.promises.access(this.legacyFilePath);
|
|
19760
19797
|
return true;
|
|
19761
19798
|
} catch {
|
|
19762
19799
|
return false;
|
|
@@ -19780,7 +19817,7 @@ var FilePersistentInstructionsStorage = class {
|
|
|
19780
19817
|
*/
|
|
19781
19818
|
async ensureDirectory() {
|
|
19782
19819
|
try {
|
|
19783
|
-
await
|
|
19820
|
+
await fs16.promises.mkdir(this.directory, { recursive: true });
|
|
19784
19821
|
} catch (error) {
|
|
19785
19822
|
if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
|
|
19786
19823
|
throw error;
|
|
@@ -19792,7 +19829,7 @@ var FilePersistentInstructionsStorage = class {
|
|
|
19792
19829
|
*/
|
|
19793
19830
|
async removeLegacyFile() {
|
|
19794
19831
|
try {
|
|
19795
|
-
await
|
|
19832
|
+
await fs16.promises.unlink(this.legacyFilePath);
|
|
19796
19833
|
} catch (error) {
|
|
19797
19834
|
if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
|
|
19798
19835
|
console.warn(`Failed to remove legacy instructions file: ${this.legacyFilePath}`);
|
|
@@ -20973,7 +21010,9 @@ var AgentContextNextGen = class _AgentContextNextGen extends eventemitter3.Event
|
|
|
20973
21010
|
this._agentId = this._config.agentId;
|
|
20974
21011
|
this._storage = config.storage;
|
|
20975
21012
|
this._compactionStrategy = config.compactionStrategy ?? StrategyRegistry.create(this._config.strategy);
|
|
20976
|
-
this._tools = new ToolManager(
|
|
21013
|
+
this._tools = new ToolManager(
|
|
21014
|
+
config.toolExecutionTimeout ? { toolExecutionTimeout: config.toolExecutionTimeout } : void 0
|
|
21015
|
+
);
|
|
20977
21016
|
if (config.tools) {
|
|
20978
21017
|
for (const tool of config.tools) {
|
|
20979
21018
|
this._tools.register(tool);
|
|
@@ -22709,7 +22748,7 @@ var OpenAITextProvider = class extends BaseTextProvider {
|
|
|
22709
22748
|
streamConverter;
|
|
22710
22749
|
constructor(config) {
|
|
22711
22750
|
super(config);
|
|
22712
|
-
this.client = new
|
|
22751
|
+
this.client = new OpenAI3__default.default({
|
|
22713
22752
|
apiKey: this.getApiKey(),
|
|
22714
22753
|
baseURL: this.getBaseURL(),
|
|
22715
22754
|
organization: config.organization,
|
|
@@ -24439,7 +24478,9 @@ var GoogleTextProvider = class extends BaseTextProvider {
|
|
|
24439
24478
|
constructor(config) {
|
|
24440
24479
|
super(config);
|
|
24441
24480
|
this.client = new genai.GoogleGenAI({
|
|
24442
|
-
apiKey: this.getApiKey()
|
|
24481
|
+
apiKey: this.getApiKey(),
|
|
24482
|
+
// Pass custom baseURL for proxy support (e.g. when routing through EW proxy)
|
|
24483
|
+
...config.baseURL ? { httpOptions: { baseUrl: config.baseURL } } : {}
|
|
24443
24484
|
});
|
|
24444
24485
|
this.converter = new GoogleConverter();
|
|
24445
24486
|
this.streamConverter = new GoogleStreamConverter();
|
|
@@ -24736,6 +24777,30 @@ var GenericOpenAIProvider = class extends OpenAITextProvider {
|
|
|
24736
24777
|
};
|
|
24737
24778
|
|
|
24738
24779
|
// src/core/createProvider.ts
|
|
24780
|
+
var VENDOR_DEFAULT_URLS = (() => {
|
|
24781
|
+
const map = /* @__PURE__ */ new Map();
|
|
24782
|
+
try {
|
|
24783
|
+
map.set(Vendor.OpenAI, new OpenAI3__default.default({ apiKey: "_" }).baseURL);
|
|
24784
|
+
} catch {
|
|
24785
|
+
}
|
|
24786
|
+
try {
|
|
24787
|
+
map.set(Vendor.Anthropic, new Anthropic__default.default({ apiKey: "_" }).baseURL);
|
|
24788
|
+
} catch {
|
|
24789
|
+
}
|
|
24790
|
+
map.set(Vendor.Google, "https://generativelanguage.googleapis.com");
|
|
24791
|
+
map.set(Vendor.GoogleVertex, "https://us-central1-aiplatform.googleapis.com");
|
|
24792
|
+
map.set(Vendor.Groq, "https://api.groq.com/openai/v1");
|
|
24793
|
+
map.set(Vendor.Together, "https://api.together.xyz/v1");
|
|
24794
|
+
map.set(Vendor.Perplexity, "https://api.perplexity.ai");
|
|
24795
|
+
map.set(Vendor.Grok, "https://api.x.ai/v1");
|
|
24796
|
+
map.set(Vendor.DeepSeek, "https://api.deepseek.com/v1");
|
|
24797
|
+
map.set(Vendor.Mistral, "https://api.mistral.ai/v1");
|
|
24798
|
+
map.set(Vendor.Ollama, "http://localhost:11434/v1");
|
|
24799
|
+
return map;
|
|
24800
|
+
})();
|
|
24801
|
+
function getVendorDefaultBaseURL(vendor) {
|
|
24802
|
+
return VENDOR_DEFAULT_URLS.get(vendor);
|
|
24803
|
+
}
|
|
24739
24804
|
function createProvider(connector) {
|
|
24740
24805
|
const injectedProvider = connector.getOptions().provider;
|
|
24741
24806
|
if (injectedProvider && typeof injectedProvider.generate === "function") {
|
|
@@ -24770,39 +24835,15 @@ function createProvider(connector) {
|
|
|
24770
24835
|
});
|
|
24771
24836
|
// OpenAI-compatible providers (use connector.name for unique identification)
|
|
24772
24837
|
case Vendor.Groq:
|
|
24773
|
-
return new GenericOpenAIProvider(connector.name, {
|
|
24774
|
-
...config,
|
|
24775
|
-
baseURL: config.baseURL || "https://api.groq.com/openai/v1"
|
|
24776
|
-
});
|
|
24777
24838
|
case Vendor.Together:
|
|
24778
|
-
return new GenericOpenAIProvider(connector.name, {
|
|
24779
|
-
...config,
|
|
24780
|
-
baseURL: config.baseURL || "https://api.together.xyz/v1"
|
|
24781
|
-
});
|
|
24782
24839
|
case Vendor.Perplexity:
|
|
24783
|
-
return new GenericOpenAIProvider(connector.name, {
|
|
24784
|
-
...config,
|
|
24785
|
-
baseURL: config.baseURL || "https://api.perplexity.ai"
|
|
24786
|
-
});
|
|
24787
24840
|
case Vendor.Grok:
|
|
24788
|
-
return new GenericOpenAIProvider(connector.name, {
|
|
24789
|
-
...config,
|
|
24790
|
-
baseURL: config.baseURL || "https://api.x.ai/v1"
|
|
24791
|
-
});
|
|
24792
24841
|
case Vendor.DeepSeek:
|
|
24793
|
-
return new GenericOpenAIProvider(connector.name, {
|
|
24794
|
-
...config,
|
|
24795
|
-
baseURL: config.baseURL || "https://api.deepseek.com/v1"
|
|
24796
|
-
});
|
|
24797
24842
|
case Vendor.Mistral:
|
|
24798
|
-
return new GenericOpenAIProvider(connector.name, {
|
|
24799
|
-
...config,
|
|
24800
|
-
baseURL: config.baseURL || "https://api.mistral.ai/v1"
|
|
24801
|
-
});
|
|
24802
24843
|
case Vendor.Ollama:
|
|
24803
24844
|
return new GenericOpenAIProvider(connector.name, {
|
|
24804
24845
|
...config,
|
|
24805
|
-
baseURL: config.baseURL ||
|
|
24846
|
+
baseURL: config.baseURL || getVendorDefaultBaseURL(vendor)
|
|
24806
24847
|
});
|
|
24807
24848
|
case Vendor.Custom:
|
|
24808
24849
|
if (!config.baseURL) {
|
|
@@ -24914,7 +24955,10 @@ var BaseAgent = class extends eventemitter3.EventEmitter {
|
|
|
24914
24955
|
agentId: config.name,
|
|
24915
24956
|
// Include storage and sessionId if session config is provided
|
|
24916
24957
|
storage: config.session?.storage,
|
|
24958
|
+
// Thread tool execution timeout to ToolManager
|
|
24959
|
+
toolExecutionTimeout: config.toolExecutionTimeout,
|
|
24917
24960
|
// Subclasses can add systemPrompt via their config
|
|
24961
|
+
// Note: context-level toolExecutionTimeout overrides agent-level if both set
|
|
24918
24962
|
...typeof config.context === "object" && config.context !== null ? config.context : {}
|
|
24919
24963
|
};
|
|
24920
24964
|
return AgentContextNextGen.create(contextConfig);
|
|
@@ -27354,18 +27398,18 @@ var Agent = class _Agent extends BaseAgent {
|
|
|
27354
27398
|
(class {
|
|
27355
27399
|
static DEFAULT_PATHS = [
|
|
27356
27400
|
"./oneringai.config.json",
|
|
27357
|
-
|
|
27401
|
+
path2.join(os2.homedir(), ".oneringai", "config.json")
|
|
27358
27402
|
];
|
|
27359
27403
|
/**
|
|
27360
27404
|
* Load configuration from file
|
|
27361
27405
|
*/
|
|
27362
27406
|
static async load(path6) {
|
|
27363
|
-
const configPath = path6 ?
|
|
27407
|
+
const configPath = path6 ? path2.resolve(path6) : await this.findConfig();
|
|
27364
27408
|
if (!configPath) {
|
|
27365
27409
|
throw new Error("Configuration file not found. Searched: " + this.DEFAULT_PATHS.join(", "));
|
|
27366
27410
|
}
|
|
27367
27411
|
try {
|
|
27368
|
-
const content = await
|
|
27412
|
+
const content = await fs16.promises.readFile(configPath, "utf-8");
|
|
27369
27413
|
let config = JSON.parse(content);
|
|
27370
27414
|
config = this.interpolateEnvVars(config);
|
|
27371
27415
|
this.validate(config);
|
|
@@ -27381,13 +27425,13 @@ var Agent = class _Agent extends BaseAgent {
|
|
|
27381
27425
|
* Load configuration synchronously
|
|
27382
27426
|
*/
|
|
27383
27427
|
static loadSync(path6) {
|
|
27384
|
-
const configPath = path6 ?
|
|
27428
|
+
const configPath = path6 ? path2.resolve(path6) : this.findConfigSync();
|
|
27385
27429
|
if (!configPath) {
|
|
27386
27430
|
throw new Error("Configuration file not found. Searched: " + this.DEFAULT_PATHS.join(", "));
|
|
27387
27431
|
}
|
|
27388
27432
|
try {
|
|
27389
|
-
const
|
|
27390
|
-
const content =
|
|
27433
|
+
const fs17 = __require("fs");
|
|
27434
|
+
const content = fs17.readFileSync(configPath, "utf-8");
|
|
27391
27435
|
let config = JSON.parse(content);
|
|
27392
27436
|
config = this.interpolateEnvVars(config);
|
|
27393
27437
|
this.validate(config);
|
|
@@ -27405,8 +27449,8 @@ var Agent = class _Agent extends BaseAgent {
|
|
|
27405
27449
|
static async findConfig() {
|
|
27406
27450
|
for (const path6 of this.DEFAULT_PATHS) {
|
|
27407
27451
|
try {
|
|
27408
|
-
await
|
|
27409
|
-
return
|
|
27452
|
+
await fs16.promises.access(path2.resolve(path6));
|
|
27453
|
+
return path2.resolve(path6);
|
|
27410
27454
|
} catch {
|
|
27411
27455
|
}
|
|
27412
27456
|
}
|
|
@@ -27416,11 +27460,11 @@ var Agent = class _Agent extends BaseAgent {
|
|
|
27416
27460
|
* Find configuration file synchronously
|
|
27417
27461
|
*/
|
|
27418
27462
|
static findConfigSync() {
|
|
27419
|
-
const
|
|
27463
|
+
const fs17 = __require("fs");
|
|
27420
27464
|
for (const path6 of this.DEFAULT_PATHS) {
|
|
27421
27465
|
try {
|
|
27422
|
-
|
|
27423
|
-
return
|
|
27466
|
+
fs17.accessSync(path2.resolve(path6));
|
|
27467
|
+
return path2.resolve(path6);
|
|
27424
27468
|
} catch {
|
|
27425
27469
|
}
|
|
27426
27470
|
}
|
|
@@ -32977,8 +33021,8 @@ var MCPRegistry = class {
|
|
|
32977
33021
|
*/
|
|
32978
33022
|
static async loadFromConfigFile(path6) {
|
|
32979
33023
|
try {
|
|
32980
|
-
const configPath =
|
|
32981
|
-
const content = await
|
|
33024
|
+
const configPath = path2.resolve(path6);
|
|
33025
|
+
const content = await fs16.promises.readFile(configPath, "utf-8");
|
|
32982
33026
|
const config = JSON.parse(content);
|
|
32983
33027
|
if (!config.mcp) {
|
|
32984
33028
|
throw new MCPError("Configuration file does not contain MCP section");
|
|
@@ -33366,7 +33410,7 @@ var OpenAITTSProvider = class extends BaseMediaProvider {
|
|
|
33366
33410
|
client;
|
|
33367
33411
|
constructor(config) {
|
|
33368
33412
|
super({ apiKey: config.auth.apiKey, ...config });
|
|
33369
|
-
this.client = new
|
|
33413
|
+
this.client = new OpenAI3__default.default({
|
|
33370
33414
|
apiKey: config.auth.apiKey,
|
|
33371
33415
|
baseURL: config.baseURL,
|
|
33372
33416
|
organization: config.organization,
|
|
@@ -33449,7 +33493,7 @@ var OpenAITTSProvider = class extends BaseMediaProvider {
|
|
|
33449
33493
|
* Handle OpenAI API errors
|
|
33450
33494
|
*/
|
|
33451
33495
|
handleError(error) {
|
|
33452
|
-
if (error instanceof
|
|
33496
|
+
if (error instanceof OpenAI3__default.default.APIError) {
|
|
33453
33497
|
const status = error.status;
|
|
33454
33498
|
const message = error.message || "Unknown OpenAI API error";
|
|
33455
33499
|
if (status === 401) {
|
|
@@ -33481,7 +33525,7 @@ var OpenAISTTProvider = class extends BaseMediaProvider {
|
|
|
33481
33525
|
client;
|
|
33482
33526
|
constructor(config) {
|
|
33483
33527
|
super({ apiKey: config.auth.apiKey, ...config });
|
|
33484
|
-
this.client = new
|
|
33528
|
+
this.client = new OpenAI3__default.default({
|
|
33485
33529
|
apiKey: config.auth.apiKey,
|
|
33486
33530
|
baseURL: config.baseURL,
|
|
33487
33531
|
organization: config.organization,
|
|
@@ -33583,7 +33627,7 @@ var OpenAISTTProvider = class extends BaseMediaProvider {
|
|
|
33583
33627
|
if (Buffer.isBuffer(audio)) {
|
|
33584
33628
|
return new File([new Uint8Array(audio)], "audio.wav", { type: "audio/wav" });
|
|
33585
33629
|
} else if (typeof audio === "string") {
|
|
33586
|
-
return
|
|
33630
|
+
return fs16__namespace.createReadStream(audio);
|
|
33587
33631
|
} else {
|
|
33588
33632
|
throw new Error("Invalid audio input: must be Buffer or file path");
|
|
33589
33633
|
}
|
|
@@ -33642,7 +33686,7 @@ var OpenAISTTProvider = class extends BaseMediaProvider {
|
|
|
33642
33686
|
* Handle OpenAI API errors
|
|
33643
33687
|
*/
|
|
33644
33688
|
handleError(error) {
|
|
33645
|
-
if (error instanceof
|
|
33689
|
+
if (error instanceof OpenAI3__default.default.APIError) {
|
|
33646
33690
|
const status = error.status;
|
|
33647
33691
|
const message = error.message || "Unknown OpenAI API error";
|
|
33648
33692
|
if (status === 401) {
|
|
@@ -34136,7 +34180,7 @@ var TextToSpeech = class _TextToSpeech {
|
|
|
34136
34180
|
*/
|
|
34137
34181
|
async toFile(text, filePath, options) {
|
|
34138
34182
|
const response = await this.synthesize(text, options);
|
|
34139
|
-
await
|
|
34183
|
+
await fs15__namespace.writeFile(filePath, response.audio);
|
|
34140
34184
|
}
|
|
34141
34185
|
// ======================== Introspection Methods ========================
|
|
34142
34186
|
/**
|
|
@@ -34484,7 +34528,7 @@ var SpeechToText = class _SpeechToText {
|
|
|
34484
34528
|
* @param options - Optional transcription parameters
|
|
34485
34529
|
*/
|
|
34486
34530
|
async transcribeFile(filePath, options) {
|
|
34487
|
-
const audio = await
|
|
34531
|
+
const audio = await fs15__namespace.readFile(filePath);
|
|
34488
34532
|
return this.transcribe(audio, options);
|
|
34489
34533
|
}
|
|
34490
34534
|
/**
|
|
@@ -34648,7 +34692,7 @@ var OpenAIImageProvider = class extends BaseMediaProvider {
|
|
|
34648
34692
|
client;
|
|
34649
34693
|
constructor(config) {
|
|
34650
34694
|
super({ apiKey: config.auth.apiKey, ...config });
|
|
34651
|
-
this.client = new
|
|
34695
|
+
this.client = new OpenAI3__default.default({
|
|
34652
34696
|
apiKey: config.auth.apiKey,
|
|
34653
34697
|
baseURL: config.baseURL,
|
|
34654
34698
|
organization: config.organization,
|
|
@@ -34810,7 +34854,7 @@ var OpenAIImageProvider = class extends BaseMediaProvider {
|
|
|
34810
34854
|
if (Buffer.isBuffer(image)) {
|
|
34811
34855
|
return new File([new Uint8Array(image)], "image.png", { type: "image/png" });
|
|
34812
34856
|
}
|
|
34813
|
-
return
|
|
34857
|
+
return fs16__namespace.createReadStream(image);
|
|
34814
34858
|
}
|
|
34815
34859
|
/**
|
|
34816
34860
|
* Handle OpenAI API errors
|
|
@@ -34957,8 +35001,8 @@ var GoogleImageProvider = class extends BaseMediaProvider {
|
|
|
34957
35001
|
if (Buffer.isBuffer(image)) {
|
|
34958
35002
|
imageBytes = image.toString("base64");
|
|
34959
35003
|
} else {
|
|
34960
|
-
const
|
|
34961
|
-
const buffer =
|
|
35004
|
+
const fs17 = await import('fs');
|
|
35005
|
+
const buffer = fs17.readFileSync(image);
|
|
34962
35006
|
imageBytes = buffer.toString("base64");
|
|
34963
35007
|
}
|
|
34964
35008
|
return {
|
|
@@ -35008,7 +35052,7 @@ var GrokImageProvider = class extends BaseMediaProvider {
|
|
|
35008
35052
|
client;
|
|
35009
35053
|
constructor(config) {
|
|
35010
35054
|
super({ apiKey: config.auth.apiKey, ...config });
|
|
35011
|
-
this.client = new
|
|
35055
|
+
this.client = new OpenAI3__default.default({
|
|
35012
35056
|
apiKey: config.auth.apiKey,
|
|
35013
35057
|
baseURL: config.baseURL || GROK_API_BASE_URL,
|
|
35014
35058
|
timeout: config.timeout,
|
|
@@ -35119,7 +35163,7 @@ var GrokImageProvider = class extends BaseMediaProvider {
|
|
|
35119
35163
|
if (Buffer.isBuffer(image)) {
|
|
35120
35164
|
return new File([new Uint8Array(image)], "image.png", { type: "image/png" });
|
|
35121
35165
|
}
|
|
35122
|
-
return
|
|
35166
|
+
return fs16__namespace.createReadStream(image);
|
|
35123
35167
|
}
|
|
35124
35168
|
/**
|
|
35125
35169
|
* Handle API errors
|
|
@@ -36321,7 +36365,7 @@ var OpenAISoraProvider = class extends BaseMediaProvider {
|
|
|
36321
36365
|
client;
|
|
36322
36366
|
constructor(config) {
|
|
36323
36367
|
super({ apiKey: config.auth.apiKey, ...config });
|
|
36324
|
-
this.client = new
|
|
36368
|
+
this.client = new OpenAI3__default.default({
|
|
36325
36369
|
apiKey: config.auth.apiKey,
|
|
36326
36370
|
baseURL: config.baseURL,
|
|
36327
36371
|
organization: config.organization,
|
|
@@ -36569,8 +36613,8 @@ var OpenAISoraProvider = class extends BaseMediaProvider {
|
|
|
36569
36613
|
return new File([new Uint8Array(image)], "input.png", { type: "image/png" });
|
|
36570
36614
|
}
|
|
36571
36615
|
if (!image.startsWith("http")) {
|
|
36572
|
-
const
|
|
36573
|
-
const data =
|
|
36616
|
+
const fs17 = await import('fs');
|
|
36617
|
+
const data = fs17.readFileSync(image);
|
|
36574
36618
|
return new File([new Uint8Array(data)], "input.png", { type: "image/png" });
|
|
36575
36619
|
}
|
|
36576
36620
|
const response = await fetch(image);
|
|
@@ -36748,7 +36792,7 @@ var GoogleVeoProvider = class extends BaseMediaProvider {
|
|
|
36748
36792
|
if (video.videoBytes) {
|
|
36749
36793
|
buffer = Buffer.from(video.videoBytes, "base64");
|
|
36750
36794
|
} else if (video.uri) {
|
|
36751
|
-
const
|
|
36795
|
+
const fs17 = await import('fs/promises');
|
|
36752
36796
|
const os3 = await import('os');
|
|
36753
36797
|
const path6 = await import('path');
|
|
36754
36798
|
const tempDir = os3.tmpdir();
|
|
@@ -36759,11 +36803,11 @@ var GoogleVeoProvider = class extends BaseMediaProvider {
|
|
|
36759
36803
|
// Pass as GeneratedVideo
|
|
36760
36804
|
downloadPath: tempFile
|
|
36761
36805
|
});
|
|
36762
|
-
buffer = await
|
|
36763
|
-
await
|
|
36806
|
+
buffer = await fs17.readFile(tempFile);
|
|
36807
|
+
await fs17.unlink(tempFile).catch(() => {
|
|
36764
36808
|
});
|
|
36765
36809
|
} catch (downloadError) {
|
|
36766
|
-
await
|
|
36810
|
+
await fs17.unlink(tempFile).catch(() => {
|
|
36767
36811
|
});
|
|
36768
36812
|
throw new ProviderError(
|
|
36769
36813
|
"google",
|
|
@@ -36885,8 +36929,8 @@ var GoogleVeoProvider = class extends BaseMediaProvider {
|
|
|
36885
36929
|
if (image.startsWith("http://") || image.startsWith("https://")) {
|
|
36886
36930
|
return { imageUri: image };
|
|
36887
36931
|
}
|
|
36888
|
-
const
|
|
36889
|
-
const data = await
|
|
36932
|
+
const fs17 = await import('fs/promises');
|
|
36933
|
+
const data = await fs17.readFile(image);
|
|
36890
36934
|
return {
|
|
36891
36935
|
imageBytes: data.toString("base64")
|
|
36892
36936
|
};
|
|
@@ -37193,8 +37237,8 @@ var GrokImagineProvider = class extends BaseMediaProvider {
|
|
|
37193
37237
|
if (image.startsWith("http") || image.startsWith("data:")) {
|
|
37194
37238
|
return image;
|
|
37195
37239
|
}
|
|
37196
|
-
const
|
|
37197
|
-
const data =
|
|
37240
|
+
const fs17 = await import('fs');
|
|
37241
|
+
const data = fs17.readFileSync(image);
|
|
37198
37242
|
const base64 = data.toString("base64");
|
|
37199
37243
|
const ext = image.split(".").pop()?.toLowerCase() || "png";
|
|
37200
37244
|
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext}`;
|
|
@@ -40399,10 +40443,10 @@ function getDefaultBaseDirectory2() {
|
|
|
40399
40443
|
if (platform2 === "win32") {
|
|
40400
40444
|
const appData = process.env.APPDATA || process.env.LOCALAPPDATA;
|
|
40401
40445
|
if (appData) {
|
|
40402
|
-
return
|
|
40446
|
+
return path2.join(appData, "oneringai", "agents");
|
|
40403
40447
|
}
|
|
40404
40448
|
}
|
|
40405
|
-
return
|
|
40449
|
+
return path2.join(os2.homedir(), ".oneringai", "agents");
|
|
40406
40450
|
}
|
|
40407
40451
|
function sanitizeId(id) {
|
|
40408
40452
|
return id.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase() || "default";
|
|
@@ -40419,8 +40463,8 @@ var FileContextStorage = class {
|
|
|
40419
40463
|
const sanitizedAgentId = sanitizeId(config.agentId);
|
|
40420
40464
|
const baseDir = config.baseDirectory ?? getDefaultBaseDirectory2();
|
|
40421
40465
|
this.prettyPrint = config.prettyPrint ?? true;
|
|
40422
|
-
this.sessionsDirectory =
|
|
40423
|
-
this.indexPath =
|
|
40466
|
+
this.sessionsDirectory = path2.join(baseDir, sanitizedAgentId, "sessions");
|
|
40467
|
+
this.indexPath = path2.join(this.sessionsDirectory, "_index.json");
|
|
40424
40468
|
}
|
|
40425
40469
|
/**
|
|
40426
40470
|
* Save context state to a session file
|
|
@@ -40446,11 +40490,11 @@ var FileContextStorage = class {
|
|
|
40446
40490
|
const data = this.prettyPrint ? JSON.stringify(storedSession, null, 2) : JSON.stringify(storedSession);
|
|
40447
40491
|
const tempPath = `${filePath}.tmp`;
|
|
40448
40492
|
try {
|
|
40449
|
-
await
|
|
40450
|
-
await
|
|
40493
|
+
await fs16.promises.writeFile(tempPath, data, "utf-8");
|
|
40494
|
+
await fs16.promises.rename(tempPath, filePath);
|
|
40451
40495
|
} catch (error) {
|
|
40452
40496
|
try {
|
|
40453
|
-
await
|
|
40497
|
+
await fs16.promises.unlink(tempPath);
|
|
40454
40498
|
} catch {
|
|
40455
40499
|
}
|
|
40456
40500
|
throw error;
|
|
@@ -40471,7 +40515,7 @@ var FileContextStorage = class {
|
|
|
40471
40515
|
const sanitizedSessionId = sanitizeId(sessionId);
|
|
40472
40516
|
const filePath = this.getFilePath(sanitizedSessionId);
|
|
40473
40517
|
try {
|
|
40474
|
-
await
|
|
40518
|
+
await fs16.promises.unlink(filePath);
|
|
40475
40519
|
} catch (error) {
|
|
40476
40520
|
if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
|
|
40477
40521
|
throw error;
|
|
@@ -40486,7 +40530,7 @@ var FileContextStorage = class {
|
|
|
40486
40530
|
const sanitizedSessionId = sanitizeId(sessionId);
|
|
40487
40531
|
const filePath = this.getFilePath(sanitizedSessionId);
|
|
40488
40532
|
try {
|
|
40489
|
-
await
|
|
40533
|
+
await fs16.promises.access(filePath);
|
|
40490
40534
|
return true;
|
|
40491
40535
|
} catch {
|
|
40492
40536
|
return false;
|
|
@@ -40551,7 +40595,7 @@ var FileContextStorage = class {
|
|
|
40551
40595
|
const sanitizedSessionId = sanitizeId(sessionId);
|
|
40552
40596
|
const filePath = this.getFilePath(sanitizedSessionId);
|
|
40553
40597
|
const data = this.prettyPrint ? JSON.stringify(stored, null, 2) : JSON.stringify(stored);
|
|
40554
|
-
await
|
|
40598
|
+
await fs16.promises.writeFile(filePath, data, "utf-8");
|
|
40555
40599
|
await this.updateIndex(stored);
|
|
40556
40600
|
}
|
|
40557
40601
|
/**
|
|
@@ -40572,13 +40616,13 @@ var FileContextStorage = class {
|
|
|
40572
40616
|
*/
|
|
40573
40617
|
async rebuildIndex() {
|
|
40574
40618
|
await this.ensureDirectory();
|
|
40575
|
-
const files = await
|
|
40619
|
+
const files = await fs16.promises.readdir(this.sessionsDirectory);
|
|
40576
40620
|
const sessionFiles = files.filter((f) => f.endsWith(".json") && !f.startsWith("_"));
|
|
40577
40621
|
const entries = [];
|
|
40578
40622
|
for (const file of sessionFiles) {
|
|
40579
40623
|
try {
|
|
40580
|
-
const filePath =
|
|
40581
|
-
const data = await
|
|
40624
|
+
const filePath = path2.join(this.sessionsDirectory, file);
|
|
40625
|
+
const data = await fs16.promises.readFile(filePath, "utf-8");
|
|
40582
40626
|
const stored = JSON.parse(data);
|
|
40583
40627
|
entries.push(this.storedToIndexEntry(stored));
|
|
40584
40628
|
} catch {
|
|
@@ -40596,11 +40640,11 @@ var FileContextStorage = class {
|
|
|
40596
40640
|
// Private Helpers
|
|
40597
40641
|
// ==========================================================================
|
|
40598
40642
|
getFilePath(sanitizedSessionId) {
|
|
40599
|
-
return
|
|
40643
|
+
return path2.join(this.sessionsDirectory, `${sanitizedSessionId}.json`);
|
|
40600
40644
|
}
|
|
40601
40645
|
async ensureDirectory() {
|
|
40602
40646
|
try {
|
|
40603
|
-
await
|
|
40647
|
+
await fs16.promises.mkdir(this.sessionsDirectory, { recursive: true });
|
|
40604
40648
|
} catch (error) {
|
|
40605
40649
|
if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
|
|
40606
40650
|
throw error;
|
|
@@ -40610,7 +40654,7 @@ var FileContextStorage = class {
|
|
|
40610
40654
|
async loadRaw(sanitizedSessionId) {
|
|
40611
40655
|
const filePath = this.getFilePath(sanitizedSessionId);
|
|
40612
40656
|
try {
|
|
40613
|
-
const data = await
|
|
40657
|
+
const data = await fs16.promises.readFile(filePath, "utf-8");
|
|
40614
40658
|
return JSON.parse(data);
|
|
40615
40659
|
} catch (error) {
|
|
40616
40660
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -40628,7 +40672,7 @@ var FileContextStorage = class {
|
|
|
40628
40672
|
return this.index;
|
|
40629
40673
|
}
|
|
40630
40674
|
try {
|
|
40631
|
-
const data = await
|
|
40675
|
+
const data = await fs16.promises.readFile(this.indexPath, "utf-8");
|
|
40632
40676
|
this.index = JSON.parse(data);
|
|
40633
40677
|
return this.index;
|
|
40634
40678
|
} catch (error) {
|
|
@@ -40649,7 +40693,7 @@ var FileContextStorage = class {
|
|
|
40649
40693
|
await this.ensureDirectory();
|
|
40650
40694
|
this.index.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
40651
40695
|
const data = this.prettyPrint ? JSON.stringify(this.index, null, 2) : JSON.stringify(this.index);
|
|
40652
|
-
await
|
|
40696
|
+
await fs16.promises.writeFile(this.indexPath, data, "utf-8");
|
|
40653
40697
|
}
|
|
40654
40698
|
async updateIndex(stored) {
|
|
40655
40699
|
const index = await this.loadIndex();
|
|
@@ -40687,10 +40731,10 @@ function getDefaultBaseDirectory3() {
|
|
|
40687
40731
|
if (platform2 === "win32") {
|
|
40688
40732
|
const appData = process.env.APPDATA || process.env.LOCALAPPDATA;
|
|
40689
40733
|
if (appData) {
|
|
40690
|
-
return
|
|
40734
|
+
return path2.join(appData, "oneringai", "agents");
|
|
40691
40735
|
}
|
|
40692
40736
|
}
|
|
40693
|
-
return
|
|
40737
|
+
return path2.join(os2.homedir(), ".oneringai", "agents");
|
|
40694
40738
|
}
|
|
40695
40739
|
function sanitizeAgentId2(agentId) {
|
|
40696
40740
|
return agentId.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase() || "default";
|
|
@@ -40703,15 +40747,15 @@ var FileAgentDefinitionStorage = class {
|
|
|
40703
40747
|
constructor(config = {}) {
|
|
40704
40748
|
this.baseDirectory = config.baseDirectory ?? getDefaultBaseDirectory3();
|
|
40705
40749
|
this.prettyPrint = config.prettyPrint ?? true;
|
|
40706
|
-
this.indexPath =
|
|
40750
|
+
this.indexPath = path2.join(this.baseDirectory, "_agents_index.json");
|
|
40707
40751
|
}
|
|
40708
40752
|
/**
|
|
40709
40753
|
* Save an agent definition
|
|
40710
40754
|
*/
|
|
40711
40755
|
async save(definition) {
|
|
40712
40756
|
const sanitizedId = sanitizeAgentId2(definition.agentId);
|
|
40713
|
-
const agentDir =
|
|
40714
|
-
const filePath =
|
|
40757
|
+
const agentDir = path2.join(this.baseDirectory, sanitizedId);
|
|
40758
|
+
const filePath = path2.join(agentDir, "definition.json");
|
|
40715
40759
|
await this.ensureDirectory(agentDir);
|
|
40716
40760
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
40717
40761
|
if (!definition.createdAt) {
|
|
@@ -40723,11 +40767,11 @@ var FileAgentDefinitionStorage = class {
|
|
|
40723
40767
|
const data = this.prettyPrint ? JSON.stringify(definition, null, 2) : JSON.stringify(definition);
|
|
40724
40768
|
const tempPath = `${filePath}.tmp`;
|
|
40725
40769
|
try {
|
|
40726
|
-
await
|
|
40727
|
-
await
|
|
40770
|
+
await fs16.promises.writeFile(tempPath, data, "utf-8");
|
|
40771
|
+
await fs16.promises.rename(tempPath, filePath);
|
|
40728
40772
|
} catch (error) {
|
|
40729
40773
|
try {
|
|
40730
|
-
await
|
|
40774
|
+
await fs16.promises.unlink(tempPath);
|
|
40731
40775
|
} catch {
|
|
40732
40776
|
}
|
|
40733
40777
|
throw error;
|
|
@@ -40746,10 +40790,10 @@ var FileAgentDefinitionStorage = class {
|
|
|
40746
40790
|
*/
|
|
40747
40791
|
async delete(agentId) {
|
|
40748
40792
|
const sanitizedId = sanitizeAgentId2(agentId);
|
|
40749
|
-
const agentDir =
|
|
40750
|
-
const filePath =
|
|
40793
|
+
const agentDir = path2.join(this.baseDirectory, sanitizedId);
|
|
40794
|
+
const filePath = path2.join(agentDir, "definition.json");
|
|
40751
40795
|
try {
|
|
40752
|
-
await
|
|
40796
|
+
await fs16.promises.unlink(filePath);
|
|
40753
40797
|
} catch (error) {
|
|
40754
40798
|
if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
|
|
40755
40799
|
throw error;
|
|
@@ -40762,9 +40806,9 @@ var FileAgentDefinitionStorage = class {
|
|
|
40762
40806
|
*/
|
|
40763
40807
|
async exists(agentId) {
|
|
40764
40808
|
const sanitizedId = sanitizeAgentId2(agentId);
|
|
40765
|
-
const filePath =
|
|
40809
|
+
const filePath = path2.join(this.baseDirectory, sanitizedId, "definition.json");
|
|
40766
40810
|
try {
|
|
40767
|
-
await
|
|
40811
|
+
await fs16.promises.access(filePath);
|
|
40768
40812
|
return true;
|
|
40769
40813
|
} catch {
|
|
40770
40814
|
return false;
|
|
@@ -40826,13 +40870,13 @@ var FileAgentDefinitionStorage = class {
|
|
|
40826
40870
|
*/
|
|
40827
40871
|
async rebuildIndex() {
|
|
40828
40872
|
await this.ensureDirectory(this.baseDirectory);
|
|
40829
|
-
const entries = await
|
|
40873
|
+
const entries = await fs16.promises.readdir(this.baseDirectory, { withFileTypes: true });
|
|
40830
40874
|
const agentDirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith("_"));
|
|
40831
40875
|
const indexEntries = [];
|
|
40832
40876
|
for (const dir of agentDirs) {
|
|
40833
40877
|
try {
|
|
40834
|
-
const filePath =
|
|
40835
|
-
const data = await
|
|
40878
|
+
const filePath = path2.join(this.baseDirectory, dir.name, "definition.json");
|
|
40879
|
+
const data = await fs16.promises.readFile(filePath, "utf-8");
|
|
40836
40880
|
const definition = JSON.parse(data);
|
|
40837
40881
|
indexEntries.push(this.definitionToIndexEntry(definition));
|
|
40838
40882
|
} catch {
|
|
@@ -40850,7 +40894,7 @@ var FileAgentDefinitionStorage = class {
|
|
|
40850
40894
|
// ==========================================================================
|
|
40851
40895
|
async ensureDirectory(dir) {
|
|
40852
40896
|
try {
|
|
40853
|
-
await
|
|
40897
|
+
await fs16.promises.mkdir(dir, { recursive: true });
|
|
40854
40898
|
} catch (error) {
|
|
40855
40899
|
if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
|
|
40856
40900
|
throw error;
|
|
@@ -40858,9 +40902,9 @@ var FileAgentDefinitionStorage = class {
|
|
|
40858
40902
|
}
|
|
40859
40903
|
}
|
|
40860
40904
|
async loadRaw(sanitizedId) {
|
|
40861
|
-
const filePath =
|
|
40905
|
+
const filePath = path2.join(this.baseDirectory, sanitizedId, "definition.json");
|
|
40862
40906
|
try {
|
|
40863
|
-
const data = await
|
|
40907
|
+
const data = await fs16.promises.readFile(filePath, "utf-8");
|
|
40864
40908
|
return JSON.parse(data);
|
|
40865
40909
|
} catch (error) {
|
|
40866
40910
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -40878,7 +40922,7 @@ var FileAgentDefinitionStorage = class {
|
|
|
40878
40922
|
return this.index;
|
|
40879
40923
|
}
|
|
40880
40924
|
try {
|
|
40881
|
-
const data = await
|
|
40925
|
+
const data = await fs16.promises.readFile(this.indexPath, "utf-8");
|
|
40882
40926
|
this.index = JSON.parse(data);
|
|
40883
40927
|
return this.index;
|
|
40884
40928
|
} catch (error) {
|
|
@@ -40898,7 +40942,7 @@ var FileAgentDefinitionStorage = class {
|
|
|
40898
40942
|
await this.ensureDirectory(this.baseDirectory);
|
|
40899
40943
|
this.index.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
40900
40944
|
const data = this.prettyPrint ? JSON.stringify(this.index, null, 2) : JSON.stringify(this.index);
|
|
40901
|
-
await
|
|
40945
|
+
await fs16.promises.writeFile(this.indexPath, data, "utf-8");
|
|
40902
40946
|
}
|
|
40903
40947
|
async updateIndex(definition) {
|
|
40904
40948
|
const index = await this.loadIndex();
|
|
@@ -40931,6 +40975,126 @@ var FileAgentDefinitionStorage = class {
|
|
|
40931
40975
|
function createFileAgentDefinitionStorage(config) {
|
|
40932
40976
|
return new FileAgentDefinitionStorage(config);
|
|
40933
40977
|
}
|
|
40978
|
+
var MIME_TYPES = {
|
|
40979
|
+
png: "image/png",
|
|
40980
|
+
jpeg: "image/jpeg",
|
|
40981
|
+
jpg: "image/jpeg",
|
|
40982
|
+
webp: "image/webp",
|
|
40983
|
+
gif: "image/gif",
|
|
40984
|
+
mp4: "video/mp4",
|
|
40985
|
+
webm: "video/webm",
|
|
40986
|
+
mp3: "audio/mpeg",
|
|
40987
|
+
wav: "audio/wav",
|
|
40988
|
+
opus: "audio/opus",
|
|
40989
|
+
ogg: "audio/ogg",
|
|
40990
|
+
aac: "audio/aac",
|
|
40991
|
+
flac: "audio/flac",
|
|
40992
|
+
pcm: "audio/pcm"
|
|
40993
|
+
};
|
|
40994
|
+
var MEDIA_TYPE_PREFIXES = ["image", "video", "audio"];
|
|
40995
|
+
var FileMediaStorage = class {
|
|
40996
|
+
outputDir;
|
|
40997
|
+
initialized = false;
|
|
40998
|
+
constructor(config) {
|
|
40999
|
+
this.outputDir = config?.outputDir ?? path2__namespace.join(os2__namespace.tmpdir(), "oneringai-media");
|
|
41000
|
+
}
|
|
41001
|
+
async save(data, metadata) {
|
|
41002
|
+
const dir = metadata.userId ? path2__namespace.join(this.outputDir, metadata.userId) : this.outputDir;
|
|
41003
|
+
await fs15__namespace.mkdir(dir, { recursive: true });
|
|
41004
|
+
const filename = metadata.suggestedFilename ?? this.generateFilename(metadata);
|
|
41005
|
+
const filePath = path2__namespace.join(dir, filename);
|
|
41006
|
+
await fs15__namespace.writeFile(filePath, data);
|
|
41007
|
+
const format = metadata.format.toLowerCase();
|
|
41008
|
+
const mimeType = MIME_TYPES[format] ?? "application/octet-stream";
|
|
41009
|
+
return {
|
|
41010
|
+
location: filePath,
|
|
41011
|
+
mimeType,
|
|
41012
|
+
size: data.length
|
|
41013
|
+
};
|
|
41014
|
+
}
|
|
41015
|
+
async read(location) {
|
|
41016
|
+
try {
|
|
41017
|
+
return await fs15__namespace.readFile(location);
|
|
41018
|
+
} catch (err) {
|
|
41019
|
+
if (err.code === "ENOENT") {
|
|
41020
|
+
return null;
|
|
41021
|
+
}
|
|
41022
|
+
throw err;
|
|
41023
|
+
}
|
|
41024
|
+
}
|
|
41025
|
+
async delete(location) {
|
|
41026
|
+
try {
|
|
41027
|
+
await fs15__namespace.unlink(location);
|
|
41028
|
+
} catch (err) {
|
|
41029
|
+
if (err.code === "ENOENT") {
|
|
41030
|
+
return;
|
|
41031
|
+
}
|
|
41032
|
+
throw err;
|
|
41033
|
+
}
|
|
41034
|
+
}
|
|
41035
|
+
async exists(location) {
|
|
41036
|
+
try {
|
|
41037
|
+
await fs15__namespace.access(location);
|
|
41038
|
+
return true;
|
|
41039
|
+
} catch {
|
|
41040
|
+
return false;
|
|
41041
|
+
}
|
|
41042
|
+
}
|
|
41043
|
+
async list(options) {
|
|
41044
|
+
await this.ensureDir();
|
|
41045
|
+
let entries = [];
|
|
41046
|
+
const files = await fs15__namespace.readdir(this.outputDir);
|
|
41047
|
+
for (const file of files) {
|
|
41048
|
+
const filePath = path2__namespace.join(this.outputDir, file);
|
|
41049
|
+
try {
|
|
41050
|
+
const stat6 = await fs15__namespace.stat(filePath);
|
|
41051
|
+
if (!stat6.isFile()) continue;
|
|
41052
|
+
const ext = path2__namespace.extname(file).slice(1).toLowerCase();
|
|
41053
|
+
const mimeType = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
41054
|
+
let type;
|
|
41055
|
+
for (const prefix of MEDIA_TYPE_PREFIXES) {
|
|
41056
|
+
if (file.startsWith(`${prefix}_`)) {
|
|
41057
|
+
type = prefix;
|
|
41058
|
+
break;
|
|
41059
|
+
}
|
|
41060
|
+
}
|
|
41061
|
+
entries.push({
|
|
41062
|
+
location: filePath,
|
|
41063
|
+
mimeType,
|
|
41064
|
+
size: stat6.size,
|
|
41065
|
+
type,
|
|
41066
|
+
createdAt: stat6.birthtime
|
|
41067
|
+
});
|
|
41068
|
+
} catch {
|
|
41069
|
+
}
|
|
41070
|
+
}
|
|
41071
|
+
if (options?.type) {
|
|
41072
|
+
entries = entries.filter((e) => e.type === options.type);
|
|
41073
|
+
}
|
|
41074
|
+
entries.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
41075
|
+
const offset = options?.offset ?? 0;
|
|
41076
|
+
const limit = options?.limit ?? entries.length;
|
|
41077
|
+
return entries.slice(offset, offset + limit);
|
|
41078
|
+
}
|
|
41079
|
+
getPath() {
|
|
41080
|
+
return this.outputDir;
|
|
41081
|
+
}
|
|
41082
|
+
generateFilename(metadata) {
|
|
41083
|
+
const timestamp = Date.now();
|
|
41084
|
+
const random2 = crypto2__namespace.randomBytes(4).toString("hex");
|
|
41085
|
+
const indexSuffix = metadata.index != null ? `_${metadata.index}` : "";
|
|
41086
|
+
return `${metadata.type}_${timestamp}_${random2}${indexSuffix}.${metadata.format}`;
|
|
41087
|
+
}
|
|
41088
|
+
async ensureDir() {
|
|
41089
|
+
if (!this.initialized) {
|
|
41090
|
+
await fs15__namespace.mkdir(this.outputDir, { recursive: true });
|
|
41091
|
+
this.initialized = true;
|
|
41092
|
+
}
|
|
41093
|
+
}
|
|
41094
|
+
};
|
|
41095
|
+
function createFileMediaStorage(config) {
|
|
41096
|
+
return new FileMediaStorage(config);
|
|
41097
|
+
}
|
|
40934
41098
|
|
|
40935
41099
|
// src/capabilities/agents/StreamHelpers.ts
|
|
40936
41100
|
var StreamHelpers = class {
|
|
@@ -41853,7 +42017,7 @@ var ConnectorTools = class {
|
|
|
41853
42017
|
static createGenericAPITool(connector, options) {
|
|
41854
42018
|
const toolName = options?.toolName ?? `${connector.name}_api`;
|
|
41855
42019
|
const userId = options?.userId;
|
|
41856
|
-
const description = options?.description ?? `Make an authenticated API call to ${connector.displayName}.` + (connector.baseURL ? ` Base URL: ${connector.baseURL}
|
|
42020
|
+
const description = options?.description ?? `Make an authenticated API call to ${connector.displayName}.` + (connector.baseURL ? ` Base URL: ${connector.baseURL}.` : " Provide full URL in endpoint.") + ' IMPORTANT: For POST/PUT/PATCH requests, pass data in the "body" parameter as a JSON object, NOT as query string parameters in the endpoint URL. The body is sent as application/json.';
|
|
41857
42021
|
return {
|
|
41858
42022
|
definition: {
|
|
41859
42023
|
type: "function",
|
|
@@ -41870,15 +42034,15 @@ var ConnectorTools = class {
|
|
|
41870
42034
|
},
|
|
41871
42035
|
endpoint: {
|
|
41872
42036
|
type: "string",
|
|
41873
|
-
description:
|
|
42037
|
+
description: 'API endpoint path (relative to base URL) or full URL. Do NOT put request data as query parameters here for POST/PUT/PATCH \u2014 use the "body" parameter instead.'
|
|
41874
42038
|
},
|
|
41875
42039
|
body: {
|
|
41876
42040
|
type: "object",
|
|
41877
|
-
description:
|
|
42041
|
+
description: 'JSON request body for POST/PUT/PATCH requests. ALWAYS use this for sending data (e.g., {"channel": "C123", "text": "hello"}) instead of query string parameters.'
|
|
41878
42042
|
},
|
|
41879
42043
|
queryParams: {
|
|
41880
42044
|
type: "object",
|
|
41881
|
-
description:
|
|
42045
|
+
description: 'URL query parameters (for filtering/pagination on GET requests). Do NOT use for POST/PUT/PATCH data \u2014 use "body" instead.'
|
|
41882
42046
|
},
|
|
41883
42047
|
headers: {
|
|
41884
42048
|
type: "object",
|
|
@@ -41943,7 +42107,10 @@ var ConnectorTools = class {
|
|
|
41943
42107
|
};
|
|
41944
42108
|
}
|
|
41945
42109
|
},
|
|
41946
|
-
describeCall: (args) =>
|
|
42110
|
+
describeCall: (args) => {
|
|
42111
|
+
const bodyInfo = args.body ? ` body=${JSON.stringify(args.body).slice(0, 100)}` : "";
|
|
42112
|
+
return `${args.method} ${args.endpoint}${bodyInfo}`;
|
|
42113
|
+
},
|
|
41947
42114
|
permission: options?.permission ?? {
|
|
41948
42115
|
scope: "session",
|
|
41949
42116
|
riskLevel: "medium",
|
|
@@ -41978,8 +42145,8 @@ var FileStorage = class {
|
|
|
41978
42145
|
}
|
|
41979
42146
|
async ensureDirectory() {
|
|
41980
42147
|
try {
|
|
41981
|
-
await
|
|
41982
|
-
await
|
|
42148
|
+
await fs15__namespace.mkdir(this.directory, { recursive: true });
|
|
42149
|
+
await fs15__namespace.chmod(this.directory, 448);
|
|
41983
42150
|
} catch (error) {
|
|
41984
42151
|
}
|
|
41985
42152
|
}
|
|
@@ -41988,20 +42155,20 @@ var FileStorage = class {
|
|
|
41988
42155
|
*/
|
|
41989
42156
|
getFilePath(key) {
|
|
41990
42157
|
const hash = crypto2__namespace.createHash("sha256").update(key).digest("hex");
|
|
41991
|
-
return
|
|
42158
|
+
return path2__namespace.join(this.directory, `${hash}.token`);
|
|
41992
42159
|
}
|
|
41993
42160
|
async storeToken(key, token) {
|
|
41994
42161
|
await this.ensureDirectory();
|
|
41995
42162
|
const filePath = this.getFilePath(key);
|
|
41996
42163
|
const plaintext = JSON.stringify(token);
|
|
41997
42164
|
const encrypted = encrypt(plaintext, this.encryptionKey);
|
|
41998
|
-
await
|
|
41999
|
-
await
|
|
42165
|
+
await fs15__namespace.writeFile(filePath, encrypted, "utf8");
|
|
42166
|
+
await fs15__namespace.chmod(filePath, 384);
|
|
42000
42167
|
}
|
|
42001
42168
|
async getToken(key) {
|
|
42002
42169
|
const filePath = this.getFilePath(key);
|
|
42003
42170
|
try {
|
|
42004
|
-
const encrypted = await
|
|
42171
|
+
const encrypted = await fs15__namespace.readFile(filePath, "utf8");
|
|
42005
42172
|
const decrypted = decrypt(encrypted, this.encryptionKey);
|
|
42006
42173
|
return JSON.parse(decrypted);
|
|
42007
42174
|
} catch (error) {
|
|
@@ -42010,7 +42177,7 @@ var FileStorage = class {
|
|
|
42010
42177
|
}
|
|
42011
42178
|
console.error("Failed to read/decrypt token file:", error);
|
|
42012
42179
|
try {
|
|
42013
|
-
await
|
|
42180
|
+
await fs15__namespace.unlink(filePath);
|
|
42014
42181
|
} catch {
|
|
42015
42182
|
}
|
|
42016
42183
|
return null;
|
|
@@ -42019,7 +42186,7 @@ var FileStorage = class {
|
|
|
42019
42186
|
async deleteToken(key) {
|
|
42020
42187
|
const filePath = this.getFilePath(key);
|
|
42021
42188
|
try {
|
|
42022
|
-
await
|
|
42189
|
+
await fs15__namespace.unlink(filePath);
|
|
42023
42190
|
} catch (error) {
|
|
42024
42191
|
if (error.code !== "ENOENT") {
|
|
42025
42192
|
throw error;
|
|
@@ -42029,7 +42196,7 @@ var FileStorage = class {
|
|
|
42029
42196
|
async hasToken(key) {
|
|
42030
42197
|
const filePath = this.getFilePath(key);
|
|
42031
42198
|
try {
|
|
42032
|
-
await
|
|
42199
|
+
await fs15__namespace.access(filePath);
|
|
42033
42200
|
return true;
|
|
42034
42201
|
} catch {
|
|
42035
42202
|
return false;
|
|
@@ -42040,7 +42207,7 @@ var FileStorage = class {
|
|
|
42040
42207
|
*/
|
|
42041
42208
|
async listTokens() {
|
|
42042
42209
|
try {
|
|
42043
|
-
const files = await
|
|
42210
|
+
const files = await fs15__namespace.readdir(this.directory);
|
|
42044
42211
|
return files.filter((f) => f.endsWith(".token")).map((f) => f.replace(".token", ""));
|
|
42045
42212
|
} catch {
|
|
42046
42213
|
return [];
|
|
@@ -42051,10 +42218,10 @@ var FileStorage = class {
|
|
|
42051
42218
|
*/
|
|
42052
42219
|
async clearAll() {
|
|
42053
42220
|
try {
|
|
42054
|
-
const files = await
|
|
42221
|
+
const files = await fs15__namespace.readdir(this.directory);
|
|
42055
42222
|
const tokenFiles = files.filter((f) => f.endsWith(".token"));
|
|
42056
42223
|
await Promise.all(
|
|
42057
|
-
tokenFiles.map((f) =>
|
|
42224
|
+
tokenFiles.map((f) => fs15__namespace.unlink(path2__namespace.join(this.directory, f)).catch(() => {
|
|
42058
42225
|
}))
|
|
42059
42226
|
);
|
|
42060
42227
|
} catch {
|
|
@@ -42322,22 +42489,26 @@ var ConnectorConfigStore = class {
|
|
|
42322
42489
|
* Encrypt secrets in ConnectorAuth based on auth type
|
|
42323
42490
|
*/
|
|
42324
42491
|
encryptAuthSecrets(auth2) {
|
|
42492
|
+
const encryptedExtra = this.encryptExtra(auth2.extra);
|
|
42325
42493
|
switch (auth2.type) {
|
|
42326
42494
|
case "api_key":
|
|
42327
42495
|
return {
|
|
42328
42496
|
...auth2,
|
|
42329
|
-
apiKey: this.encryptValue(auth2.apiKey)
|
|
42497
|
+
apiKey: this.encryptValue(auth2.apiKey),
|
|
42498
|
+
...encryptedExtra ? { extra: encryptedExtra } : {}
|
|
42330
42499
|
};
|
|
42331
42500
|
case "oauth":
|
|
42332
42501
|
return {
|
|
42333
42502
|
...auth2,
|
|
42334
42503
|
clientSecret: auth2.clientSecret ? this.encryptValue(auth2.clientSecret) : void 0,
|
|
42335
|
-
privateKey: auth2.privateKey ? this.encryptValue(auth2.privateKey) : void 0
|
|
42504
|
+
privateKey: auth2.privateKey ? this.encryptValue(auth2.privateKey) : void 0,
|
|
42505
|
+
...encryptedExtra ? { extra: encryptedExtra } : {}
|
|
42336
42506
|
};
|
|
42337
42507
|
case "jwt":
|
|
42338
42508
|
return {
|
|
42339
42509
|
...auth2,
|
|
42340
|
-
privateKey: this.encryptValue(auth2.privateKey)
|
|
42510
|
+
privateKey: this.encryptValue(auth2.privateKey),
|
|
42511
|
+
...encryptedExtra ? { extra: encryptedExtra } : {}
|
|
42341
42512
|
};
|
|
42342
42513
|
default:
|
|
42343
42514
|
return auth2;
|
|
@@ -42347,27 +42518,53 @@ var ConnectorConfigStore = class {
|
|
|
42347
42518
|
* Decrypt secrets in ConnectorAuth based on auth type
|
|
42348
42519
|
*/
|
|
42349
42520
|
decryptAuthSecrets(auth2) {
|
|
42521
|
+
const decryptedExtra = this.decryptExtra(auth2.extra);
|
|
42350
42522
|
switch (auth2.type) {
|
|
42351
42523
|
case "api_key":
|
|
42352
42524
|
return {
|
|
42353
42525
|
...auth2,
|
|
42354
|
-
apiKey: this.decryptValue(auth2.apiKey)
|
|
42526
|
+
apiKey: this.decryptValue(auth2.apiKey),
|
|
42527
|
+
...decryptedExtra ? { extra: decryptedExtra } : {}
|
|
42355
42528
|
};
|
|
42356
42529
|
case "oauth":
|
|
42357
42530
|
return {
|
|
42358
42531
|
...auth2,
|
|
42359
42532
|
clientSecret: auth2.clientSecret ? this.decryptValue(auth2.clientSecret) : void 0,
|
|
42360
|
-
privateKey: auth2.privateKey ? this.decryptValue(auth2.privateKey) : void 0
|
|
42533
|
+
privateKey: auth2.privateKey ? this.decryptValue(auth2.privateKey) : void 0,
|
|
42534
|
+
...decryptedExtra ? { extra: decryptedExtra } : {}
|
|
42361
42535
|
};
|
|
42362
42536
|
case "jwt":
|
|
42363
42537
|
return {
|
|
42364
42538
|
...auth2,
|
|
42365
|
-
privateKey: this.decryptValue(auth2.privateKey)
|
|
42539
|
+
privateKey: this.decryptValue(auth2.privateKey),
|
|
42540
|
+
...decryptedExtra ? { extra: decryptedExtra } : {}
|
|
42366
42541
|
};
|
|
42367
42542
|
default:
|
|
42368
42543
|
return auth2;
|
|
42369
42544
|
}
|
|
42370
42545
|
}
|
|
42546
|
+
/**
|
|
42547
|
+
* Encrypt all values in an extra Record (vendor-specific credentials)
|
|
42548
|
+
*/
|
|
42549
|
+
encryptExtra(extra) {
|
|
42550
|
+
if (!extra || Object.keys(extra).length === 0) return void 0;
|
|
42551
|
+
const result = {};
|
|
42552
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
42553
|
+
result[key] = this.encryptValue(value);
|
|
42554
|
+
}
|
|
42555
|
+
return result;
|
|
42556
|
+
}
|
|
42557
|
+
/**
|
|
42558
|
+
* Decrypt all values in an extra Record (vendor-specific credentials)
|
|
42559
|
+
*/
|
|
42560
|
+
decryptExtra(extra) {
|
|
42561
|
+
if (!extra || Object.keys(extra).length === 0) return void 0;
|
|
42562
|
+
const result = {};
|
|
42563
|
+
for (const [key, value] of Object.entries(extra)) {
|
|
42564
|
+
result[key] = this.decryptValue(value);
|
|
42565
|
+
}
|
|
42566
|
+
return result;
|
|
42567
|
+
}
|
|
42371
42568
|
/**
|
|
42372
42569
|
* Encrypt a single value if not already encrypted
|
|
42373
42570
|
*/
|
|
@@ -42445,20 +42642,20 @@ var FileConnectorStorage = class {
|
|
|
42445
42642
|
throw new Error("FileConnectorStorage requires a directory path");
|
|
42446
42643
|
}
|
|
42447
42644
|
this.directory = config.directory;
|
|
42448
|
-
this.indexPath =
|
|
42645
|
+
this.indexPath = path2__namespace.join(this.directory, "_index.json");
|
|
42449
42646
|
}
|
|
42450
42647
|
async save(name, stored) {
|
|
42451
42648
|
await this.ensureDirectory();
|
|
42452
42649
|
const filePath = this.getFilePath(name);
|
|
42453
42650
|
const json = JSON.stringify(stored, null, 2);
|
|
42454
|
-
await
|
|
42455
|
-
await
|
|
42651
|
+
await fs15__namespace.writeFile(filePath, json, "utf8");
|
|
42652
|
+
await fs15__namespace.chmod(filePath, 384);
|
|
42456
42653
|
await this.updateIndex(name, "add");
|
|
42457
42654
|
}
|
|
42458
42655
|
async get(name) {
|
|
42459
42656
|
const filePath = this.getFilePath(name);
|
|
42460
42657
|
try {
|
|
42461
|
-
const json = await
|
|
42658
|
+
const json = await fs15__namespace.readFile(filePath, "utf8");
|
|
42462
42659
|
return JSON.parse(json);
|
|
42463
42660
|
} catch (error) {
|
|
42464
42661
|
const err = error;
|
|
@@ -42471,7 +42668,7 @@ var FileConnectorStorage = class {
|
|
|
42471
42668
|
async delete(name) {
|
|
42472
42669
|
const filePath = this.getFilePath(name);
|
|
42473
42670
|
try {
|
|
42474
|
-
await
|
|
42671
|
+
await fs15__namespace.unlink(filePath);
|
|
42475
42672
|
await this.updateIndex(name, "remove");
|
|
42476
42673
|
return true;
|
|
42477
42674
|
} catch (error) {
|
|
@@ -42485,7 +42682,7 @@ var FileConnectorStorage = class {
|
|
|
42485
42682
|
async has(name) {
|
|
42486
42683
|
const filePath = this.getFilePath(name);
|
|
42487
42684
|
try {
|
|
42488
|
-
await
|
|
42685
|
+
await fs15__namespace.access(filePath);
|
|
42489
42686
|
return true;
|
|
42490
42687
|
} catch {
|
|
42491
42688
|
return false;
|
|
@@ -42511,13 +42708,13 @@ var FileConnectorStorage = class {
|
|
|
42511
42708
|
*/
|
|
42512
42709
|
async clear() {
|
|
42513
42710
|
try {
|
|
42514
|
-
const files = await
|
|
42711
|
+
const files = await fs15__namespace.readdir(this.directory);
|
|
42515
42712
|
const connectorFiles = files.filter(
|
|
42516
42713
|
(f) => f.endsWith(".connector.json") || f === "_index.json"
|
|
42517
42714
|
);
|
|
42518
42715
|
await Promise.all(
|
|
42519
42716
|
connectorFiles.map(
|
|
42520
|
-
(f) =>
|
|
42717
|
+
(f) => fs15__namespace.unlink(path2__namespace.join(this.directory, f)).catch(() => {
|
|
42521
42718
|
})
|
|
42522
42719
|
)
|
|
42523
42720
|
);
|
|
@@ -42530,7 +42727,7 @@ var FileConnectorStorage = class {
|
|
|
42530
42727
|
*/
|
|
42531
42728
|
getFilePath(name) {
|
|
42532
42729
|
const hash = this.hashName(name);
|
|
42533
|
-
return
|
|
42730
|
+
return path2__namespace.join(this.directory, `${hash}.connector.json`);
|
|
42534
42731
|
}
|
|
42535
42732
|
/**
|
|
42536
42733
|
* Hash connector name to prevent enumeration
|
|
@@ -42544,8 +42741,8 @@ var FileConnectorStorage = class {
|
|
|
42544
42741
|
async ensureDirectory() {
|
|
42545
42742
|
if (this.initialized) return;
|
|
42546
42743
|
try {
|
|
42547
|
-
await
|
|
42548
|
-
await
|
|
42744
|
+
await fs15__namespace.mkdir(this.directory, { recursive: true });
|
|
42745
|
+
await fs15__namespace.chmod(this.directory, 448);
|
|
42549
42746
|
this.initialized = true;
|
|
42550
42747
|
} catch {
|
|
42551
42748
|
this.initialized = true;
|
|
@@ -42556,7 +42753,7 @@ var FileConnectorStorage = class {
|
|
|
42556
42753
|
*/
|
|
42557
42754
|
async loadIndex() {
|
|
42558
42755
|
try {
|
|
42559
|
-
const json = await
|
|
42756
|
+
const json = await fs15__namespace.readFile(this.indexPath, "utf8");
|
|
42560
42757
|
return JSON.parse(json);
|
|
42561
42758
|
} catch {
|
|
42562
42759
|
return { connectors: {} };
|
|
@@ -42574,8 +42771,8 @@ var FileConnectorStorage = class {
|
|
|
42574
42771
|
delete index.connectors[hash];
|
|
42575
42772
|
}
|
|
42576
42773
|
const json = JSON.stringify(index, null, 2);
|
|
42577
|
-
await
|
|
42578
|
-
await
|
|
42774
|
+
await fs15__namespace.writeFile(this.indexPath, json, "utf8");
|
|
42775
|
+
await fs15__namespace.chmod(this.indexPath, 384);
|
|
42579
42776
|
}
|
|
42580
42777
|
};
|
|
42581
42778
|
|
|
@@ -42620,11 +42817,19 @@ function buildAuthConfig(authTemplate, credentials) {
|
|
|
42620
42817
|
if (!credentials.apiKey) {
|
|
42621
42818
|
throw new Error("API key is required for api_key auth");
|
|
42622
42819
|
}
|
|
42820
|
+
const standardApiKeyFields = /* @__PURE__ */ new Set(["apiKey", "headerName", "headerPrefix"]);
|
|
42821
|
+
const extra = {};
|
|
42822
|
+
for (const field of authTemplate.optionalFields ?? []) {
|
|
42823
|
+
if (!standardApiKeyFields.has(field) && credentials[field]) {
|
|
42824
|
+
extra[field] = credentials[field];
|
|
42825
|
+
}
|
|
42826
|
+
}
|
|
42623
42827
|
return {
|
|
42624
42828
|
type: "api_key",
|
|
42625
42829
|
apiKey: credentials.apiKey,
|
|
42626
42830
|
headerName: defaults.headerName ?? "Authorization",
|
|
42627
|
-
headerPrefix: defaults.headerPrefix ?? "Bearer"
|
|
42831
|
+
headerPrefix: defaults.headerPrefix ?? "Bearer",
|
|
42832
|
+
...Object.keys(extra).length > 0 ? { extra } : {}
|
|
42628
42833
|
};
|
|
42629
42834
|
}
|
|
42630
42835
|
if (!authTemplate.flow) {
|
|
@@ -42894,8 +43099,9 @@ var slackTemplate = {
|
|
|
42894
43099
|
id: "bot-token",
|
|
42895
43100
|
name: "Bot Token",
|
|
42896
43101
|
type: "api_key",
|
|
42897
|
-
description: "Internal workspace bot - get from OAuth & Permissions page of your Slack app",
|
|
43102
|
+
description: "Internal workspace bot - get from OAuth & Permissions page of your Slack app. For Socket Mode bots, also provide appToken and signingSecret in extra fields.",
|
|
42898
43103
|
requiredFields: ["apiKey"],
|
|
43104
|
+
optionalFields: ["appToken", "signingSecret"],
|
|
42899
43105
|
defaults: {
|
|
42900
43106
|
type: "api_key",
|
|
42901
43107
|
headerName: "Authorization",
|
|
@@ -44733,14 +44939,14 @@ function createMessageWithImages(text, imageUrls, role = "user" /* USER */) {
|
|
|
44733
44939
|
var execAsync = util.promisify(child_process.exec);
|
|
44734
44940
|
function cleanupTempFile(filePath) {
|
|
44735
44941
|
try {
|
|
44736
|
-
if (
|
|
44737
|
-
|
|
44942
|
+
if (fs16__namespace.existsSync(filePath)) {
|
|
44943
|
+
fs16__namespace.unlinkSync(filePath);
|
|
44738
44944
|
}
|
|
44739
44945
|
} catch {
|
|
44740
44946
|
}
|
|
44741
44947
|
}
|
|
44742
44948
|
async function readClipboardImage() {
|
|
44743
|
-
const platform2 =
|
|
44949
|
+
const platform2 = os2__namespace.platform();
|
|
44744
44950
|
try {
|
|
44745
44951
|
switch (platform2) {
|
|
44746
44952
|
case "darwin":
|
|
@@ -44763,7 +44969,7 @@ async function readClipboardImage() {
|
|
|
44763
44969
|
}
|
|
44764
44970
|
}
|
|
44765
44971
|
async function readClipboardImageMac() {
|
|
44766
|
-
const tempFile =
|
|
44972
|
+
const tempFile = path2__namespace.join(os2__namespace.tmpdir(), `clipboard-${Date.now()}.png`);
|
|
44767
44973
|
try {
|
|
44768
44974
|
try {
|
|
44769
44975
|
await execAsync(`pngpaste "${tempFile}"`);
|
|
@@ -44785,7 +44991,7 @@ async function readClipboardImageMac() {
|
|
|
44785
44991
|
end try
|
|
44786
44992
|
`;
|
|
44787
44993
|
const { stdout } = await execAsync(`osascript -e '${script}'`);
|
|
44788
|
-
if (stdout.includes("success") ||
|
|
44994
|
+
if (stdout.includes("success") || fs16__namespace.existsSync(tempFile)) {
|
|
44789
44995
|
return await convertFileToDataUri(tempFile);
|
|
44790
44996
|
}
|
|
44791
44997
|
return {
|
|
@@ -44798,18 +45004,18 @@ async function readClipboardImageMac() {
|
|
|
44798
45004
|
}
|
|
44799
45005
|
}
|
|
44800
45006
|
async function readClipboardImageLinux() {
|
|
44801
|
-
const tempFile =
|
|
45007
|
+
const tempFile = path2__namespace.join(os2__namespace.tmpdir(), `clipboard-${Date.now()}.png`);
|
|
44802
45008
|
try {
|
|
44803
45009
|
try {
|
|
44804
45010
|
await execAsync(`xclip -selection clipboard -t image/png -o > "${tempFile}"`);
|
|
44805
|
-
if (
|
|
45011
|
+
if (fs16__namespace.existsSync(tempFile) && fs16__namespace.statSync(tempFile).size > 0) {
|
|
44806
45012
|
return await convertFileToDataUri(tempFile);
|
|
44807
45013
|
}
|
|
44808
45014
|
} catch {
|
|
44809
45015
|
}
|
|
44810
45016
|
try {
|
|
44811
45017
|
await execAsync(`wl-paste -t image/png > "${tempFile}"`);
|
|
44812
|
-
if (
|
|
45018
|
+
if (fs16__namespace.existsSync(tempFile) && fs16__namespace.statSync(tempFile).size > 0) {
|
|
44813
45019
|
return await convertFileToDataUri(tempFile);
|
|
44814
45020
|
}
|
|
44815
45021
|
} catch {
|
|
@@ -44823,7 +45029,7 @@ async function readClipboardImageLinux() {
|
|
|
44823
45029
|
}
|
|
44824
45030
|
}
|
|
44825
45031
|
async function readClipboardImageWindows() {
|
|
44826
|
-
const tempFile =
|
|
45032
|
+
const tempFile = path2__namespace.join(os2__namespace.tmpdir(), `clipboard-${Date.now()}.png`);
|
|
44827
45033
|
try {
|
|
44828
45034
|
const psScript = `
|
|
44829
45035
|
Add-Type -AssemblyName System.Windows.Forms;
|
|
@@ -44836,7 +45042,7 @@ async function readClipboardImageWindows() {
|
|
|
44836
45042
|
}
|
|
44837
45043
|
`;
|
|
44838
45044
|
await execAsync(`powershell -Command "${psScript}"`);
|
|
44839
|
-
if (
|
|
45045
|
+
if (fs16__namespace.existsSync(tempFile) && fs16__namespace.statSync(tempFile).size > 0) {
|
|
44840
45046
|
return await convertFileToDataUri(tempFile);
|
|
44841
45047
|
}
|
|
44842
45048
|
return {
|
|
@@ -44849,7 +45055,7 @@ async function readClipboardImageWindows() {
|
|
|
44849
45055
|
}
|
|
44850
45056
|
async function convertFileToDataUri(filePath) {
|
|
44851
45057
|
try {
|
|
44852
|
-
const imageBuffer =
|
|
45058
|
+
const imageBuffer = fs16__namespace.readFileSync(filePath);
|
|
44853
45059
|
const base64Image = imageBuffer.toString("base64");
|
|
44854
45060
|
const magic = imageBuffer.slice(0, 4).toString("hex");
|
|
44855
45061
|
let mimeType = "image/png";
|
|
@@ -44876,7 +45082,7 @@ async function convertFileToDataUri(filePath) {
|
|
|
44876
45082
|
}
|
|
44877
45083
|
}
|
|
44878
45084
|
async function hasClipboardImage() {
|
|
44879
|
-
const platform2 =
|
|
45085
|
+
const platform2 = os2__namespace.platform();
|
|
44880
45086
|
try {
|
|
44881
45087
|
switch (platform2) {
|
|
44882
45088
|
case "darwin":
|
|
@@ -45094,17 +45300,24 @@ __export(tools_exports, {
|
|
|
45094
45300
|
ConnectorTools: () => ConnectorTools,
|
|
45095
45301
|
DEFAULT_FILESYSTEM_CONFIG: () => DEFAULT_FILESYSTEM_CONFIG,
|
|
45096
45302
|
DEFAULT_SHELL_CONFIG: () => DEFAULT_SHELL_CONFIG,
|
|
45097
|
-
FileMediaOutputHandler: () =>
|
|
45303
|
+
FileMediaOutputHandler: () => FileMediaStorage,
|
|
45098
45304
|
ToolRegistry: () => ToolRegistry,
|
|
45099
45305
|
bash: () => bash,
|
|
45100
45306
|
createBashTool: () => createBashTool,
|
|
45307
|
+
createCreatePRTool: () => createCreatePRTool,
|
|
45101
45308
|
createEditFileTool: () => createEditFileTool,
|
|
45102
45309
|
createExecuteJavaScriptTool: () => createExecuteJavaScriptTool,
|
|
45310
|
+
createGetPRTool: () => createGetPRTool,
|
|
45311
|
+
createGitHubReadFileTool: () => createGitHubReadFileTool,
|
|
45103
45312
|
createGlobTool: () => createGlobTool,
|
|
45104
45313
|
createGrepTool: () => createGrepTool,
|
|
45105
45314
|
createImageGenerationTool: () => createImageGenerationTool,
|
|
45106
45315
|
createListDirectoryTool: () => createListDirectoryTool,
|
|
45316
|
+
createPRCommentsTool: () => createPRCommentsTool,
|
|
45317
|
+
createPRFilesTool: () => createPRFilesTool,
|
|
45107
45318
|
createReadFileTool: () => createReadFileTool,
|
|
45319
|
+
createSearchCodeTool: () => createSearchCodeTool,
|
|
45320
|
+
createSearchFilesTool: () => createSearchFilesTool,
|
|
45108
45321
|
createSpeechToTextTool: () => createSpeechToTextTool,
|
|
45109
45322
|
createTextToSpeechTool: () => createTextToSpeechTool,
|
|
45110
45323
|
createVideoTools: () => createVideoTools,
|
|
@@ -45116,6 +45329,7 @@ __export(tools_exports, {
|
|
|
45116
45329
|
getAllBuiltInTools: () => getAllBuiltInTools,
|
|
45117
45330
|
getBackgroundOutput: () => getBackgroundOutput,
|
|
45118
45331
|
getMediaOutputHandler: () => getMediaOutputHandler,
|
|
45332
|
+
getMediaStorage: () => getMediaStorage,
|
|
45119
45333
|
getToolByName: () => getToolByName,
|
|
45120
45334
|
getToolCategories: () => getToolCategories,
|
|
45121
45335
|
getToolRegistry: () => getToolRegistry,
|
|
@@ -45128,15 +45342,18 @@ __export(tools_exports, {
|
|
|
45128
45342
|
jsonManipulator: () => jsonManipulator,
|
|
45129
45343
|
killBackgroundProcess: () => killBackgroundProcess,
|
|
45130
45344
|
listDirectory: () => listDirectory,
|
|
45131
|
-
|
|
45345
|
+
parseRepository: () => parseRepository,
|
|
45346
|
+
readFile: () => readFile5,
|
|
45347
|
+
resolveRepository: () => resolveRepository,
|
|
45132
45348
|
setMediaOutputHandler: () => setMediaOutputHandler,
|
|
45349
|
+
setMediaStorage: () => setMediaStorage,
|
|
45133
45350
|
toolRegistry: () => toolRegistry,
|
|
45134
45351
|
validatePath: () => validatePath,
|
|
45135
45352
|
webFetch: () => webFetch,
|
|
45136
45353
|
webFetchJS: () => webFetchJS,
|
|
45137
45354
|
webScrape: () => webScrape,
|
|
45138
45355
|
webSearch: () => webSearch,
|
|
45139
|
-
writeFile: () =>
|
|
45356
|
+
writeFile: () => writeFile5
|
|
45140
45357
|
});
|
|
45141
45358
|
var DEFAULT_FILESYSTEM_CONFIG = {
|
|
45142
45359
|
workingDirectory: process.cwd(),
|
|
@@ -45195,15 +45412,15 @@ function validatePath(inputPath, config = {}) {
|
|
|
45195
45412
|
const blockedDirs = config.blockedDirectories || DEFAULT_FILESYSTEM_CONFIG.blockedDirectories;
|
|
45196
45413
|
let expandedPath = inputPath;
|
|
45197
45414
|
if (inputPath.startsWith("~/")) {
|
|
45198
|
-
expandedPath =
|
|
45415
|
+
expandedPath = path2.resolve(os2.homedir(), inputPath.slice(2));
|
|
45199
45416
|
} else if (inputPath === "~") {
|
|
45200
|
-
expandedPath =
|
|
45417
|
+
expandedPath = os2.homedir();
|
|
45201
45418
|
}
|
|
45202
45419
|
let resolvedPath;
|
|
45203
|
-
if (
|
|
45204
|
-
resolvedPath =
|
|
45420
|
+
if (path2.isAbsolute(expandedPath)) {
|
|
45421
|
+
resolvedPath = path2.normalize(expandedPath);
|
|
45205
45422
|
} else {
|
|
45206
|
-
resolvedPath =
|
|
45423
|
+
resolvedPath = path2.resolve(workingDir, expandedPath);
|
|
45207
45424
|
}
|
|
45208
45425
|
const pathSegments = resolvedPath.split("/").filter(Boolean);
|
|
45209
45426
|
for (const blocked of blockedDirs) {
|
|
@@ -45216,7 +45433,7 @@ function validatePath(inputPath, config = {}) {
|
|
|
45216
45433
|
};
|
|
45217
45434
|
}
|
|
45218
45435
|
} else {
|
|
45219
|
-
const blockedPath =
|
|
45436
|
+
const blockedPath = path2.isAbsolute(blocked) ? blocked : path2.resolve(workingDir, blocked);
|
|
45220
45437
|
if (resolvedPath.startsWith(blockedPath + "/") || resolvedPath === blockedPath) {
|
|
45221
45438
|
return {
|
|
45222
45439
|
valid: false,
|
|
@@ -45229,7 +45446,7 @@ function validatePath(inputPath, config = {}) {
|
|
|
45229
45446
|
if (allowedDirs.length > 0) {
|
|
45230
45447
|
let isAllowed = false;
|
|
45231
45448
|
for (const allowed of allowedDirs) {
|
|
45232
|
-
const allowedPath =
|
|
45449
|
+
const allowedPath = path2.isAbsolute(allowed) ? allowed : path2.resolve(workingDir, allowed);
|
|
45233
45450
|
if (resolvedPath.startsWith(allowedPath + "/") || resolvedPath === allowedPath) {
|
|
45234
45451
|
isAllowed = true;
|
|
45235
45452
|
break;
|
|
@@ -45247,9 +45464,9 @@ function validatePath(inputPath, config = {}) {
|
|
|
45247
45464
|
}
|
|
45248
45465
|
function expandTilde(inputPath) {
|
|
45249
45466
|
if (inputPath.startsWith("~/")) {
|
|
45250
|
-
return
|
|
45467
|
+
return path2.resolve(os2.homedir(), inputPath.slice(2));
|
|
45251
45468
|
} else if (inputPath === "~") {
|
|
45252
|
-
return
|
|
45469
|
+
return os2.homedir();
|
|
45253
45470
|
}
|
|
45254
45471
|
return inputPath;
|
|
45255
45472
|
}
|
|
@@ -45324,7 +45541,7 @@ EXAMPLES:
|
|
|
45324
45541
|
};
|
|
45325
45542
|
}
|
|
45326
45543
|
const resolvedPath = validation.resolvedPath;
|
|
45327
|
-
if (!
|
|
45544
|
+
if (!fs16.existsSync(resolvedPath)) {
|
|
45328
45545
|
return {
|
|
45329
45546
|
success: false,
|
|
45330
45547
|
error: `File not found: ${file_path}`,
|
|
@@ -45332,7 +45549,7 @@ EXAMPLES:
|
|
|
45332
45549
|
};
|
|
45333
45550
|
}
|
|
45334
45551
|
try {
|
|
45335
|
-
const stats = await
|
|
45552
|
+
const stats = await fs15.stat(resolvedPath);
|
|
45336
45553
|
if (!stats.isFile()) {
|
|
45337
45554
|
return {
|
|
45338
45555
|
success: false,
|
|
@@ -45348,7 +45565,7 @@ EXAMPLES:
|
|
|
45348
45565
|
size: stats.size
|
|
45349
45566
|
};
|
|
45350
45567
|
}
|
|
45351
|
-
const content = await
|
|
45568
|
+
const content = await fs15.readFile(resolvedPath, "utf-8");
|
|
45352
45569
|
const allLines = content.split("\n");
|
|
45353
45570
|
const totalLines = allLines.length;
|
|
45354
45571
|
const startIndex = Math.max(0, offset - 1);
|
|
@@ -45389,7 +45606,7 @@ EXAMPLES:
|
|
|
45389
45606
|
}
|
|
45390
45607
|
};
|
|
45391
45608
|
}
|
|
45392
|
-
var
|
|
45609
|
+
var readFile5 = createReadFileTool();
|
|
45393
45610
|
function createWriteFileTool(config = {}) {
|
|
45394
45611
|
const mergedConfig = { ...DEFAULT_FILESYSTEM_CONFIG, ...config };
|
|
45395
45612
|
return {
|
|
@@ -45453,13 +45670,13 @@ EXAMPLES:
|
|
|
45453
45670
|
};
|
|
45454
45671
|
}
|
|
45455
45672
|
const resolvedPath = validation.resolvedPath;
|
|
45456
|
-
const fileExists =
|
|
45673
|
+
const fileExists = fs16.existsSync(resolvedPath);
|
|
45457
45674
|
try {
|
|
45458
|
-
const parentDir =
|
|
45459
|
-
if (!
|
|
45460
|
-
await
|
|
45675
|
+
const parentDir = path2.dirname(resolvedPath);
|
|
45676
|
+
if (!fs16.existsSync(parentDir)) {
|
|
45677
|
+
await fs15.mkdir(parentDir, { recursive: true });
|
|
45461
45678
|
}
|
|
45462
|
-
await
|
|
45679
|
+
await fs15.writeFile(resolvedPath, content, "utf-8");
|
|
45463
45680
|
return {
|
|
45464
45681
|
success: true,
|
|
45465
45682
|
path: file_path,
|
|
@@ -45476,7 +45693,7 @@ EXAMPLES:
|
|
|
45476
45693
|
}
|
|
45477
45694
|
};
|
|
45478
45695
|
}
|
|
45479
|
-
var
|
|
45696
|
+
var writeFile5 = createWriteFileTool();
|
|
45480
45697
|
function createEditFileTool(config = {}) {
|
|
45481
45698
|
const mergedConfig = { ...DEFAULT_FILESYSTEM_CONFIG, ...config };
|
|
45482
45699
|
return {
|
|
@@ -45562,7 +45779,7 @@ EXAMPLES:
|
|
|
45562
45779
|
};
|
|
45563
45780
|
}
|
|
45564
45781
|
const resolvedPath = validation.resolvedPath;
|
|
45565
|
-
if (!
|
|
45782
|
+
if (!fs16.existsSync(resolvedPath)) {
|
|
45566
45783
|
return {
|
|
45567
45784
|
success: false,
|
|
45568
45785
|
error: `File not found: ${file_path}`,
|
|
@@ -45570,7 +45787,7 @@ EXAMPLES:
|
|
|
45570
45787
|
};
|
|
45571
45788
|
}
|
|
45572
45789
|
try {
|
|
45573
|
-
const content = await
|
|
45790
|
+
const content = await fs15.readFile(resolvedPath, "utf-8");
|
|
45574
45791
|
let occurrences = 0;
|
|
45575
45792
|
let searchIndex = 0;
|
|
45576
45793
|
while (true) {
|
|
@@ -45609,7 +45826,7 @@ EXAMPLES:
|
|
|
45609
45826
|
} else {
|
|
45610
45827
|
newContent = content.replace(old_string, new_string);
|
|
45611
45828
|
}
|
|
45612
|
-
await
|
|
45829
|
+
await fs15.writeFile(resolvedPath, newContent, "utf-8");
|
|
45613
45830
|
const diffPreview = generateDiffPreview(old_string, new_string);
|
|
45614
45831
|
return {
|
|
45615
45832
|
success: true,
|
|
@@ -45665,11 +45882,11 @@ async function findFiles(dir, pattern, baseDir, config, results = [], depth = 0)
|
|
|
45665
45882
|
return results;
|
|
45666
45883
|
}
|
|
45667
45884
|
try {
|
|
45668
|
-
const entries = await
|
|
45885
|
+
const entries = await fs15.readdir(dir, { withFileTypes: true });
|
|
45669
45886
|
for (const entry of entries) {
|
|
45670
45887
|
if (results.length >= config.maxResults) break;
|
|
45671
|
-
const fullPath =
|
|
45672
|
-
const relativePath =
|
|
45888
|
+
const fullPath = path2.join(dir, entry.name);
|
|
45889
|
+
const relativePath = path2.relative(baseDir, fullPath);
|
|
45673
45890
|
if (entry.isDirectory()) {
|
|
45674
45891
|
const isBlocked = config.blockedDirectories.some(
|
|
45675
45892
|
(blocked) => entry.name === blocked || relativePath.includes(`/${blocked}/`) || relativePath.startsWith(`${blocked}/`)
|
|
@@ -45679,7 +45896,7 @@ async function findFiles(dir, pattern, baseDir, config, results = [], depth = 0)
|
|
|
45679
45896
|
} else if (entry.isFile()) {
|
|
45680
45897
|
if (matchGlobPattern(pattern, relativePath)) {
|
|
45681
45898
|
try {
|
|
45682
|
-
const stats = await
|
|
45899
|
+
const stats = await fs15.stat(fullPath);
|
|
45683
45900
|
results.push({
|
|
45684
45901
|
path: relativePath,
|
|
45685
45902
|
mtime: stats.mtimeMs
|
|
@@ -45761,7 +45978,7 @@ WHEN TO USE:
|
|
|
45761
45978
|
};
|
|
45762
45979
|
}
|
|
45763
45980
|
const resolvedDir = validation.resolvedPath;
|
|
45764
|
-
if (!
|
|
45981
|
+
if (!fs16.existsSync(resolvedDir)) {
|
|
45765
45982
|
return {
|
|
45766
45983
|
success: false,
|
|
45767
45984
|
error: `Directory not found: ${searchDir}`
|
|
@@ -45816,9 +46033,9 @@ async function findFilesToSearch(dir, baseDir, config, globPattern, fileType, fi
|
|
|
45816
46033
|
return files;
|
|
45817
46034
|
}
|
|
45818
46035
|
try {
|
|
45819
|
-
const entries = await
|
|
46036
|
+
const entries = await fs15.readdir(dir, { withFileTypes: true });
|
|
45820
46037
|
for (const entry of entries) {
|
|
45821
|
-
const fullPath =
|
|
46038
|
+
const fullPath = path2.join(dir, entry.name);
|
|
45822
46039
|
if (entry.isDirectory()) {
|
|
45823
46040
|
const isBlocked = config.blockedDirectories.some(
|
|
45824
46041
|
(blocked) => entry.name === blocked
|
|
@@ -45830,7 +46047,7 @@ async function findFilesToSearch(dir, baseDir, config, globPattern, fileType, fi
|
|
|
45830
46047
|
if (fileType) {
|
|
45831
46048
|
const extensions = FILE_TYPE_MAP[fileType.toLowerCase()];
|
|
45832
46049
|
if (extensions) {
|
|
45833
|
-
const ext =
|
|
46050
|
+
const ext = path2.extname(entry.name).toLowerCase();
|
|
45834
46051
|
if (!extensions.includes(ext)) continue;
|
|
45835
46052
|
}
|
|
45836
46053
|
}
|
|
@@ -45849,7 +46066,7 @@ async function findFilesToSearch(dir, baseDir, config, globPattern, fileType, fi
|
|
|
45849
46066
|
async function searchFile(filePath, regex, contextBefore, contextAfter) {
|
|
45850
46067
|
const matches = [];
|
|
45851
46068
|
try {
|
|
45852
|
-
const content = await
|
|
46069
|
+
const content = await fs15.readFile(filePath, "utf-8");
|
|
45853
46070
|
const lines = content.split("\n");
|
|
45854
46071
|
for (let i = 0; i < lines.length; i++) {
|
|
45855
46072
|
const line = lines[i] ?? "";
|
|
@@ -45990,7 +46207,7 @@ WHEN TO USE:
|
|
|
45990
46207
|
};
|
|
45991
46208
|
}
|
|
45992
46209
|
const resolvedPath = validation.resolvedPath;
|
|
45993
|
-
if (!
|
|
46210
|
+
if (!fs16.existsSync(resolvedPath)) {
|
|
45994
46211
|
return {
|
|
45995
46212
|
success: false,
|
|
45996
46213
|
error: `Path not found: ${searchPath}`
|
|
@@ -46006,7 +46223,7 @@ WHEN TO USE:
|
|
|
46006
46223
|
};
|
|
46007
46224
|
}
|
|
46008
46225
|
try {
|
|
46009
|
-
const stats = await
|
|
46226
|
+
const stats = await fs15.stat(resolvedPath);
|
|
46010
46227
|
let filesToSearch;
|
|
46011
46228
|
if (stats.isFile()) {
|
|
46012
46229
|
filesToSearch = [resolvedPath];
|
|
@@ -46032,7 +46249,7 @@ WHEN TO USE:
|
|
|
46032
46249
|
);
|
|
46033
46250
|
if (matches.length > 0) {
|
|
46034
46251
|
filesMatched++;
|
|
46035
|
-
const relativePath =
|
|
46252
|
+
const relativePath = path2.relative(resolvedPath, file) || file;
|
|
46036
46253
|
for (const match of matches) {
|
|
46037
46254
|
match.file = relativePath;
|
|
46038
46255
|
}
|
|
@@ -46094,11 +46311,11 @@ async function listDir(dir, baseDir, config, recursive, filter, maxDepth = 3, cu
|
|
|
46094
46311
|
return entries;
|
|
46095
46312
|
}
|
|
46096
46313
|
try {
|
|
46097
|
-
const dirEntries = await
|
|
46314
|
+
const dirEntries = await fs15.readdir(dir, { withFileTypes: true });
|
|
46098
46315
|
for (const entry of dirEntries) {
|
|
46099
46316
|
if (entries.length >= config.maxResults) break;
|
|
46100
|
-
const fullPath =
|
|
46101
|
-
const relativePath =
|
|
46317
|
+
const fullPath = path2.join(dir, entry.name);
|
|
46318
|
+
const relativePath = path2.relative(baseDir, fullPath);
|
|
46102
46319
|
if (entry.isDirectory() && config.blockedDirectories.includes(entry.name)) {
|
|
46103
46320
|
continue;
|
|
46104
46321
|
}
|
|
@@ -46112,7 +46329,7 @@ async function listDir(dir, baseDir, config, recursive, filter, maxDepth = 3, cu
|
|
|
46112
46329
|
}
|
|
46113
46330
|
if (filter === "directories" && !isDir) continue;
|
|
46114
46331
|
try {
|
|
46115
|
-
const stats = await
|
|
46332
|
+
const stats = await fs15.stat(fullPath);
|
|
46116
46333
|
const dirEntry = {
|
|
46117
46334
|
name: entry.name,
|
|
46118
46335
|
path: relativePath,
|
|
@@ -46208,14 +46425,14 @@ EXAMPLES:
|
|
|
46208
46425
|
};
|
|
46209
46426
|
}
|
|
46210
46427
|
const resolvedPath = validation.resolvedPath;
|
|
46211
|
-
if (!
|
|
46428
|
+
if (!fs16.existsSync(resolvedPath)) {
|
|
46212
46429
|
return {
|
|
46213
46430
|
success: false,
|
|
46214
46431
|
error: `Directory not found: ${path6}`
|
|
46215
46432
|
};
|
|
46216
46433
|
}
|
|
46217
46434
|
try {
|
|
46218
|
-
const stats = await
|
|
46435
|
+
const stats = await fs15.stat(resolvedPath);
|
|
46219
46436
|
if (!stats.isDirectory()) {
|
|
46220
46437
|
return {
|
|
46221
46438
|
success: false,
|
|
@@ -46403,7 +46620,8 @@ EXAMPLES:
|
|
|
46403
46620
|
shell: mergedConfig.shell,
|
|
46404
46621
|
cwd: mergedConfig.workingDirectory,
|
|
46405
46622
|
env,
|
|
46406
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
46623
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
46624
|
+
detached: true
|
|
46407
46625
|
});
|
|
46408
46626
|
if (run_in_background && mergedConfig.allowBackground) {
|
|
46409
46627
|
const bgId = generateBackgroundId();
|
|
@@ -46430,14 +46648,27 @@ EXAMPLES:
|
|
|
46430
46648
|
let stdout = "";
|
|
46431
46649
|
let stderr = "";
|
|
46432
46650
|
let killed = false;
|
|
46651
|
+
const killProcessGroup = (signal) => {
|
|
46652
|
+
try {
|
|
46653
|
+
if (childProcess.pid) {
|
|
46654
|
+
process.kill(-childProcess.pid, signal);
|
|
46655
|
+
}
|
|
46656
|
+
} catch {
|
|
46657
|
+
try {
|
|
46658
|
+
childProcess.kill(signal);
|
|
46659
|
+
} catch {
|
|
46660
|
+
}
|
|
46661
|
+
}
|
|
46662
|
+
};
|
|
46663
|
+
const GRACEFUL_KILL_WAIT_MS = 3e3;
|
|
46433
46664
|
const timeoutId = setTimeout(() => {
|
|
46434
46665
|
killed = true;
|
|
46435
|
-
|
|
46666
|
+
killProcessGroup("SIGTERM");
|
|
46436
46667
|
setTimeout(() => {
|
|
46437
46668
|
if (!childProcess.killed) {
|
|
46438
|
-
|
|
46669
|
+
killProcessGroup("SIGKILL");
|
|
46439
46670
|
}
|
|
46440
|
-
},
|
|
46671
|
+
}, GRACEFUL_KILL_WAIT_MS);
|
|
46441
46672
|
}, effectiveTimeout);
|
|
46442
46673
|
childProcess.stdout.on("data", (data) => {
|
|
46443
46674
|
stdout += data.toString();
|
|
@@ -46451,8 +46682,28 @@ EXAMPLES:
|
|
|
46451
46682
|
stderr = stderr.slice(-mergedConfig.maxOutputSize);
|
|
46452
46683
|
}
|
|
46453
46684
|
});
|
|
46454
|
-
|
|
46685
|
+
let resolved = false;
|
|
46686
|
+
const safeResolve = (result) => {
|
|
46687
|
+
if (resolved) return;
|
|
46688
|
+
resolved = true;
|
|
46455
46689
|
clearTimeout(timeoutId);
|
|
46690
|
+
clearTimeout(hardTimeoutId);
|
|
46691
|
+
resolve4(result);
|
|
46692
|
+
};
|
|
46693
|
+
const HARD_TIMEOUT_GRACE_MS = 5e3;
|
|
46694
|
+
const hardTimeoutId = setTimeout(() => {
|
|
46695
|
+
if (!resolved) {
|
|
46696
|
+
killProcessGroup("SIGKILL");
|
|
46697
|
+
safeResolve({
|
|
46698
|
+
success: false,
|
|
46699
|
+
stdout,
|
|
46700
|
+
stderr,
|
|
46701
|
+
duration: Date.now() - startTime,
|
|
46702
|
+
error: `Command timed out after ${effectiveTimeout}ms (hard timeout: process group did not exit)`
|
|
46703
|
+
});
|
|
46704
|
+
}
|
|
46705
|
+
}, effectiveTimeout + GRACEFUL_KILL_WAIT_MS + HARD_TIMEOUT_GRACE_MS);
|
|
46706
|
+
childProcess.on("close", (code, signal) => {
|
|
46456
46707
|
const duration = Date.now() - startTime;
|
|
46457
46708
|
let truncated = false;
|
|
46458
46709
|
if (stdout.length > mergedConfig.maxOutputSize) {
|
|
@@ -46464,7 +46715,7 @@ EXAMPLES:
|
|
|
46464
46715
|
truncated = true;
|
|
46465
46716
|
}
|
|
46466
46717
|
if (killed) {
|
|
46467
|
-
|
|
46718
|
+
safeResolve({
|
|
46468
46719
|
success: false,
|
|
46469
46720
|
stdout,
|
|
46470
46721
|
stderr,
|
|
@@ -46475,7 +46726,7 @@ EXAMPLES:
|
|
|
46475
46726
|
error: `Command timed out after ${effectiveTimeout}ms`
|
|
46476
46727
|
});
|
|
46477
46728
|
} else {
|
|
46478
|
-
|
|
46729
|
+
safeResolve({
|
|
46479
46730
|
success: code === 0,
|
|
46480
46731
|
stdout,
|
|
46481
46732
|
stderr,
|
|
@@ -46488,8 +46739,7 @@ EXAMPLES:
|
|
|
46488
46739
|
}
|
|
46489
46740
|
});
|
|
46490
46741
|
childProcess.on("error", (error) => {
|
|
46491
|
-
|
|
46492
|
-
resolve4({
|
|
46742
|
+
safeResolve({
|
|
46493
46743
|
success: false,
|
|
46494
46744
|
error: `Failed to execute command: ${error.message}`,
|
|
46495
46745
|
duration: Date.now() - startTime
|
|
@@ -47755,8 +48005,8 @@ async function tryNative(args, startTime, attemptedMethods) {
|
|
|
47755
48005
|
method: "native",
|
|
47756
48006
|
title: result.title,
|
|
47757
48007
|
content: cleanContent,
|
|
47758
|
-
//
|
|
47759
|
-
|
|
48008
|
+
// Native method already returns markdown-like content — no separate markdown field needed
|
|
48009
|
+
// (would just duplicate content and waste tokens)
|
|
47760
48010
|
qualityScore: result.qualityScore,
|
|
47761
48011
|
durationMs: Date.now() - startTime,
|
|
47762
48012
|
attemptedMethods,
|
|
@@ -47792,8 +48042,7 @@ async function tryJS(args, startTime, attemptedMethods) {
|
|
|
47792
48042
|
method: "js",
|
|
47793
48043
|
title: result.title,
|
|
47794
48044
|
content: cleanContent,
|
|
47795
|
-
//
|
|
47796
|
-
markdown: args.includeMarkdown ? cleanContent : void 0,
|
|
48045
|
+
// JS method already returns markdown-like content — no separate markdown field needed
|
|
47797
48046
|
qualityScore: result.success ? 80 : 0,
|
|
47798
48047
|
durationMs: Date.now() - startTime,
|
|
47799
48048
|
attemptedMethods,
|
|
@@ -47825,8 +48074,11 @@ async function tryAPI(connectorName, args, startTime, attemptedMethods) {
|
|
|
47825
48074
|
includeLinks: args.includeLinks
|
|
47826
48075
|
};
|
|
47827
48076
|
const result = await provider.scrape(args.url, options);
|
|
47828
|
-
const
|
|
47829
|
-
const
|
|
48077
|
+
const rawContent = result.result?.content || "";
|
|
48078
|
+
const rawMarkdown = result.result?.markdown;
|
|
48079
|
+
const cleanContent = stripBase64DataUris(rawContent);
|
|
48080
|
+
const cleanMarkdown = rawMarkdown ? stripBase64DataUris(rawMarkdown) : void 0;
|
|
48081
|
+
const isDuplicate = !!cleanMarkdown && cleanContent === cleanMarkdown;
|
|
47830
48082
|
return {
|
|
47831
48083
|
success: result.success,
|
|
47832
48084
|
url: args.url,
|
|
@@ -47836,7 +48088,7 @@ async function tryAPI(connectorName, args, startTime, attemptedMethods) {
|
|
|
47836
48088
|
content: cleanContent,
|
|
47837
48089
|
html: result.result?.html,
|
|
47838
48090
|
// Keep raw HTML as-is (only used if explicitly requested)
|
|
47839
|
-
markdown: cleanMarkdown,
|
|
48091
|
+
markdown: isDuplicate ? void 0 : cleanMarkdown,
|
|
47840
48092
|
metadata: result.result?.metadata,
|
|
47841
48093
|
links: result.result?.links,
|
|
47842
48094
|
qualityScore: result.success ? 90 : 0,
|
|
@@ -48051,68 +48303,25 @@ async function executeInVM(code, input, timeout, logs) {
|
|
|
48051
48303
|
const result = await resultPromise;
|
|
48052
48304
|
return result !== void 0 ? result : sandbox.output;
|
|
48053
48305
|
}
|
|
48054
|
-
var MIME_TYPES = {
|
|
48055
|
-
png: "image/png",
|
|
48056
|
-
jpeg: "image/jpeg",
|
|
48057
|
-
jpg: "image/jpeg",
|
|
48058
|
-
webp: "image/webp",
|
|
48059
|
-
gif: "image/gif",
|
|
48060
|
-
mp4: "video/mp4",
|
|
48061
|
-
webm: "video/webm",
|
|
48062
|
-
mp3: "audio/mpeg",
|
|
48063
|
-
wav: "audio/wav",
|
|
48064
|
-
opus: "audio/opus",
|
|
48065
|
-
ogg: "audio/ogg",
|
|
48066
|
-
aac: "audio/aac",
|
|
48067
|
-
flac: "audio/flac",
|
|
48068
|
-
pcm: "audio/pcm"
|
|
48069
|
-
};
|
|
48070
|
-
var FileMediaOutputHandler = class {
|
|
48071
|
-
outputDir;
|
|
48072
|
-
initialized = false;
|
|
48073
|
-
constructor(outputDir) {
|
|
48074
|
-
this.outputDir = outputDir ?? path3__namespace.join(os__namespace.tmpdir(), "oneringai-media");
|
|
48075
|
-
}
|
|
48076
|
-
async save(data, metadata) {
|
|
48077
|
-
if (!this.initialized) {
|
|
48078
|
-
await fs14__namespace.mkdir(this.outputDir, { recursive: true });
|
|
48079
|
-
this.initialized = true;
|
|
48080
|
-
}
|
|
48081
|
-
const filename = metadata.suggestedFilename ?? this.generateFilename(metadata);
|
|
48082
|
-
const filePath = path3__namespace.join(this.outputDir, filename);
|
|
48083
|
-
await fs14__namespace.writeFile(filePath, data);
|
|
48084
|
-
const format = metadata.format.toLowerCase();
|
|
48085
|
-
const mimeType = MIME_TYPES[format] ?? `application/octet-stream`;
|
|
48086
|
-
return {
|
|
48087
|
-
location: filePath,
|
|
48088
|
-
mimeType,
|
|
48089
|
-
size: data.length
|
|
48090
|
-
};
|
|
48091
|
-
}
|
|
48092
|
-
generateFilename(metadata) {
|
|
48093
|
-
const timestamp = Date.now();
|
|
48094
|
-
const random2 = crypto2__namespace.randomBytes(4).toString("hex");
|
|
48095
|
-
const indexSuffix = metadata.index != null ? `_${metadata.index}` : "";
|
|
48096
|
-
return `${metadata.type}_${timestamp}_${random2}${indexSuffix}.${metadata.format}`;
|
|
48097
|
-
}
|
|
48098
|
-
};
|
|
48099
48306
|
|
|
48100
48307
|
// src/tools/multimedia/config.ts
|
|
48101
|
-
var
|
|
48102
|
-
function
|
|
48103
|
-
if (!
|
|
48104
|
-
|
|
48308
|
+
var _storage = null;
|
|
48309
|
+
function getMediaStorage() {
|
|
48310
|
+
if (!_storage) {
|
|
48311
|
+
_storage = new FileMediaStorage();
|
|
48105
48312
|
}
|
|
48106
|
-
return
|
|
48313
|
+
return _storage;
|
|
48107
48314
|
}
|
|
48108
|
-
function
|
|
48109
|
-
|
|
48315
|
+
function setMediaStorage(storage) {
|
|
48316
|
+
_storage = storage;
|
|
48110
48317
|
}
|
|
48318
|
+
var getMediaOutputHandler = getMediaStorage;
|
|
48319
|
+
var setMediaOutputHandler = setMediaStorage;
|
|
48111
48320
|
|
|
48112
48321
|
// src/tools/multimedia/imageGeneration.ts
|
|
48113
|
-
function createImageGenerationTool(connector,
|
|
48322
|
+
function createImageGenerationTool(connector, storage, userId) {
|
|
48114
48323
|
const vendor = connector.vendor;
|
|
48115
|
-
const handler =
|
|
48324
|
+
const handler = storage ?? getMediaStorage();
|
|
48116
48325
|
const vendorModels = vendor ? getImageModelsByVendor(vendor) : [];
|
|
48117
48326
|
const modelNames = vendorModels.map((m) => m.name);
|
|
48118
48327
|
const properties = {
|
|
@@ -48185,8 +48394,9 @@ function createImageGenerationTool(connector, outputHandler) {
|
|
|
48185
48394
|
}
|
|
48186
48395
|
}
|
|
48187
48396
|
},
|
|
48188
|
-
execute: async (args) => {
|
|
48397
|
+
execute: async (args, context) => {
|
|
48189
48398
|
try {
|
|
48399
|
+
const effectiveUserId = userId ?? context?.userId;
|
|
48190
48400
|
const imageGen = ImageGeneration.create({ connector });
|
|
48191
48401
|
const response = await imageGen.generate({
|
|
48192
48402
|
prompt: args.prompt,
|
|
@@ -48217,7 +48427,8 @@ function createImageGenerationTool(connector, outputHandler) {
|
|
|
48217
48427
|
format,
|
|
48218
48428
|
model: modelName,
|
|
48219
48429
|
vendor: vendor || "unknown",
|
|
48220
|
-
index: response.data.length > 1 ? i : void 0
|
|
48430
|
+
index: response.data.length > 1 ? i : void 0,
|
|
48431
|
+
userId: effectiveUserId
|
|
48221
48432
|
});
|
|
48222
48433
|
images.push({
|
|
48223
48434
|
location: result.location,
|
|
@@ -48244,9 +48455,9 @@ function createImageGenerationTool(connector, outputHandler) {
|
|
|
48244
48455
|
|
|
48245
48456
|
// src/tools/multimedia/videoGeneration.ts
|
|
48246
48457
|
var videoGenInstances = /* @__PURE__ */ new Map();
|
|
48247
|
-
function createVideoTools(connector,
|
|
48458
|
+
function createVideoTools(connector, storage, userId) {
|
|
48248
48459
|
const vendor = connector.vendor;
|
|
48249
|
-
const handler =
|
|
48460
|
+
const handler = storage ?? getMediaStorage();
|
|
48250
48461
|
const vendorModels = vendor ? getVideoModelsByVendor(vendor) : [];
|
|
48251
48462
|
const modelNames = vendorModels.map((m) => m.name);
|
|
48252
48463
|
const generateProperties = {
|
|
@@ -48310,7 +48521,7 @@ function createVideoTools(connector, outputHandler) {
|
|
|
48310
48521
|
}
|
|
48311
48522
|
}
|
|
48312
48523
|
},
|
|
48313
|
-
execute: async (args) => {
|
|
48524
|
+
execute: async (args, _context) => {
|
|
48314
48525
|
try {
|
|
48315
48526
|
const videoGen = VideoGeneration.create({ connector });
|
|
48316
48527
|
const response = await videoGen.generate({
|
|
@@ -48359,8 +48570,9 @@ function createVideoTools(connector, outputHandler) {
|
|
|
48359
48570
|
}
|
|
48360
48571
|
}
|
|
48361
48572
|
},
|
|
48362
|
-
execute: async (args) => {
|
|
48573
|
+
execute: async (args, context) => {
|
|
48363
48574
|
try {
|
|
48575
|
+
const effectiveUserId = userId ?? context?.userId;
|
|
48364
48576
|
let videoGen = videoGenInstances.get(args.jobId);
|
|
48365
48577
|
if (!videoGen) {
|
|
48366
48578
|
videoGen = VideoGeneration.create({ connector });
|
|
@@ -48386,7 +48598,8 @@ function createVideoTools(connector, outputHandler) {
|
|
|
48386
48598
|
type: "video",
|
|
48387
48599
|
format,
|
|
48388
48600
|
model: modelName,
|
|
48389
|
-
vendor: vendor || "unknown"
|
|
48601
|
+
vendor: vendor || "unknown",
|
|
48602
|
+
userId: effectiveUserId
|
|
48390
48603
|
});
|
|
48391
48604
|
videoGenInstances.delete(args.jobId);
|
|
48392
48605
|
return {
|
|
@@ -48434,9 +48647,9 @@ function createVideoTools(connector, outputHandler) {
|
|
|
48434
48647
|
}
|
|
48435
48648
|
|
|
48436
48649
|
// src/tools/multimedia/textToSpeech.ts
|
|
48437
|
-
function createTextToSpeechTool(connector,
|
|
48650
|
+
function createTextToSpeechTool(connector, storage, userId) {
|
|
48438
48651
|
const vendor = connector.vendor;
|
|
48439
|
-
const handler =
|
|
48652
|
+
const handler = storage ?? getMediaStorage();
|
|
48440
48653
|
const vendorModels = vendor ? getTTSModelsByVendor(vendor) : [];
|
|
48441
48654
|
const modelNames = vendorModels.map((m) => m.name);
|
|
48442
48655
|
const properties = {
|
|
@@ -48497,8 +48710,9 @@ function createTextToSpeechTool(connector, outputHandler) {
|
|
|
48497
48710
|
}
|
|
48498
48711
|
}
|
|
48499
48712
|
},
|
|
48500
|
-
execute: async (args) => {
|
|
48713
|
+
execute: async (args, context) => {
|
|
48501
48714
|
try {
|
|
48715
|
+
const effectiveUserId = userId ?? context?.userId;
|
|
48502
48716
|
const tts = TextToSpeech.create({
|
|
48503
48717
|
connector,
|
|
48504
48718
|
model: args.model,
|
|
@@ -48512,7 +48726,8 @@ function createTextToSpeechTool(connector, outputHandler) {
|
|
|
48512
48726
|
type: "audio",
|
|
48513
48727
|
format,
|
|
48514
48728
|
model: args.model || modelNames[0] || "unknown",
|
|
48515
|
-
vendor: vendor || "unknown"
|
|
48729
|
+
vendor: vendor || "unknown",
|
|
48730
|
+
userId: effectiveUserId
|
|
48516
48731
|
});
|
|
48517
48732
|
return {
|
|
48518
48733
|
success: true,
|
|
@@ -48535,14 +48750,17 @@ function createTextToSpeechTool(connector, outputHandler) {
|
|
|
48535
48750
|
}
|
|
48536
48751
|
};
|
|
48537
48752
|
}
|
|
48538
|
-
|
|
48753
|
+
|
|
48754
|
+
// src/tools/multimedia/speechToText.ts
|
|
48755
|
+
function createSpeechToTextTool(connector, storage, _userId) {
|
|
48539
48756
|
const vendor = connector.vendor;
|
|
48757
|
+
const handler = storage ?? getMediaStorage();
|
|
48540
48758
|
const vendorModels = vendor ? getSTTModelsByVendor(vendor) : [];
|
|
48541
48759
|
const modelNames = vendorModels.map((m) => m.name);
|
|
48542
48760
|
const properties = {
|
|
48543
|
-
|
|
48761
|
+
audioSource: {
|
|
48544
48762
|
type: "string",
|
|
48545
|
-
description: "Path
|
|
48763
|
+
description: "Path or location of the audio file to transcribe (file path, storage location, etc.)"
|
|
48546
48764
|
}
|
|
48547
48765
|
};
|
|
48548
48766
|
if (modelNames.length > 0) {
|
|
@@ -48570,13 +48788,19 @@ function createSpeechToTextTool(connector) {
|
|
|
48570
48788
|
parameters: {
|
|
48571
48789
|
type: "object",
|
|
48572
48790
|
properties,
|
|
48573
|
-
required: ["
|
|
48791
|
+
required: ["audioSource"]
|
|
48574
48792
|
}
|
|
48575
48793
|
}
|
|
48576
48794
|
},
|
|
48577
|
-
execute: async (args) => {
|
|
48795
|
+
execute: async (args, _context) => {
|
|
48578
48796
|
try {
|
|
48579
|
-
const audioBuffer = await
|
|
48797
|
+
const audioBuffer = await handler.read(args.audioSource);
|
|
48798
|
+
if (!audioBuffer) {
|
|
48799
|
+
return {
|
|
48800
|
+
success: false,
|
|
48801
|
+
error: `Audio not found at: ${args.audioSource}`
|
|
48802
|
+
};
|
|
48803
|
+
}
|
|
48580
48804
|
const stt = SpeechToText.create({
|
|
48581
48805
|
connector,
|
|
48582
48806
|
model: args.model,
|
|
@@ -48598,7 +48822,7 @@ function createSpeechToTextTool(connector) {
|
|
|
48598
48822
|
};
|
|
48599
48823
|
}
|
|
48600
48824
|
},
|
|
48601
|
-
describeCall: (args) => args.
|
|
48825
|
+
describeCall: (args) => args.audioSource,
|
|
48602
48826
|
permission: {
|
|
48603
48827
|
scope: "session",
|
|
48604
48828
|
riskLevel: "low",
|
|
@@ -48613,21 +48837,22 @@ var VENDOR_CAPABILITIES = {
|
|
|
48613
48837
|
[Vendor.Google]: ["image", "video", "tts"],
|
|
48614
48838
|
[Vendor.Grok]: ["image", "video"]
|
|
48615
48839
|
};
|
|
48616
|
-
function registerMultimediaTools() {
|
|
48840
|
+
function registerMultimediaTools(storage) {
|
|
48617
48841
|
for (const [vendor, capabilities] of Object.entries(VENDOR_CAPABILITIES)) {
|
|
48618
|
-
ConnectorTools.registerService(vendor, (connector,
|
|
48842
|
+
ConnectorTools.registerService(vendor, (connector, userId) => {
|
|
48843
|
+
const handler = getMediaStorage();
|
|
48619
48844
|
const tools = [];
|
|
48620
48845
|
if (capabilities.includes("image")) {
|
|
48621
|
-
tools.push(createImageGenerationTool(connector));
|
|
48846
|
+
tools.push(createImageGenerationTool(connector, handler, userId));
|
|
48622
48847
|
}
|
|
48623
48848
|
if (capabilities.includes("video")) {
|
|
48624
|
-
tools.push(...createVideoTools(connector));
|
|
48849
|
+
tools.push(...createVideoTools(connector, handler, userId));
|
|
48625
48850
|
}
|
|
48626
48851
|
if (capabilities.includes("tts")) {
|
|
48627
|
-
tools.push(createTextToSpeechTool(connector));
|
|
48852
|
+
tools.push(createTextToSpeechTool(connector, handler, userId));
|
|
48628
48853
|
}
|
|
48629
48854
|
if (capabilities.includes("stt")) {
|
|
48630
|
-
tools.push(createSpeechToTextTool(connector));
|
|
48855
|
+
tools.push(createSpeechToTextTool(connector, handler));
|
|
48631
48856
|
}
|
|
48632
48857
|
return tools;
|
|
48633
48858
|
});
|
|
@@ -48637,6 +48862,851 @@ function registerMultimediaTools() {
|
|
|
48637
48862
|
// src/tools/multimedia/index.ts
|
|
48638
48863
|
registerMultimediaTools();
|
|
48639
48864
|
|
|
48865
|
+
// src/tools/github/types.ts
|
|
48866
|
+
function parseRepository(input) {
|
|
48867
|
+
if (!input || input.trim().length === 0) {
|
|
48868
|
+
throw new Error("Repository cannot be empty");
|
|
48869
|
+
}
|
|
48870
|
+
const trimmed = input.trim();
|
|
48871
|
+
try {
|
|
48872
|
+
const url2 = new URL(trimmed);
|
|
48873
|
+
if (url2.hostname === "github.com" || url2.hostname === "www.github.com") {
|
|
48874
|
+
const segments = url2.pathname.split("/").filter(Boolean);
|
|
48875
|
+
if (segments.length >= 2) {
|
|
48876
|
+
return { owner: segments[0], repo: segments[1].replace(/\.git$/, "") };
|
|
48877
|
+
}
|
|
48878
|
+
}
|
|
48879
|
+
} catch {
|
|
48880
|
+
}
|
|
48881
|
+
const parts = trimmed.split("/");
|
|
48882
|
+
if (parts.length === 2 && parts[0].length > 0 && parts[1].length > 0) {
|
|
48883
|
+
return { owner: parts[0], repo: parts[1] };
|
|
48884
|
+
}
|
|
48885
|
+
throw new Error(
|
|
48886
|
+
`Invalid repository format: "${input}". Expected "owner/repo" or "https://github.com/owner/repo"`
|
|
48887
|
+
);
|
|
48888
|
+
}
|
|
48889
|
+
function resolveRepository(repository, connector) {
|
|
48890
|
+
const repoStr = repository ?? connector.getOptions().defaultRepository;
|
|
48891
|
+
if (!repoStr) {
|
|
48892
|
+
return {
|
|
48893
|
+
success: false,
|
|
48894
|
+
error: 'No repository specified. Provide a "repository" parameter (e.g., "owner/repo") or configure defaultRepository on the connector.'
|
|
48895
|
+
};
|
|
48896
|
+
}
|
|
48897
|
+
try {
|
|
48898
|
+
return { success: true, repo: parseRepository(repoStr) };
|
|
48899
|
+
} catch (err) {
|
|
48900
|
+
return { success: false, error: err instanceof Error ? err.message : String(err) };
|
|
48901
|
+
}
|
|
48902
|
+
}
|
|
48903
|
+
var GitHubAPIError = class extends Error {
|
|
48904
|
+
constructor(status, statusText, body) {
|
|
48905
|
+
const msg = typeof body === "object" && body !== null && "message" in body ? body.message : statusText;
|
|
48906
|
+
super(`GitHub API error ${status}: ${msg}`);
|
|
48907
|
+
this.status = status;
|
|
48908
|
+
this.statusText = statusText;
|
|
48909
|
+
this.body = body;
|
|
48910
|
+
this.name = "GitHubAPIError";
|
|
48911
|
+
}
|
|
48912
|
+
};
|
|
48913
|
+
async function githubFetch(connector, endpoint, options) {
|
|
48914
|
+
let url2 = endpoint;
|
|
48915
|
+
if (options?.queryParams && Object.keys(options.queryParams).length > 0) {
|
|
48916
|
+
const params = new URLSearchParams();
|
|
48917
|
+
for (const [key, value] of Object.entries(options.queryParams)) {
|
|
48918
|
+
params.append(key, String(value));
|
|
48919
|
+
}
|
|
48920
|
+
url2 += (url2.includes("?") ? "&" : "?") + params.toString();
|
|
48921
|
+
}
|
|
48922
|
+
const headers = {
|
|
48923
|
+
"Accept": options?.accept ?? "application/vnd.github+json",
|
|
48924
|
+
"X-GitHub-Api-Version": "2022-11-28"
|
|
48925
|
+
};
|
|
48926
|
+
if (options?.body) {
|
|
48927
|
+
headers["Content-Type"] = "application/json";
|
|
48928
|
+
}
|
|
48929
|
+
const response = await connector.fetch(
|
|
48930
|
+
url2,
|
|
48931
|
+
{
|
|
48932
|
+
method: options?.method ?? "GET",
|
|
48933
|
+
headers,
|
|
48934
|
+
body: options?.body ? JSON.stringify(options.body) : void 0
|
|
48935
|
+
},
|
|
48936
|
+
options?.userId
|
|
48937
|
+
);
|
|
48938
|
+
const text = await response.text();
|
|
48939
|
+
let data;
|
|
48940
|
+
try {
|
|
48941
|
+
data = JSON.parse(text);
|
|
48942
|
+
} catch {
|
|
48943
|
+
data = text;
|
|
48944
|
+
}
|
|
48945
|
+
if (!response.ok) {
|
|
48946
|
+
throw new GitHubAPIError(response.status, response.statusText, data);
|
|
48947
|
+
}
|
|
48948
|
+
return data;
|
|
48949
|
+
}
|
|
48950
|
+
|
|
48951
|
+
// src/tools/github/searchFiles.ts
|
|
48952
|
+
function matchGlobPattern2(pattern, filePath) {
|
|
48953
|
+
let regexPattern = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/\?/g, ".").replace(/\{\{GLOBSTAR\}\}/g, ".*");
|
|
48954
|
+
regexPattern = "^" + regexPattern + "$";
|
|
48955
|
+
try {
|
|
48956
|
+
const regex = new RegExp(regexPattern);
|
|
48957
|
+
return regex.test(filePath);
|
|
48958
|
+
} catch {
|
|
48959
|
+
return false;
|
|
48960
|
+
}
|
|
48961
|
+
}
|
|
48962
|
+
function createSearchFilesTool(connector, userId) {
|
|
48963
|
+
return {
|
|
48964
|
+
definition: {
|
|
48965
|
+
type: "function",
|
|
48966
|
+
function: {
|
|
48967
|
+
name: "search_files",
|
|
48968
|
+
description: `Search for files by name/path pattern in a GitHub repository.
|
|
48969
|
+
|
|
48970
|
+
USAGE:
|
|
48971
|
+
- Supports glob patterns like "**/*.ts", "src/**/*.tsx"
|
|
48972
|
+
- Returns matching file paths sorted alphabetically
|
|
48973
|
+
- Uses the repository's file tree for fast matching
|
|
48974
|
+
|
|
48975
|
+
PATTERN SYNTAX:
|
|
48976
|
+
- * matches any characters except /
|
|
48977
|
+
- ** matches any characters including /
|
|
48978
|
+
- ? matches a single character
|
|
48979
|
+
|
|
48980
|
+
EXAMPLES:
|
|
48981
|
+
- Find all TypeScript files: { "pattern": "**/*.ts" }
|
|
48982
|
+
- Find files in src: { "pattern": "src/**/*.{ts,tsx}" }
|
|
48983
|
+
- Find package.json: { "pattern": "**/package.json" }
|
|
48984
|
+
- Search specific branch: { "pattern": "**/*.ts", "ref": "develop" }`,
|
|
48985
|
+
parameters: {
|
|
48986
|
+
type: "object",
|
|
48987
|
+
properties: {
|
|
48988
|
+
repository: {
|
|
48989
|
+
type: "string",
|
|
48990
|
+
description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
|
|
48991
|
+
},
|
|
48992
|
+
pattern: {
|
|
48993
|
+
type: "string",
|
|
48994
|
+
description: 'Glob pattern to match files (e.g., "**/*.ts", "src/**/*.tsx")'
|
|
48995
|
+
},
|
|
48996
|
+
ref: {
|
|
48997
|
+
type: "string",
|
|
48998
|
+
description: "Branch, tag, or commit SHA. Defaults to the repository's default branch."
|
|
48999
|
+
}
|
|
49000
|
+
},
|
|
49001
|
+
required: ["pattern"]
|
|
49002
|
+
}
|
|
49003
|
+
}
|
|
49004
|
+
},
|
|
49005
|
+
describeCall: (args) => {
|
|
49006
|
+
const parts = [args.pattern];
|
|
49007
|
+
if (args.repository) parts.push(`in ${args.repository}`);
|
|
49008
|
+
if (args.ref) parts.push(`@${args.ref}`);
|
|
49009
|
+
return parts.join(" ");
|
|
49010
|
+
},
|
|
49011
|
+
permission: {
|
|
49012
|
+
scope: "session",
|
|
49013
|
+
riskLevel: "low",
|
|
49014
|
+
approvalMessage: `Search files in a GitHub repository via ${connector.displayName}`
|
|
49015
|
+
},
|
|
49016
|
+
execute: async (args) => {
|
|
49017
|
+
const resolved = resolveRepository(args.repository, connector);
|
|
49018
|
+
if (!resolved.success) {
|
|
49019
|
+
return { success: false, error: resolved.error };
|
|
49020
|
+
}
|
|
49021
|
+
const { owner, repo } = resolved.repo;
|
|
49022
|
+
try {
|
|
49023
|
+
let ref = args.ref;
|
|
49024
|
+
if (!ref) {
|
|
49025
|
+
const repoInfo = await githubFetch(
|
|
49026
|
+
connector,
|
|
49027
|
+
`/repos/${owner}/${repo}`,
|
|
49028
|
+
{ userId }
|
|
49029
|
+
);
|
|
49030
|
+
ref = repoInfo.default_branch;
|
|
49031
|
+
}
|
|
49032
|
+
const tree = await githubFetch(
|
|
49033
|
+
connector,
|
|
49034
|
+
`/repos/${owner}/${repo}/git/trees/${ref}?recursive=1`,
|
|
49035
|
+
{ userId }
|
|
49036
|
+
);
|
|
49037
|
+
const matching = tree.tree.filter(
|
|
49038
|
+
(entry) => entry.type === "blob" && matchGlobPattern2(args.pattern, entry.path)
|
|
49039
|
+
).map((entry) => ({
|
|
49040
|
+
path: entry.path,
|
|
49041
|
+
size: entry.size ?? 0,
|
|
49042
|
+
type: entry.type
|
|
49043
|
+
})).sort((a, b) => a.path.localeCompare(b.path));
|
|
49044
|
+
return {
|
|
49045
|
+
success: true,
|
|
49046
|
+
files: matching,
|
|
49047
|
+
count: matching.length,
|
|
49048
|
+
truncated: tree.truncated
|
|
49049
|
+
};
|
|
49050
|
+
} catch (error) {
|
|
49051
|
+
return {
|
|
49052
|
+
success: false,
|
|
49053
|
+
error: `Failed to search files: ${error instanceof Error ? error.message : String(error)}`
|
|
49054
|
+
};
|
|
49055
|
+
}
|
|
49056
|
+
}
|
|
49057
|
+
};
|
|
49058
|
+
}
|
|
49059
|
+
|
|
49060
|
+
// src/tools/github/searchCode.ts
|
|
49061
|
+
function createSearchCodeTool(connector, userId) {
|
|
49062
|
+
return {
|
|
49063
|
+
definition: {
|
|
49064
|
+
type: "function",
|
|
49065
|
+
function: {
|
|
49066
|
+
name: "search_code",
|
|
49067
|
+
description: `Search for code content across a GitHub repository.
|
|
49068
|
+
|
|
49069
|
+
USAGE:
|
|
49070
|
+
- Search by keyword, function name, class name, or any text
|
|
49071
|
+
- Filter by language, path, or file extension
|
|
49072
|
+
- Returns matching files with text fragments showing context
|
|
49073
|
+
|
|
49074
|
+
RATE LIMITS:
|
|
49075
|
+
- GitHub's code search API is limited to 30 requests per minute
|
|
49076
|
+
- Results may be incomplete for very large repositories
|
|
49077
|
+
|
|
49078
|
+
EXAMPLES:
|
|
49079
|
+
- Find function: { "query": "function handleAuth", "language": "typescript" }
|
|
49080
|
+
- Find imports: { "query": "import React", "extension": "tsx" }
|
|
49081
|
+
- Search in path: { "query": "TODO", "path": "src/utils" }
|
|
49082
|
+
- Limit results: { "query": "console.log", "limit": 10 }`,
|
|
49083
|
+
parameters: {
|
|
49084
|
+
type: "object",
|
|
49085
|
+
properties: {
|
|
49086
|
+
repository: {
|
|
49087
|
+
type: "string",
|
|
49088
|
+
description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
|
|
49089
|
+
},
|
|
49090
|
+
query: {
|
|
49091
|
+
type: "string",
|
|
49092
|
+
description: "Search query \u2014 keyword, function name, or any text to find in code"
|
|
49093
|
+
},
|
|
49094
|
+
language: {
|
|
49095
|
+
type: "string",
|
|
49096
|
+
description: 'Filter by programming language (e.g., "typescript", "python", "go")'
|
|
49097
|
+
},
|
|
49098
|
+
path: {
|
|
49099
|
+
type: "string",
|
|
49100
|
+
description: 'Filter by file path prefix (e.g., "src/", "lib/utils")'
|
|
49101
|
+
},
|
|
49102
|
+
extension: {
|
|
49103
|
+
type: "string",
|
|
49104
|
+
description: 'Filter by file extension without dot (e.g., "ts", "py", "go")'
|
|
49105
|
+
},
|
|
49106
|
+
limit: {
|
|
49107
|
+
type: "number",
|
|
49108
|
+
description: "Maximum number of results (default: 30, max: 100)"
|
|
49109
|
+
}
|
|
49110
|
+
},
|
|
49111
|
+
required: ["query"]
|
|
49112
|
+
}
|
|
49113
|
+
}
|
|
49114
|
+
},
|
|
49115
|
+
describeCall: (args) => {
|
|
49116
|
+
const parts = [`"${args.query}"`];
|
|
49117
|
+
if (args.language) parts.push(`lang:${args.language}`);
|
|
49118
|
+
if (args.repository) parts.push(`in ${args.repository}`);
|
|
49119
|
+
return parts.join(" ");
|
|
49120
|
+
},
|
|
49121
|
+
permission: {
|
|
49122
|
+
scope: "session",
|
|
49123
|
+
riskLevel: "low",
|
|
49124
|
+
approvalMessage: `Search code in a GitHub repository via ${connector.displayName}`
|
|
49125
|
+
},
|
|
49126
|
+
execute: async (args) => {
|
|
49127
|
+
const resolved = resolveRepository(args.repository, connector);
|
|
49128
|
+
if (!resolved.success) {
|
|
49129
|
+
return { success: false, error: resolved.error };
|
|
49130
|
+
}
|
|
49131
|
+
const { owner, repo } = resolved.repo;
|
|
49132
|
+
try {
|
|
49133
|
+
const qualifiers = [`repo:${owner}/${repo}`];
|
|
49134
|
+
if (args.language) qualifiers.push(`language:${args.language}`);
|
|
49135
|
+
if (args.path) qualifiers.push(`path:${args.path}`);
|
|
49136
|
+
if (args.extension) qualifiers.push(`extension:${args.extension}`);
|
|
49137
|
+
const q = `${args.query} ${qualifiers.join(" ")}`;
|
|
49138
|
+
const perPage = Math.min(args.limit ?? 30, 100);
|
|
49139
|
+
const result = await githubFetch(
|
|
49140
|
+
connector,
|
|
49141
|
+
`/search/code`,
|
|
49142
|
+
{
|
|
49143
|
+
userId,
|
|
49144
|
+
// Request text-match fragments
|
|
49145
|
+
accept: "application/vnd.github.text-match+json",
|
|
49146
|
+
queryParams: { q, per_page: perPage }
|
|
49147
|
+
}
|
|
49148
|
+
);
|
|
49149
|
+
const matches = result.items.map((item) => ({
|
|
49150
|
+
file: item.path,
|
|
49151
|
+
fragment: item.text_matches?.[0]?.fragment
|
|
49152
|
+
}));
|
|
49153
|
+
return {
|
|
49154
|
+
success: true,
|
|
49155
|
+
matches,
|
|
49156
|
+
count: result.total_count,
|
|
49157
|
+
truncated: result.incomplete_results || result.total_count > perPage
|
|
49158
|
+
};
|
|
49159
|
+
} catch (error) {
|
|
49160
|
+
return {
|
|
49161
|
+
success: false,
|
|
49162
|
+
error: `Failed to search code: ${error instanceof Error ? error.message : String(error)}`
|
|
49163
|
+
};
|
|
49164
|
+
}
|
|
49165
|
+
}
|
|
49166
|
+
};
|
|
49167
|
+
}
|
|
49168
|
+
|
|
49169
|
+
// src/tools/github/readFile.ts
|
|
49170
|
+
function createGitHubReadFileTool(connector, userId) {
|
|
49171
|
+
return {
|
|
49172
|
+
definition: {
|
|
49173
|
+
type: "function",
|
|
49174
|
+
function: {
|
|
49175
|
+
name: "read_file",
|
|
49176
|
+
description: `Read file content from a GitHub repository.
|
|
49177
|
+
|
|
49178
|
+
USAGE:
|
|
49179
|
+
- Reads a file and returns content with line numbers
|
|
49180
|
+
- Supports line range selection with offset/limit for large files
|
|
49181
|
+
- By default reads up to 2000 lines from the beginning
|
|
49182
|
+
|
|
49183
|
+
EXAMPLES:
|
|
49184
|
+
- Read entire file: { "path": "src/index.ts" }
|
|
49185
|
+
- Read specific branch: { "path": "README.md", "ref": "develop" }
|
|
49186
|
+
- Read lines 100-200: { "path": "src/app.ts", "offset": 100, "limit": 100 }
|
|
49187
|
+
- Specific repo: { "repository": "owner/repo", "path": "package.json" }
|
|
49188
|
+
|
|
49189
|
+
NOTE: Files larger than 1MB are fetched via the Git Blob API. Very large files (>5MB) may be truncated.`,
|
|
49190
|
+
parameters: {
|
|
49191
|
+
type: "object",
|
|
49192
|
+
properties: {
|
|
49193
|
+
repository: {
|
|
49194
|
+
type: "string",
|
|
49195
|
+
description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
|
|
49196
|
+
},
|
|
49197
|
+
path: {
|
|
49198
|
+
type: "string",
|
|
49199
|
+
description: 'File path within the repository (e.g., "src/index.ts")'
|
|
49200
|
+
},
|
|
49201
|
+
ref: {
|
|
49202
|
+
type: "string",
|
|
49203
|
+
description: "Branch, tag, or commit SHA. Defaults to the repository's default branch."
|
|
49204
|
+
},
|
|
49205
|
+
offset: {
|
|
49206
|
+
type: "number",
|
|
49207
|
+
description: "Line number to start reading from (1-indexed). Only provide if the file is too large."
|
|
49208
|
+
},
|
|
49209
|
+
limit: {
|
|
49210
|
+
type: "number",
|
|
49211
|
+
description: "Number of lines to read (default: 2000). Only provide if the file is too large."
|
|
49212
|
+
}
|
|
49213
|
+
},
|
|
49214
|
+
required: ["path"]
|
|
49215
|
+
}
|
|
49216
|
+
}
|
|
49217
|
+
},
|
|
49218
|
+
describeCall: (args) => {
|
|
49219
|
+
const parts = [args.path];
|
|
49220
|
+
if (args.repository) parts.push(`in ${args.repository}`);
|
|
49221
|
+
if (args.ref) parts.push(`@${args.ref}`);
|
|
49222
|
+
if (args.offset && args.limit) parts.push(`[lines ${args.offset}-${args.offset + args.limit}]`);
|
|
49223
|
+
return parts.join(" ");
|
|
49224
|
+
},
|
|
49225
|
+
permission: {
|
|
49226
|
+
scope: "session",
|
|
49227
|
+
riskLevel: "low",
|
|
49228
|
+
approvalMessage: `Read a file from a GitHub repository via ${connector.displayName}`
|
|
49229
|
+
},
|
|
49230
|
+
execute: async (args) => {
|
|
49231
|
+
const resolved = resolveRepository(args.repository, connector);
|
|
49232
|
+
if (!resolved.success) {
|
|
49233
|
+
return { success: false, error: resolved.error };
|
|
49234
|
+
}
|
|
49235
|
+
const { owner, repo } = resolved.repo;
|
|
49236
|
+
try {
|
|
49237
|
+
let fileContent;
|
|
49238
|
+
let fileSha;
|
|
49239
|
+
let fileSize;
|
|
49240
|
+
const refParam = args.ref ? `?ref=${encodeURIComponent(args.ref)}` : "";
|
|
49241
|
+
const contentResp = await githubFetch(
|
|
49242
|
+
connector,
|
|
49243
|
+
`/repos/${owner}/${repo}/contents/${args.path}${refParam}`,
|
|
49244
|
+
{ userId }
|
|
49245
|
+
);
|
|
49246
|
+
if (contentResp.type !== "file") {
|
|
49247
|
+
return {
|
|
49248
|
+
success: false,
|
|
49249
|
+
error: `Path is not a file: ${args.path} (type: ${contentResp.type}). Use search_files to explore the repository.`,
|
|
49250
|
+
path: args.path
|
|
49251
|
+
};
|
|
49252
|
+
}
|
|
49253
|
+
fileSha = contentResp.sha;
|
|
49254
|
+
fileSize = contentResp.size;
|
|
49255
|
+
if (contentResp.content && contentResp.encoding === "base64") {
|
|
49256
|
+
fileContent = Buffer.from(contentResp.content, "base64").toString("utf-8");
|
|
49257
|
+
} else if (contentResp.git_url) {
|
|
49258
|
+
const blob = await githubFetch(
|
|
49259
|
+
connector,
|
|
49260
|
+
contentResp.git_url,
|
|
49261
|
+
{ userId }
|
|
49262
|
+
);
|
|
49263
|
+
fileContent = Buffer.from(blob.content, "base64").toString("utf-8");
|
|
49264
|
+
fileSize = blob.size;
|
|
49265
|
+
} else {
|
|
49266
|
+
return {
|
|
49267
|
+
success: false,
|
|
49268
|
+
error: `Cannot read file content: ${args.path} (no content or git_url in response)`,
|
|
49269
|
+
path: args.path
|
|
49270
|
+
};
|
|
49271
|
+
}
|
|
49272
|
+
const offset = args.offset ?? 1;
|
|
49273
|
+
const limit = args.limit ?? 2e3;
|
|
49274
|
+
const allLines = fileContent.split("\n");
|
|
49275
|
+
const totalLines = allLines.length;
|
|
49276
|
+
const startIndex = Math.max(0, offset - 1);
|
|
49277
|
+
const endIndex = Math.min(totalLines, startIndex + limit);
|
|
49278
|
+
const selectedLines = allLines.slice(startIndex, endIndex);
|
|
49279
|
+
const lineNumberWidth = String(endIndex).length;
|
|
49280
|
+
const formattedLines = selectedLines.map((line, i) => {
|
|
49281
|
+
const lineNum = startIndex + i + 1;
|
|
49282
|
+
const paddedNum = String(lineNum).padStart(lineNumberWidth, " ");
|
|
49283
|
+
const truncatedLine = line.length > 2e3 ? line.substring(0, 2e3) + "..." : line;
|
|
49284
|
+
return `${paddedNum} ${truncatedLine}`;
|
|
49285
|
+
});
|
|
49286
|
+
const truncated = endIndex < totalLines;
|
|
49287
|
+
const result = formattedLines.join("\n");
|
|
49288
|
+
return {
|
|
49289
|
+
success: true,
|
|
49290
|
+
content: result,
|
|
49291
|
+
path: args.path,
|
|
49292
|
+
size: fileSize,
|
|
49293
|
+
lines: totalLines,
|
|
49294
|
+
truncated,
|
|
49295
|
+
sha: fileSha
|
|
49296
|
+
};
|
|
49297
|
+
} catch (error) {
|
|
49298
|
+
return {
|
|
49299
|
+
success: false,
|
|
49300
|
+
error: `Failed to read file: ${error instanceof Error ? error.message : String(error)}`,
|
|
49301
|
+
path: args.path
|
|
49302
|
+
};
|
|
49303
|
+
}
|
|
49304
|
+
}
|
|
49305
|
+
};
|
|
49306
|
+
}
|
|
49307
|
+
|
|
49308
|
+
// src/tools/github/getPR.ts
|
|
49309
|
+
function createGetPRTool(connector, userId) {
|
|
49310
|
+
return {
|
|
49311
|
+
definition: {
|
|
49312
|
+
type: "function",
|
|
49313
|
+
function: {
|
|
49314
|
+
name: "get_pr",
|
|
49315
|
+
description: `Get full details of a pull request from a GitHub repository.
|
|
49316
|
+
|
|
49317
|
+
Returns: title, description, state, author, labels, reviewers, merge status, branches, file stats, and more.
|
|
49318
|
+
|
|
49319
|
+
EXAMPLES:
|
|
49320
|
+
- Get PR: { "pull_number": 123 }
|
|
49321
|
+
- Specific repo: { "repository": "owner/repo", "pull_number": 456 }`,
|
|
49322
|
+
parameters: {
|
|
49323
|
+
type: "object",
|
|
49324
|
+
properties: {
|
|
49325
|
+
repository: {
|
|
49326
|
+
type: "string",
|
|
49327
|
+
description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
|
|
49328
|
+
},
|
|
49329
|
+
pull_number: {
|
|
49330
|
+
type: "number",
|
|
49331
|
+
description: "Pull request number"
|
|
49332
|
+
}
|
|
49333
|
+
},
|
|
49334
|
+
required: ["pull_number"]
|
|
49335
|
+
}
|
|
49336
|
+
}
|
|
49337
|
+
},
|
|
49338
|
+
describeCall: (args) => {
|
|
49339
|
+
const parts = [`#${args.pull_number}`];
|
|
49340
|
+
if (args.repository) parts.push(`in ${args.repository}`);
|
|
49341
|
+
return parts.join(" ");
|
|
49342
|
+
},
|
|
49343
|
+
permission: {
|
|
49344
|
+
scope: "session",
|
|
49345
|
+
riskLevel: "low",
|
|
49346
|
+
approvalMessage: `Get pull request details from GitHub via ${connector.displayName}`
|
|
49347
|
+
},
|
|
49348
|
+
execute: async (args) => {
|
|
49349
|
+
const resolved = resolveRepository(args.repository, connector);
|
|
49350
|
+
if (!resolved.success) {
|
|
49351
|
+
return { success: false, error: resolved.error };
|
|
49352
|
+
}
|
|
49353
|
+
const { owner, repo } = resolved.repo;
|
|
49354
|
+
try {
|
|
49355
|
+
const pr = await githubFetch(
|
|
49356
|
+
connector,
|
|
49357
|
+
`/repos/${owner}/${repo}/pulls/${args.pull_number}`,
|
|
49358
|
+
{ userId }
|
|
49359
|
+
);
|
|
49360
|
+
return {
|
|
49361
|
+
success: true,
|
|
49362
|
+
data: {
|
|
49363
|
+
number: pr.number,
|
|
49364
|
+
title: pr.title,
|
|
49365
|
+
body: pr.body,
|
|
49366
|
+
state: pr.state,
|
|
49367
|
+
draft: pr.draft,
|
|
49368
|
+
author: pr.user.login,
|
|
49369
|
+
labels: pr.labels.map((l) => l.name),
|
|
49370
|
+
reviewers: pr.requested_reviewers.map((r) => r.login),
|
|
49371
|
+
mergeable: pr.mergeable,
|
|
49372
|
+
head: pr.head.ref,
|
|
49373
|
+
base: pr.base.ref,
|
|
49374
|
+
url: pr.html_url,
|
|
49375
|
+
created_at: pr.created_at,
|
|
49376
|
+
updated_at: pr.updated_at,
|
|
49377
|
+
additions: pr.additions,
|
|
49378
|
+
deletions: pr.deletions,
|
|
49379
|
+
changed_files: pr.changed_files
|
|
49380
|
+
}
|
|
49381
|
+
};
|
|
49382
|
+
} catch (error) {
|
|
49383
|
+
return {
|
|
49384
|
+
success: false,
|
|
49385
|
+
error: `Failed to get PR: ${error instanceof Error ? error.message : String(error)}`
|
|
49386
|
+
};
|
|
49387
|
+
}
|
|
49388
|
+
}
|
|
49389
|
+
};
|
|
49390
|
+
}
|
|
49391
|
+
|
|
49392
|
+
// src/tools/github/prFiles.ts
|
|
49393
|
+
function createPRFilesTool(connector, userId) {
|
|
49394
|
+
return {
|
|
49395
|
+
definition: {
|
|
49396
|
+
type: "function",
|
|
49397
|
+
function: {
|
|
49398
|
+
name: "pr_files",
|
|
49399
|
+
description: `Get the files changed in a pull request with diffs.
|
|
49400
|
+
|
|
49401
|
+
Returns: filename, status (added/modified/removed/renamed), additions, deletions, and patch (diff) content for each file.
|
|
49402
|
+
|
|
49403
|
+
EXAMPLES:
|
|
49404
|
+
- Get files: { "pull_number": 123 }
|
|
49405
|
+
- Specific repo: { "repository": "owner/repo", "pull_number": 456 }
|
|
49406
|
+
|
|
49407
|
+
NOTE: Very large diffs may be truncated by GitHub. Patch content may be absent for binary files.`,
|
|
49408
|
+
parameters: {
|
|
49409
|
+
type: "object",
|
|
49410
|
+
properties: {
|
|
49411
|
+
repository: {
|
|
49412
|
+
type: "string",
|
|
49413
|
+
description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
|
|
49414
|
+
},
|
|
49415
|
+
pull_number: {
|
|
49416
|
+
type: "number",
|
|
49417
|
+
description: "Pull request number"
|
|
49418
|
+
}
|
|
49419
|
+
},
|
|
49420
|
+
required: ["pull_number"]
|
|
49421
|
+
}
|
|
49422
|
+
}
|
|
49423
|
+
},
|
|
49424
|
+
describeCall: (args) => {
|
|
49425
|
+
const parts = [`files for #${args.pull_number}`];
|
|
49426
|
+
if (args.repository) parts.push(`in ${args.repository}`);
|
|
49427
|
+
return parts.join(" ");
|
|
49428
|
+
},
|
|
49429
|
+
permission: {
|
|
49430
|
+
scope: "session",
|
|
49431
|
+
riskLevel: "low",
|
|
49432
|
+
approvalMessage: `Get PR changed files from GitHub via ${connector.displayName}`
|
|
49433
|
+
},
|
|
49434
|
+
execute: async (args) => {
|
|
49435
|
+
const resolved = resolveRepository(args.repository, connector);
|
|
49436
|
+
if (!resolved.success) {
|
|
49437
|
+
return { success: false, error: resolved.error };
|
|
49438
|
+
}
|
|
49439
|
+
const { owner, repo } = resolved.repo;
|
|
49440
|
+
try {
|
|
49441
|
+
const files = await githubFetch(
|
|
49442
|
+
connector,
|
|
49443
|
+
`/repos/${owner}/${repo}/pulls/${args.pull_number}/files`,
|
|
49444
|
+
{
|
|
49445
|
+
userId,
|
|
49446
|
+
queryParams: { per_page: 100 }
|
|
49447
|
+
}
|
|
49448
|
+
);
|
|
49449
|
+
return {
|
|
49450
|
+
success: true,
|
|
49451
|
+
files: files.map((f) => ({
|
|
49452
|
+
filename: f.filename,
|
|
49453
|
+
status: f.status,
|
|
49454
|
+
additions: f.additions,
|
|
49455
|
+
deletions: f.deletions,
|
|
49456
|
+
changes: f.changes,
|
|
49457
|
+
patch: f.patch
|
|
49458
|
+
})),
|
|
49459
|
+
count: files.length
|
|
49460
|
+
};
|
|
49461
|
+
} catch (error) {
|
|
49462
|
+
return {
|
|
49463
|
+
success: false,
|
|
49464
|
+
error: `Failed to get PR files: ${error instanceof Error ? error.message : String(error)}`
|
|
49465
|
+
};
|
|
49466
|
+
}
|
|
49467
|
+
}
|
|
49468
|
+
};
|
|
49469
|
+
}
|
|
49470
|
+
|
|
49471
|
+
// src/tools/github/prComments.ts
|
|
49472
|
+
function createPRCommentsTool(connector, userId) {
|
|
49473
|
+
return {
|
|
49474
|
+
definition: {
|
|
49475
|
+
type: "function",
|
|
49476
|
+
function: {
|
|
49477
|
+
name: "pr_comments",
|
|
49478
|
+
description: `Get all comments and reviews on a pull request.
|
|
49479
|
+
|
|
49480
|
+
Returns a unified list of:
|
|
49481
|
+
- **review_comment**: Line-level comments on specific code (includes file path and line number)
|
|
49482
|
+
- **review**: Full reviews (approve/request changes/comment)
|
|
49483
|
+
- **comment**: General comments on the PR (issue-level)
|
|
49484
|
+
|
|
49485
|
+
All entries are sorted by creation date (oldest first).
|
|
49486
|
+
|
|
49487
|
+
EXAMPLES:
|
|
49488
|
+
- Get comments: { "pull_number": 123 }
|
|
49489
|
+
- Specific repo: { "repository": "owner/repo", "pull_number": 456 }`,
|
|
49490
|
+
parameters: {
|
|
49491
|
+
type: "object",
|
|
49492
|
+
properties: {
|
|
49493
|
+
repository: {
|
|
49494
|
+
type: "string",
|
|
49495
|
+
description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
|
|
49496
|
+
},
|
|
49497
|
+
pull_number: {
|
|
49498
|
+
type: "number",
|
|
49499
|
+
description: "Pull request number"
|
|
49500
|
+
}
|
|
49501
|
+
},
|
|
49502
|
+
required: ["pull_number"]
|
|
49503
|
+
}
|
|
49504
|
+
}
|
|
49505
|
+
},
|
|
49506
|
+
describeCall: (args) => {
|
|
49507
|
+
const parts = [`comments for #${args.pull_number}`];
|
|
49508
|
+
if (args.repository) parts.push(`in ${args.repository}`);
|
|
49509
|
+
return parts.join(" ");
|
|
49510
|
+
},
|
|
49511
|
+
permission: {
|
|
49512
|
+
scope: "session",
|
|
49513
|
+
riskLevel: "low",
|
|
49514
|
+
approvalMessage: `Get PR comments and reviews from GitHub via ${connector.displayName}`
|
|
49515
|
+
},
|
|
49516
|
+
execute: async (args) => {
|
|
49517
|
+
const resolved = resolveRepository(args.repository, connector);
|
|
49518
|
+
if (!resolved.success) {
|
|
49519
|
+
return { success: false, error: resolved.error };
|
|
49520
|
+
}
|
|
49521
|
+
const { owner, repo } = resolved.repo;
|
|
49522
|
+
try {
|
|
49523
|
+
const basePath = `/repos/${owner}/${repo}`;
|
|
49524
|
+
const queryOpts = { userId, queryParams: { per_page: 100 } };
|
|
49525
|
+
const [reviewComments, reviews, issueComments] = await Promise.all([
|
|
49526
|
+
githubFetch(
|
|
49527
|
+
connector,
|
|
49528
|
+
`${basePath}/pulls/${args.pull_number}/comments`,
|
|
49529
|
+
queryOpts
|
|
49530
|
+
),
|
|
49531
|
+
githubFetch(
|
|
49532
|
+
connector,
|
|
49533
|
+
`${basePath}/pulls/${args.pull_number}/reviews`,
|
|
49534
|
+
queryOpts
|
|
49535
|
+
),
|
|
49536
|
+
githubFetch(
|
|
49537
|
+
connector,
|
|
49538
|
+
`${basePath}/issues/${args.pull_number}/comments`,
|
|
49539
|
+
queryOpts
|
|
49540
|
+
)
|
|
49541
|
+
]);
|
|
49542
|
+
const allComments = [];
|
|
49543
|
+
for (const rc of reviewComments) {
|
|
49544
|
+
allComments.push({
|
|
49545
|
+
id: rc.id,
|
|
49546
|
+
type: "review_comment",
|
|
49547
|
+
author: rc.user.login,
|
|
49548
|
+
body: rc.body,
|
|
49549
|
+
created_at: rc.created_at,
|
|
49550
|
+
path: rc.path,
|
|
49551
|
+
line: rc.line ?? rc.original_line ?? void 0
|
|
49552
|
+
});
|
|
49553
|
+
}
|
|
49554
|
+
for (const r of reviews) {
|
|
49555
|
+
if (!r.body && r.state === "APPROVED") continue;
|
|
49556
|
+
allComments.push({
|
|
49557
|
+
id: r.id,
|
|
49558
|
+
type: "review",
|
|
49559
|
+
author: r.user.login,
|
|
49560
|
+
body: r.body || `[${r.state}]`,
|
|
49561
|
+
created_at: r.submitted_at,
|
|
49562
|
+
state: r.state
|
|
49563
|
+
});
|
|
49564
|
+
}
|
|
49565
|
+
for (const ic of issueComments) {
|
|
49566
|
+
allComments.push({
|
|
49567
|
+
id: ic.id,
|
|
49568
|
+
type: "comment",
|
|
49569
|
+
author: ic.user.login,
|
|
49570
|
+
body: ic.body,
|
|
49571
|
+
created_at: ic.created_at
|
|
49572
|
+
});
|
|
49573
|
+
}
|
|
49574
|
+
allComments.sort(
|
|
49575
|
+
(a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
|
|
49576
|
+
);
|
|
49577
|
+
return {
|
|
49578
|
+
success: true,
|
|
49579
|
+
comments: allComments,
|
|
49580
|
+
count: allComments.length
|
|
49581
|
+
};
|
|
49582
|
+
} catch (error) {
|
|
49583
|
+
return {
|
|
49584
|
+
success: false,
|
|
49585
|
+
error: `Failed to get PR comments: ${error instanceof Error ? error.message : String(error)}`
|
|
49586
|
+
};
|
|
49587
|
+
}
|
|
49588
|
+
}
|
|
49589
|
+
};
|
|
49590
|
+
}
|
|
49591
|
+
|
|
49592
|
+
// src/tools/github/createPR.ts
|
|
49593
|
+
function createCreatePRTool(connector, userId) {
|
|
49594
|
+
return {
|
|
49595
|
+
definition: {
|
|
49596
|
+
type: "function",
|
|
49597
|
+
function: {
|
|
49598
|
+
name: "create_pr",
|
|
49599
|
+
description: `Create a pull request on a GitHub repository.
|
|
49600
|
+
|
|
49601
|
+
USAGE:
|
|
49602
|
+
- Specify source branch (head) and target branch (base)
|
|
49603
|
+
- Optionally create as draft
|
|
49604
|
+
|
|
49605
|
+
EXAMPLES:
|
|
49606
|
+
- Create PR: { "title": "Add feature", "head": "feature-branch", "base": "main" }
|
|
49607
|
+
- Draft PR: { "title": "WIP: Refactor", "head": "refactor", "base": "develop", "draft": true }
|
|
49608
|
+
- With body: { "title": "Fix bug #42", "body": "Fixes the login issue\\n\\n## Changes\\n- Fixed auth flow", "head": "fix/42", "base": "main" }`,
|
|
49609
|
+
parameters: {
|
|
49610
|
+
type: "object",
|
|
49611
|
+
properties: {
|
|
49612
|
+
repository: {
|
|
49613
|
+
type: "string",
|
|
49614
|
+
description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
|
|
49615
|
+
},
|
|
49616
|
+
title: {
|
|
49617
|
+
type: "string",
|
|
49618
|
+
description: "Pull request title"
|
|
49619
|
+
},
|
|
49620
|
+
body: {
|
|
49621
|
+
type: "string",
|
|
49622
|
+
description: "Pull request description/body (Markdown supported)"
|
|
49623
|
+
},
|
|
49624
|
+
head: {
|
|
49625
|
+
type: "string",
|
|
49626
|
+
description: "Source branch name (the branch with your changes)"
|
|
49627
|
+
},
|
|
49628
|
+
base: {
|
|
49629
|
+
type: "string",
|
|
49630
|
+
description: 'Target branch name (the branch you want to merge into, e.g., "main")'
|
|
49631
|
+
},
|
|
49632
|
+
draft: {
|
|
49633
|
+
type: "boolean",
|
|
49634
|
+
description: "Create as a draft pull request (default: false)"
|
|
49635
|
+
}
|
|
49636
|
+
},
|
|
49637
|
+
required: ["title", "head", "base"]
|
|
49638
|
+
}
|
|
49639
|
+
}
|
|
49640
|
+
},
|
|
49641
|
+
describeCall: (args) => {
|
|
49642
|
+
const parts = [args.title];
|
|
49643
|
+
if (args.repository) parts.push(`in ${args.repository}`);
|
|
49644
|
+
return parts.join(" ");
|
|
49645
|
+
},
|
|
49646
|
+
permission: {
|
|
49647
|
+
scope: "session",
|
|
49648
|
+
riskLevel: "medium",
|
|
49649
|
+
approvalMessage: `Create a pull request on GitHub via ${connector.displayName}`
|
|
49650
|
+
},
|
|
49651
|
+
execute: async (args) => {
|
|
49652
|
+
const resolved = resolveRepository(args.repository, connector);
|
|
49653
|
+
if (!resolved.success) {
|
|
49654
|
+
return { success: false, error: resolved.error };
|
|
49655
|
+
}
|
|
49656
|
+
const { owner, repo } = resolved.repo;
|
|
49657
|
+
try {
|
|
49658
|
+
const pr = await githubFetch(
|
|
49659
|
+
connector,
|
|
49660
|
+
`/repos/${owner}/${repo}/pulls`,
|
|
49661
|
+
{
|
|
49662
|
+
method: "POST",
|
|
49663
|
+
userId,
|
|
49664
|
+
body: {
|
|
49665
|
+
title: args.title,
|
|
49666
|
+
body: args.body,
|
|
49667
|
+
head: args.head,
|
|
49668
|
+
base: args.base,
|
|
49669
|
+
draft: args.draft ?? false
|
|
49670
|
+
}
|
|
49671
|
+
}
|
|
49672
|
+
);
|
|
49673
|
+
return {
|
|
49674
|
+
success: true,
|
|
49675
|
+
data: {
|
|
49676
|
+
number: pr.number,
|
|
49677
|
+
url: pr.html_url,
|
|
49678
|
+
state: pr.state,
|
|
49679
|
+
title: pr.title
|
|
49680
|
+
}
|
|
49681
|
+
};
|
|
49682
|
+
} catch (error) {
|
|
49683
|
+
return {
|
|
49684
|
+
success: false,
|
|
49685
|
+
error: `Failed to create PR: ${error instanceof Error ? error.message : String(error)}`
|
|
49686
|
+
};
|
|
49687
|
+
}
|
|
49688
|
+
}
|
|
49689
|
+
};
|
|
49690
|
+
}
|
|
49691
|
+
|
|
49692
|
+
// src/tools/github/register.ts
|
|
49693
|
+
function registerGitHubTools() {
|
|
49694
|
+
ConnectorTools.registerService("github", (connector, userId) => {
|
|
49695
|
+
return [
|
|
49696
|
+
createSearchFilesTool(connector, userId),
|
|
49697
|
+
createSearchCodeTool(connector, userId),
|
|
49698
|
+
createGitHubReadFileTool(connector, userId),
|
|
49699
|
+
createGetPRTool(connector, userId),
|
|
49700
|
+
createPRFilesTool(connector, userId),
|
|
49701
|
+
createPRCommentsTool(connector, userId),
|
|
49702
|
+
createCreatePRTool(connector, userId)
|
|
49703
|
+
];
|
|
49704
|
+
});
|
|
49705
|
+
}
|
|
49706
|
+
|
|
49707
|
+
// src/tools/github/index.ts
|
|
49708
|
+
registerGitHubTools();
|
|
49709
|
+
|
|
48640
49710
|
// src/tools/registry.generated.ts
|
|
48641
49711
|
var toolRegistry = [
|
|
48642
49712
|
{
|
|
@@ -48690,7 +49760,7 @@ var toolRegistry = [
|
|
|
48690
49760
|
displayName: "Read File",
|
|
48691
49761
|
category: "filesystem",
|
|
48692
49762
|
description: "Read content from a file on the local filesystem.",
|
|
48693
|
-
tool:
|
|
49763
|
+
tool: readFile5,
|
|
48694
49764
|
safeByDefault: true
|
|
48695
49765
|
},
|
|
48696
49766
|
{
|
|
@@ -48699,7 +49769,7 @@ var toolRegistry = [
|
|
|
48699
49769
|
displayName: "Write File",
|
|
48700
49770
|
category: "filesystem",
|
|
48701
49771
|
description: "Write content to a file on the local filesystem.",
|
|
48702
|
-
tool:
|
|
49772
|
+
tool: writeFile5,
|
|
48703
49773
|
safeByDefault: false
|
|
48704
49774
|
},
|
|
48705
49775
|
{
|
|
@@ -48928,8 +49998,8 @@ var ToolRegistry = class {
|
|
|
48928
49998
|
|
|
48929
49999
|
// src/tools/index.ts
|
|
48930
50000
|
var developerTools = [
|
|
48931
|
-
|
|
48932
|
-
|
|
50001
|
+
readFile5,
|
|
50002
|
+
writeFile5,
|
|
48933
50003
|
editFile,
|
|
48934
50004
|
glob,
|
|
48935
50005
|
grep,
|
|
@@ -49153,7 +50223,8 @@ exports.ExternalDependencyHandler = ExternalDependencyHandler;
|
|
|
49153
50223
|
exports.FileAgentDefinitionStorage = FileAgentDefinitionStorage;
|
|
49154
50224
|
exports.FileConnectorStorage = FileConnectorStorage;
|
|
49155
50225
|
exports.FileContextStorage = FileContextStorage;
|
|
49156
|
-
exports.FileMediaOutputHandler =
|
|
50226
|
+
exports.FileMediaOutputHandler = FileMediaStorage;
|
|
50227
|
+
exports.FileMediaStorage = FileMediaStorage;
|
|
49157
50228
|
exports.FilePersistentInstructionsStorage = FilePersistentInstructionsStorage;
|
|
49158
50229
|
exports.FileStorage = FileStorage;
|
|
49159
50230
|
exports.HookManager = HookManager;
|
|
@@ -49259,11 +50330,15 @@ exports.createAgentStorage = createAgentStorage;
|
|
|
49259
50330
|
exports.createAuthenticatedFetch = createAuthenticatedFetch;
|
|
49260
50331
|
exports.createBashTool = createBashTool;
|
|
49261
50332
|
exports.createConnectorFromTemplate = createConnectorFromTemplate;
|
|
50333
|
+
exports.createCreatePRTool = createCreatePRTool;
|
|
49262
50334
|
exports.createEditFileTool = createEditFileTool;
|
|
49263
50335
|
exports.createEstimator = createEstimator;
|
|
49264
50336
|
exports.createExecuteJavaScriptTool = createExecuteJavaScriptTool;
|
|
49265
50337
|
exports.createFileAgentDefinitionStorage = createFileAgentDefinitionStorage;
|
|
49266
50338
|
exports.createFileContextStorage = createFileContextStorage;
|
|
50339
|
+
exports.createFileMediaStorage = createFileMediaStorage;
|
|
50340
|
+
exports.createGetPRTool = createGetPRTool;
|
|
50341
|
+
exports.createGitHubReadFileTool = createGitHubReadFileTool;
|
|
49267
50342
|
exports.createGlobTool = createGlobTool;
|
|
49268
50343
|
exports.createGrepTool = createGrepTool;
|
|
49269
50344
|
exports.createImageGenerationTool = createImageGenerationTool;
|
|
@@ -49271,9 +50346,13 @@ exports.createImageProvider = createImageProvider;
|
|
|
49271
50346
|
exports.createListDirectoryTool = createListDirectoryTool;
|
|
49272
50347
|
exports.createMessageWithImages = createMessageWithImages;
|
|
49273
50348
|
exports.createMetricsCollector = createMetricsCollector;
|
|
50349
|
+
exports.createPRCommentsTool = createPRCommentsTool;
|
|
50350
|
+
exports.createPRFilesTool = createPRFilesTool;
|
|
49274
50351
|
exports.createPlan = createPlan;
|
|
49275
50352
|
exports.createProvider = createProvider;
|
|
49276
50353
|
exports.createReadFileTool = createReadFileTool;
|
|
50354
|
+
exports.createSearchCodeTool = createSearchCodeTool;
|
|
50355
|
+
exports.createSearchFilesTool = createSearchFilesTool;
|
|
49277
50356
|
exports.createSpeechToTextTool = createSpeechToTextTool;
|
|
49278
50357
|
exports.createTask = createTask;
|
|
49279
50358
|
exports.createTextMessage = createTextMessage;
|
|
@@ -49313,6 +50392,7 @@ exports.getImageModelInfo = getImageModelInfo;
|
|
|
49313
50392
|
exports.getImageModelsByVendor = getImageModelsByVendor;
|
|
49314
50393
|
exports.getImageModelsWithFeature = getImageModelsWithFeature;
|
|
49315
50394
|
exports.getMediaOutputHandler = getMediaOutputHandler;
|
|
50395
|
+
exports.getMediaStorage = getMediaStorage;
|
|
49316
50396
|
exports.getModelInfo = getModelInfo;
|
|
49317
50397
|
exports.getModelsByVendor = getModelsByVendor;
|
|
49318
50398
|
exports.getNextExecutableTasks = getNextExecutableTasks;
|
|
@@ -49335,6 +50415,7 @@ exports.getToolsByCategory = getToolsByCategory;
|
|
|
49335
50415
|
exports.getToolsRequiringConnector = getToolsRequiringConnector;
|
|
49336
50416
|
exports.getVendorAuthTemplate = getVendorAuthTemplate;
|
|
49337
50417
|
exports.getVendorColor = getVendorColor;
|
|
50418
|
+
exports.getVendorDefaultBaseURL = getVendorDefaultBaseURL;
|
|
49338
50419
|
exports.getVendorInfo = getVendorInfo;
|
|
49339
50420
|
exports.getVendorLogo = getVendorLogo;
|
|
49340
50421
|
exports.getVendorLogoCdnUrl = getVendorLogoCdnUrl;
|
|
@@ -49373,15 +50454,18 @@ exports.listVendors = listVendors;
|
|
|
49373
50454
|
exports.listVendorsByAuthType = listVendorsByAuthType;
|
|
49374
50455
|
exports.listVendorsByCategory = listVendorsByCategory;
|
|
49375
50456
|
exports.listVendorsWithLogos = listVendorsWithLogos;
|
|
50457
|
+
exports.parseRepository = parseRepository;
|
|
49376
50458
|
exports.readClipboardImage = readClipboardImage;
|
|
49377
|
-
exports.readFile =
|
|
50459
|
+
exports.readFile = readFile5;
|
|
49378
50460
|
exports.registerScrapeProvider = registerScrapeProvider;
|
|
49379
50461
|
exports.resolveConnector = resolveConnector;
|
|
49380
50462
|
exports.resolveDependencies = resolveDependencies;
|
|
50463
|
+
exports.resolveRepository = resolveRepository;
|
|
49381
50464
|
exports.retryWithBackoff = retryWithBackoff;
|
|
49382
50465
|
exports.scopeEquals = scopeEquals;
|
|
49383
50466
|
exports.scopeMatches = scopeMatches;
|
|
49384
50467
|
exports.setMediaOutputHandler = setMediaOutputHandler;
|
|
50468
|
+
exports.setMediaStorage = setMediaStorage;
|
|
49385
50469
|
exports.setMetricsCollector = setMetricsCollector;
|
|
49386
50470
|
exports.simpleTokenEstimator = simpleTokenEstimator;
|
|
49387
50471
|
exports.toConnectorOptions = toConnectorOptions;
|
|
@@ -49389,6 +50473,6 @@ exports.toolRegistry = toolRegistry;
|
|
|
49389
50473
|
exports.tools = tools_exports;
|
|
49390
50474
|
exports.updateTaskStatus = updateTaskStatus;
|
|
49391
50475
|
exports.validatePath = validatePath;
|
|
49392
|
-
exports.writeFile =
|
|
50476
|
+
exports.writeFile = writeFile5;
|
|
49393
50477
|
//# sourceMappingURL=index.cjs.map
|
|
49394
50478
|
//# sourceMappingURL=index.cjs.map
|