@everworker/oneringai 0.1.2 → 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/dist/index.cjs CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  var crypto2 = require('crypto');
4
4
  var jose = require('jose');
5
- var fs15 = require('fs');
5
+ var fs16 = require('fs');
6
6
  var eventemitter3 = require('eventemitter3');
7
- var path3 = require('path');
8
- var os = require('os');
9
- var OpenAI2 = require('openai');
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 fs14 = require('fs/promises');
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 fs15__namespace = /*#__PURE__*/_interopNamespace(fs15);
48
- var path3__namespace = /*#__PURE__*/_interopNamespace(path3);
49
- var os__namespace = /*#__PURE__*/_interopNamespace(os);
50
- var OpenAI2__default = /*#__PURE__*/_interopDefault(OpenAI2);
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 fs14__namespace = /*#__PURE__*/_interopNamespace(fs14);
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 = fs15__namespace.readFileSync(config.privateKeyPath, "utf8");
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 = path3__namespace.dirname(filePath);
1285
- if (!fs15__namespace.existsSync(dir)) {
1286
- fs15__namespace.mkdirSync(dir, { recursive: true });
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 = fs15__namespace.createWriteStream(filePath, {
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, fs18, exportName) {
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, fs18[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 fs18 = __require("fs");
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(stat5, path6, options) {
14595
- if (!stat5.isSymbolicLink() && !stat5.isFile()) {
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
- fs18.stat(path6, function(er, stat5) {
14602
- cb(er, er ? false : checkStat(stat5, path6, options));
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(fs18.statSync(path6), path6, options);
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 fs18 = __require("fs");
14616
+ var fs17 = __require("fs");
14617
14617
  function isexe(path6, options, cb) {
14618
- fs18.stat(path6, function(er, stat5) {
14619
- cb(er, er ? false : checkStat(stat5, options));
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(fs18.statSync(path6), options);
14623
+ return checkStat(fs17.statSync(path6), options);
14624
14624
  }
14625
- function checkStat(stat5, options) {
14626
- return stat5.isFile() && checkMode(stat5, options);
14625
+ function checkStat(stat6, options) {
14626
+ return stat6.isFile() && checkMode(stat6, options);
14627
14627
  }
14628
- function checkMode(stat5, options) {
14629
- var mod = stat5.mode;
14630
- var uid = stat5.uid;
14631
- var gid = stat5.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 fs18 = __require("fs");
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 = fs18.openSync(command, "r");
14913
- fs18.readSync(fd, buffer, 0, size, 0);
14914
- fs18.closeSync(fd);
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());
@@ -15089,8 +15089,8 @@ var DEFAULT_ALLOWLIST = [
15089
15089
  "context_list",
15090
15090
  // Persistent instructions tools
15091
15091
  "instructions_set",
15092
- "instructions_append",
15093
- "instructions_get",
15092
+ "instructions_remove",
15093
+ "instructions_list",
15094
15094
  "instructions_clear",
15095
15095
  // Meta-tools (internal coordination)
15096
15096
  "_start_planning",
@@ -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
- constructor() {
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 result = await breaker.execute(async () => {
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 path3.join(appData, "oneringai", "agents");
19693
+ return path2.join(appData, "oneringai", "agents");
19657
19694
  }
19658
19695
  }
19659
- return path3.join(os.homedir(), ".oneringai", "agents");
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";
@@ -19664,22 +19701,45 @@ function sanitizeAgentId(agentId) {
19664
19701
  var FilePersistentInstructionsStorage = class {
19665
19702
  directory;
19666
19703
  filePath;
19704
+ legacyFilePath;
19667
19705
  agentId;
19668
19706
  constructor(config) {
19669
19707
  this.agentId = config.agentId;
19670
19708
  const sanitizedId = sanitizeAgentId(config.agentId);
19671
19709
  const baseDir = config.baseDirectory ?? getDefaultBaseDirectory();
19672
- const filename = config.filename ?? "custom_instructions.md";
19673
- this.directory = path3.join(baseDir, sanitizedId);
19674
- this.filePath = path3.join(this.directory, filename);
19710
+ const filename = config.filename ?? "custom_instructions.json";
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");
19675
19714
  }
19676
19715
  /**
19677
- * Load instructions from file
19716
+ * Load instruction entries from file.
19717
+ * Falls back to legacy .md file migration if JSON not found.
19678
19718
  */
19679
19719
  async load() {
19680
19720
  try {
19681
- const content = await fs15.promises.readFile(this.filePath, "utf-8");
19682
- return content.trim() || null;
19721
+ const raw = await fs16.promises.readFile(this.filePath, "utf-8");
19722
+ const data = JSON.parse(raw);
19723
+ if (data.version === 2 && Array.isArray(data.entries)) {
19724
+ return data.entries.length > 0 ? data.entries : null;
19725
+ }
19726
+ return null;
19727
+ } catch (error) {
19728
+ if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) {
19729
+ throw error;
19730
+ }
19731
+ }
19732
+ try {
19733
+ const content = await fs16.promises.readFile(this.legacyFilePath, "utf-8");
19734
+ const trimmed = content.trim();
19735
+ if (!trimmed) return null;
19736
+ const now = Date.now();
19737
+ return [{
19738
+ id: "legacy_instructions",
19739
+ content: trimmed,
19740
+ createdAt: now,
19741
+ updatedAt: now
19742
+ }];
19683
19743
  } catch (error) {
19684
19744
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
19685
19745
  return null;
@@ -19688,44 +19748,56 @@ var FilePersistentInstructionsStorage = class {
19688
19748
  }
19689
19749
  }
19690
19750
  /**
19691
- * Save instructions to file
19692
- * Creates directory if it doesn't exist
19751
+ * Save instruction entries to file as JSON.
19752
+ * Creates directory if it doesn't exist.
19753
+ * Cleans up legacy .md file if present.
19693
19754
  */
19694
- async save(content) {
19755
+ async save(entries) {
19695
19756
  await this.ensureDirectory();
19757
+ const data = {
19758
+ version: 2,
19759
+ entries
19760
+ };
19696
19761
  const tempPath = `${this.filePath}.tmp`;
19697
19762
  try {
19698
- await fs15.promises.writeFile(tempPath, content, "utf-8");
19699
- await fs15.promises.rename(tempPath, this.filePath);
19763
+ await fs16.promises.writeFile(tempPath, JSON.stringify(data, null, 2), "utf-8");
19764
+ await fs16.promises.rename(tempPath, this.filePath);
19700
19765
  } catch (error) {
19701
19766
  try {
19702
- await fs15.promises.unlink(tempPath);
19767
+ await fs16.promises.unlink(tempPath);
19703
19768
  } catch {
19704
19769
  }
19705
19770
  throw error;
19706
19771
  }
19772
+ await this.removeLegacyFile();
19707
19773
  }
19708
19774
  /**
19709
- * Delete instructions file
19775
+ * Delete instructions file (and legacy .md if exists)
19710
19776
  */
19711
19777
  async delete() {
19712
19778
  try {
19713
- await fs15.promises.unlink(this.filePath);
19779
+ await fs16.promises.unlink(this.filePath);
19714
19780
  } catch (error) {
19715
19781
  if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
19716
19782
  throw error;
19717
19783
  }
19718
19784
  }
19785
+ await this.removeLegacyFile();
19719
19786
  }
19720
19787
  /**
19721
- * Check if instructions file exists
19788
+ * Check if instructions file exists (JSON or legacy .md)
19722
19789
  */
19723
19790
  async exists() {
19724
19791
  try {
19725
- await fs15.promises.access(this.filePath);
19792
+ await fs16.promises.access(this.filePath);
19726
19793
  return true;
19727
19794
  } catch {
19728
- return false;
19795
+ try {
19796
+ await fs16.promises.access(this.legacyFilePath);
19797
+ return true;
19798
+ } catch {
19799
+ return false;
19800
+ }
19729
19801
  }
19730
19802
  }
19731
19803
  /**
@@ -19745,65 +19817,86 @@ var FilePersistentInstructionsStorage = class {
19745
19817
  */
19746
19818
  async ensureDirectory() {
19747
19819
  try {
19748
- await fs15.promises.mkdir(this.directory, { recursive: true });
19820
+ await fs16.promises.mkdir(this.directory, { recursive: true });
19749
19821
  } catch (error) {
19750
19822
  if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
19751
19823
  throw error;
19752
19824
  }
19753
19825
  }
19754
19826
  }
19827
+ /**
19828
+ * Remove legacy .md file if it exists
19829
+ */
19830
+ async removeLegacyFile() {
19831
+ try {
19832
+ await fs16.promises.unlink(this.legacyFilePath);
19833
+ } catch (error) {
19834
+ if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
19835
+ console.warn(`Failed to remove legacy instructions file: ${this.legacyFilePath}`);
19836
+ }
19837
+ }
19838
+ }
19755
19839
  };
19756
19840
 
19757
19841
  // src/core/context-nextgen/plugins/PersistentInstructionsPluginNextGen.ts
19758
- var DEFAULT_MAX_LENGTH = 5e4;
19842
+ var DEFAULT_MAX_TOTAL_LENGTH = 5e4;
19843
+ var DEFAULT_MAX_ENTRIES = 50;
19844
+ var KEY_MAX_LENGTH = 100;
19845
+ var KEY_PATTERN = /^[a-zA-Z0-9_-]+$/;
19759
19846
  var PERSISTENT_INSTRUCTIONS_INSTRUCTIONS = `Persistent Instructions are stored on disk and survive across sessions.
19847
+ Each instruction is a keyed entry that can be independently managed.
19760
19848
 
19761
19849
  **To modify:**
19762
- - \`instructions_set(content)\`: Replace all instructions
19763
- - \`instructions_append(section)\`: Add a section
19764
- - \`instructions_clear(confirm: true)\`: Remove all (destructive!)
19850
+ - \`instructions_set(key, content)\`: Add or update a single instruction by key
19851
+ - \`instructions_remove(key)\`: Remove a single instruction by key
19852
+ - \`instructions_list()\`: List all instructions with keys and content
19853
+ - \`instructions_clear(confirm: true)\`: Remove all instructions (destructive!)
19765
19854
 
19766
19855
  **Use for:** Agent personality, user preferences, learned rules, guidelines.`;
19767
19856
  var instructionsSetDefinition = {
19768
19857
  type: "function",
19769
19858
  function: {
19770
19859
  name: "instructions_set",
19771
- description: `Set or replace all custom instructions. Persists across sessions.
19772
- IMPORTANT: This replaces ALL existing instructions.`,
19860
+ description: `Add or update a single persistent instruction by key. Persists across sessions.
19861
+ If the key exists, it will be updated. If not, a new entry is created.`,
19773
19862
  parameters: {
19774
19863
  type: "object",
19775
19864
  properties: {
19865
+ key: {
19866
+ type: "string",
19867
+ description: "Unique key for the instruction (alphanumeric, dash, underscore; max 100 chars)"
19868
+ },
19776
19869
  content: {
19777
19870
  type: "string",
19778
- description: "Full instructions content (markdown supported)"
19871
+ description: "Instruction content (markdown supported)"
19779
19872
  }
19780
19873
  },
19781
- required: ["content"]
19874
+ required: ["key", "content"]
19782
19875
  }
19783
19876
  }
19784
19877
  };
19785
- var instructionsAppendDefinition = {
19878
+ var instructionsRemoveDefinition = {
19786
19879
  type: "function",
19787
19880
  function: {
19788
- name: "instructions_append",
19789
- description: "Append a section to existing instructions.",
19881
+ name: "instructions_remove",
19882
+ description: "Remove a single persistent instruction by key.",
19790
19883
  parameters: {
19791
19884
  type: "object",
19792
19885
  properties: {
19793
- section: {
19886
+ key: {
19794
19887
  type: "string",
19795
- description: "Section to append (will add newlines before)"
19888
+ description: "Key of the instruction to remove"
19796
19889
  }
19797
19890
  },
19798
- required: ["section"]
19891
+ required: ["key"]
19799
19892
  }
19800
19893
  }
19801
19894
  };
19802
- var instructionsGetDefinition = {
19895
+ var instructionsListDefinition = {
19803
19896
  type: "function",
19804
19897
  function: {
19805
- name: "instructions_get",
19806
- description: "Get current custom instructions.",
19898
+ name: "instructions_list",
19899
+ description: "List all persistent instructions with their keys and content.",
19807
19900
  parameters: {
19808
19901
  type: "object",
19809
19902
  properties: {},
@@ -19815,7 +19908,7 @@ var instructionsClearDefinition = {
19815
19908
  type: "function",
19816
19909
  function: {
19817
19910
  name: "instructions_clear",
19818
- description: "Clear all custom instructions (DESTRUCTIVE). Requires confirmation.",
19911
+ description: "Clear all persistent instructions (DESTRUCTIVE). Requires confirmation.",
19819
19912
  parameters: {
19820
19913
  type: "object",
19821
19914
  properties: {
@@ -19828,13 +19921,22 @@ var instructionsClearDefinition = {
19828
19921
  }
19829
19922
  }
19830
19923
  };
19924
+ function validateKey(key) {
19925
+ if (typeof key !== "string") return "Key must be a string";
19926
+ const trimmed = key.trim();
19927
+ if (trimmed.length === 0) return "Key cannot be empty";
19928
+ if (trimmed.length > KEY_MAX_LENGTH) return `Key exceeds maximum length (${KEY_MAX_LENGTH} chars)`;
19929
+ if (!KEY_PATTERN.test(trimmed)) return "Key must contain only alphanumeric characters, dashes, and underscores";
19930
+ return null;
19931
+ }
19831
19932
  var PersistentInstructionsPluginNextGen = class {
19832
19933
  name = "persistent_instructions";
19833
- _content = null;
19934
+ _entries = /* @__PURE__ */ new Map();
19834
19935
  _initialized = false;
19835
19936
  _destroyed = false;
19836
19937
  storage;
19837
- maxLength;
19938
+ maxTotalLength;
19939
+ maxEntries;
19838
19940
  agentId;
19839
19941
  estimator = simpleTokenEstimator;
19840
19942
  _tokenCache = null;
@@ -19844,7 +19946,8 @@ var PersistentInstructionsPluginNextGen = class {
19844
19946
  throw new Error("PersistentInstructionsPluginNextGen requires agentId");
19845
19947
  }
19846
19948
  this.agentId = config.agentId;
19847
- this.maxLength = config.maxLength ?? DEFAULT_MAX_LENGTH;
19949
+ this.maxTotalLength = config.maxTotalLength ?? DEFAULT_MAX_TOTAL_LENGTH;
19950
+ this.maxEntries = config.maxEntries ?? DEFAULT_MAX_ENTRIES;
19848
19951
  this.storage = config.storage ?? new FilePersistentInstructionsStorage({
19849
19952
  agentId: config.agentId
19850
19953
  });
@@ -19857,14 +19960,16 @@ var PersistentInstructionsPluginNextGen = class {
19857
19960
  }
19858
19961
  async getContent() {
19859
19962
  await this.ensureInitialized();
19860
- if (!this._content) {
19963
+ if (this._entries.size === 0) {
19964
+ this._tokenCache = 0;
19861
19965
  return null;
19862
19966
  }
19863
- this._tokenCache = this.estimator.estimateTokens(this._content);
19864
- return this._content;
19967
+ const rendered = this.renderContent();
19968
+ this._tokenCache = this.estimator.estimateTokens(rendered);
19969
+ return rendered;
19865
19970
  }
19866
19971
  getContents() {
19867
- return this._content;
19972
+ return new Map(this._entries);
19868
19973
  }
19869
19974
  getTokenSize() {
19870
19975
  return this._tokenCache ?? 0;
@@ -19884,32 +19989,54 @@ var PersistentInstructionsPluginNextGen = class {
19884
19989
  getTools() {
19885
19990
  return [
19886
19991
  this.createInstructionsSetTool(),
19887
- this.createInstructionsAppendTool(),
19888
- this.createInstructionsGetTool(),
19992
+ this.createInstructionsRemoveTool(),
19993
+ this.createInstructionsListTool(),
19889
19994
  this.createInstructionsClearTool()
19890
19995
  ];
19891
19996
  }
19892
19997
  destroy() {
19893
19998
  if (this._destroyed) return;
19894
- this._content = null;
19999
+ this._entries.clear();
19895
20000
  this._destroyed = true;
19896
20001
  this._tokenCache = null;
19897
20002
  }
19898
20003
  getState() {
19899
20004
  return {
19900
- content: this._content,
19901
- agentId: this.agentId
20005
+ entries: Array.from(this._entries.values()),
20006
+ agentId: this.agentId,
20007
+ version: 2
19902
20008
  };
19903
20009
  }
19904
20010
  restoreState(state) {
20011
+ if (!state || typeof state !== "object") return;
19905
20012
  const s = state;
19906
- if (!s) return;
19907
- this._content = s.content;
19908
- this._initialized = true;
19909
- this._tokenCache = null;
20013
+ if ("version" in s && s.version === 2 && Array.isArray(s.entries)) {
20014
+ this._entries.clear();
20015
+ for (const entry of s.entries) {
20016
+ this._entries.set(entry.id, entry);
20017
+ }
20018
+ this._initialized = true;
20019
+ this._tokenCache = null;
20020
+ return;
20021
+ }
20022
+ if ("content" in s) {
20023
+ this._entries.clear();
20024
+ const content = s.content;
20025
+ if (content) {
20026
+ const now = Date.now();
20027
+ this._entries.set("legacy_instructions", {
20028
+ id: "legacy_instructions",
20029
+ content,
20030
+ createdAt: now,
20031
+ updatedAt: now
20032
+ });
20033
+ }
20034
+ this._initialized = true;
20035
+ this._tokenCache = null;
20036
+ }
19910
20037
  }
19911
20038
  // ============================================================================
19912
- // Content Management
20039
+ // Public API
19913
20040
  // ============================================================================
19914
20041
  /**
19915
20042
  * Initialize by loading from storage (called lazily)
@@ -19917,66 +20044,99 @@ var PersistentInstructionsPluginNextGen = class {
19917
20044
  async initialize() {
19918
20045
  if (this._initialized || this._destroyed) return;
19919
20046
  try {
19920
- this._content = await this.storage.load();
20047
+ const entries = await this.storage.load();
20048
+ this._entries.clear();
20049
+ if (entries) {
20050
+ for (const entry of entries) {
20051
+ this._entries.set(entry.id, entry);
20052
+ }
20053
+ }
19921
20054
  this._initialized = true;
19922
20055
  } catch (error) {
19923
20056
  console.warn(`Failed to load persistent instructions for agent '${this.agentId}':`, error);
19924
- this._content = null;
20057
+ this._entries.clear();
19925
20058
  this._initialized = true;
19926
20059
  }
19927
20060
  this._tokenCache = null;
19928
20061
  }
19929
20062
  /**
19930
- * Set entire instructions content (replaces existing)
20063
+ * Add or update an instruction entry by key
19931
20064
  */
19932
- async set(content) {
20065
+ async set(key, content) {
19933
20066
  this.assertNotDestroyed();
19934
- if (content.length > this.maxLength) {
20067
+ await this.ensureInitialized();
20068
+ const keyError = validateKey(key);
20069
+ if (keyError) return false;
20070
+ const trimmedContent = content.trim();
20071
+ if (trimmedContent.length === 0) return false;
20072
+ if (!this._entries.has(key) && this._entries.size >= this.maxEntries) {
19935
20073
  return false;
19936
20074
  }
19937
- this._content = content.trim() || null;
19938
- if (this._content) {
19939
- await this.storage.save(this._content);
19940
- } else {
19941
- await this.storage.delete();
20075
+ const currentTotal = this.calculateTotalContentLength();
20076
+ const existingLength = this._entries.get(key)?.content.length ?? 0;
20077
+ const newTotal = currentTotal - existingLength + trimmedContent.length;
20078
+ if (newTotal > this.maxTotalLength) {
20079
+ return false;
19942
20080
  }
20081
+ const now = Date.now();
20082
+ const existing = this._entries.get(key);
20083
+ this._entries.set(key, {
20084
+ id: key,
20085
+ content: trimmedContent,
20086
+ createdAt: existing?.createdAt ?? now,
20087
+ updatedAt: now
20088
+ });
20089
+ await this.persistToStorage();
19943
20090
  this._tokenCache = null;
19944
20091
  return true;
19945
20092
  }
19946
20093
  /**
19947
- * Append a section to existing instructions
20094
+ * Remove an instruction entry by key
19948
20095
  */
19949
- async append(section) {
20096
+ async remove(key) {
19950
20097
  this.assertNotDestroyed();
19951
20098
  await this.ensureInitialized();
19952
- const trimmedSection = section.trim();
19953
- if (!trimmedSection) return true;
19954
- const currentContent = this._content || "";
19955
- const newContent = currentContent ? `${currentContent}
19956
-
19957
- ${trimmedSection}` : trimmedSection;
19958
- if (newContent.length > this.maxLength) {
19959
- return false;
20099
+ if (!this._entries.has(key)) return false;
20100
+ this._entries.delete(key);
20101
+ if (this._entries.size === 0) {
20102
+ await this.storage.delete();
20103
+ } else {
20104
+ await this.persistToStorage();
19960
20105
  }
19961
- this._content = newContent;
19962
- await this.storage.save(this._content);
19963
20106
  this._tokenCache = null;
19964
20107
  return true;
19965
20108
  }
19966
20109
  /**
19967
- * Get current content
20110
+ * Get one entry by key, or all entries if no key provided
19968
20111
  */
19969
- async get() {
20112
+ async get(key) {
19970
20113
  this.assertNotDestroyed();
19971
20114
  await this.ensureInitialized();
19972
- return this._content;
20115
+ if (key !== void 0) {
20116
+ return this._entries.get(key) ?? null;
20117
+ }
20118
+ if (this._entries.size === 0) return null;
20119
+ return this.getSortedEntries();
19973
20120
  }
19974
20121
  /**
19975
- * Clear all instructions
20122
+ * List metadata for all entries
20123
+ */
20124
+ async list() {
20125
+ this.assertNotDestroyed();
20126
+ await this.ensureInitialized();
20127
+ return this.getSortedEntries().map((entry) => ({
20128
+ key: entry.id,
20129
+ contentLength: entry.content.length,
20130
+ createdAt: entry.createdAt,
20131
+ updatedAt: entry.updatedAt
20132
+ }));
20133
+ }
20134
+ /**
20135
+ * Clear all instruction entries
19976
20136
  */
19977
20137
  async clear() {
19978
20138
  this.assertNotDestroyed();
19979
- this._content = null;
20139
+ this._entries.clear();
19980
20140
  await this.storage.delete();
19981
20141
  this._tokenCache = null;
19982
20142
  }
@@ -19999,6 +20159,35 @@ ${trimmedSection}` : trimmedSection;
19999
20159
  throw new Error("PersistentInstructionsPluginNextGen is destroyed");
20000
20160
  }
20001
20161
  }
20162
+ /**
20163
+ * Persist current entries to storage
20164
+ */
20165
+ async persistToStorage() {
20166
+ await this.storage.save(Array.from(this._entries.values()));
20167
+ }
20168
+ /**
20169
+ * Calculate total content length across all entries
20170
+ */
20171
+ calculateTotalContentLength() {
20172
+ let total = 0;
20173
+ for (const entry of this._entries.values()) {
20174
+ total += entry.content.length;
20175
+ }
20176
+ return total;
20177
+ }
20178
+ /**
20179
+ * Get entries sorted by createdAt (oldest first)
20180
+ */
20181
+ getSortedEntries() {
20182
+ return Array.from(this._entries.values()).sort((a, b) => a.createdAt - b.createdAt);
20183
+ }
20184
+ /**
20185
+ * Render all entries as markdown for context injection
20186
+ */
20187
+ renderContent() {
20188
+ return this.getSortedEntries().map((entry) => `### ${entry.id}
20189
+ ${entry.content}`).join("\n\n");
20190
+ }
20002
20191
  // ============================================================================
20003
20192
  // Tool Factories
20004
20193
  // ============================================================================
@@ -20006,60 +20195,84 @@ ${trimmedSection}` : trimmedSection;
20006
20195
  return {
20007
20196
  definition: instructionsSetDefinition,
20008
20197
  execute: async (args) => {
20198
+ const key = args.key;
20009
20199
  const content = args.content;
20200
+ const keyError = validateKey(key);
20201
+ if (keyError) {
20202
+ return { error: keyError };
20203
+ }
20010
20204
  if (!content || content.trim().length === 0) {
20011
- return { error: "Content cannot be empty. Use instructions_clear to remove." };
20205
+ return { error: "Content cannot be empty. Use instructions_remove to delete an entry." };
20012
20206
  }
20013
- const success = await this.set(content);
20207
+ const isUpdate = this._entries.has(key.trim());
20208
+ const success = await this.set(key.trim(), content);
20014
20209
  if (!success) {
20015
- return { error: `Content exceeds maximum length (${this.maxLength} chars)` };
20210
+ if (!isUpdate && this._entries.size >= this.maxEntries) {
20211
+ return { error: `Maximum number of entries reached (${this.maxEntries})` };
20212
+ }
20213
+ return { error: `Content would exceed maximum total length (${this.maxTotalLength} chars)` };
20016
20214
  }
20017
20215
  return {
20018
20216
  success: true,
20019
- message: "Custom instructions updated",
20020
- length: content.length
20217
+ message: isUpdate ? `Instruction '${key.trim()}' updated` : `Instruction '${key.trim()}' added`,
20218
+ key: key.trim(),
20219
+ contentLength: content.trim().length
20021
20220
  };
20022
20221
  },
20023
20222
  permission: { scope: "always", riskLevel: "low" },
20024
- describeCall: () => "set instructions"
20223
+ describeCall: (args) => `set instruction '${args.key}'`
20025
20224
  };
20026
20225
  }
20027
- createInstructionsAppendTool() {
20226
+ createInstructionsRemoveTool() {
20028
20227
  return {
20029
- definition: instructionsAppendDefinition,
20228
+ definition: instructionsRemoveDefinition,
20030
20229
  execute: async (args) => {
20031
- const section = args.section;
20032
- if (!section || section.trim().length === 0) {
20033
- return { error: "Section cannot be empty" };
20230
+ const key = args.key;
20231
+ if (!key || typeof key !== "string" || key.trim().length === 0) {
20232
+ return { error: "Key is required" };
20034
20233
  }
20035
- const success = await this.append(section);
20234
+ const success = await this.remove(key.trim());
20036
20235
  if (!success) {
20037
- return { error: `Would exceed maximum length (${this.maxLength} chars)` };
20236
+ return { error: `Instruction '${key.trim()}' not found` };
20038
20237
  }
20039
20238
  return {
20040
20239
  success: true,
20041
- message: "Section appended to instructions",
20042
- newLength: this._content?.length ?? 0
20240
+ message: `Instruction '${key.trim()}' removed`,
20241
+ key: key.trim()
20043
20242
  };
20044
20243
  },
20045
20244
  permission: { scope: "always", riskLevel: "low" },
20046
- describeCall: () => "append to instructions"
20245
+ describeCall: (args) => `remove instruction '${args.key}'`
20047
20246
  };
20048
20247
  }
20049
- createInstructionsGetTool() {
20248
+ createInstructionsListTool() {
20050
20249
  return {
20051
- definition: instructionsGetDefinition,
20250
+ definition: instructionsListDefinition,
20052
20251
  execute: async () => {
20053
- const content = await this.get();
20252
+ const entries = await this.list();
20253
+ const all = await this.get();
20254
+ if (entries.length === 0) {
20255
+ return {
20256
+ count: 0,
20257
+ entries: [],
20258
+ message: "(no custom instructions set)"
20259
+ };
20260
+ }
20261
+ const allEntries = all;
20054
20262
  return {
20055
- hasContent: content !== null,
20056
- content: content ?? "(no custom instructions set)",
20057
- length: content?.length ?? 0,
20263
+ count: entries.length,
20264
+ entries: allEntries.map((e) => ({
20265
+ key: e.id,
20266
+ content: e.content,
20267
+ contentLength: e.content.length,
20268
+ createdAt: e.createdAt,
20269
+ updatedAt: e.updatedAt
20270
+ })),
20058
20271
  agentId: this.agentId
20059
20272
  };
20060
20273
  },
20061
20274
  permission: { scope: "always", riskLevel: "low" },
20062
- describeCall: () => "get instructions"
20275
+ describeCall: () => "list instructions"
20063
20276
  };
20064
20277
  }
20065
20278
  createInstructionsClearTool() {
@@ -20072,7 +20285,7 @@ ${trimmedSection}` : trimmedSection;
20072
20285
  await this.clear();
20073
20286
  return {
20074
20287
  success: true,
20075
- message: "Custom instructions cleared"
20288
+ message: "All custom instructions cleared"
20076
20289
  };
20077
20290
  },
20078
20291
  permission: { scope: "once", riskLevel: "medium" },
@@ -20797,7 +21010,9 @@ var AgentContextNextGen = class _AgentContextNextGen extends eventemitter3.Event
20797
21010
  this._agentId = this._config.agentId;
20798
21011
  this._storage = config.storage;
20799
21012
  this._compactionStrategy = config.compactionStrategy ?? StrategyRegistry.create(this._config.strategy);
20800
- this._tools = new ToolManager();
21013
+ this._tools = new ToolManager(
21014
+ config.toolExecutionTimeout ? { toolExecutionTimeout: config.toolExecutionTimeout } : void 0
21015
+ );
20801
21016
  if (config.tools) {
20802
21017
  for (const tool of config.tools) {
20803
21018
  this._tools.register(tool);
@@ -22533,7 +22748,7 @@ var OpenAITextProvider = class extends BaseTextProvider {
22533
22748
  streamConverter;
22534
22749
  constructor(config) {
22535
22750
  super(config);
22536
- this.client = new OpenAI2__default.default({
22751
+ this.client = new OpenAI3__default.default({
22537
22752
  apiKey: this.getApiKey(),
22538
22753
  baseURL: this.getBaseURL(),
22539
22754
  organization: config.organization,
@@ -24263,7 +24478,9 @@ var GoogleTextProvider = class extends BaseTextProvider {
24263
24478
  constructor(config) {
24264
24479
  super(config);
24265
24480
  this.client = new genai.GoogleGenAI({
24266
- 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 } } : {}
24267
24484
  });
24268
24485
  this.converter = new GoogleConverter();
24269
24486
  this.streamConverter = new GoogleStreamConverter();
@@ -24560,6 +24777,30 @@ var GenericOpenAIProvider = class extends OpenAITextProvider {
24560
24777
  };
24561
24778
 
24562
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
+ }
24563
24804
  function createProvider(connector) {
24564
24805
  const injectedProvider = connector.getOptions().provider;
24565
24806
  if (injectedProvider && typeof injectedProvider.generate === "function") {
@@ -24594,39 +24835,15 @@ function createProvider(connector) {
24594
24835
  });
24595
24836
  // OpenAI-compatible providers (use connector.name for unique identification)
24596
24837
  case Vendor.Groq:
24597
- return new GenericOpenAIProvider(connector.name, {
24598
- ...config,
24599
- baseURL: config.baseURL || "https://api.groq.com/openai/v1"
24600
- });
24601
24838
  case Vendor.Together:
24602
- return new GenericOpenAIProvider(connector.name, {
24603
- ...config,
24604
- baseURL: config.baseURL || "https://api.together.xyz/v1"
24605
- });
24606
24839
  case Vendor.Perplexity:
24607
- return new GenericOpenAIProvider(connector.name, {
24608
- ...config,
24609
- baseURL: config.baseURL || "https://api.perplexity.ai"
24610
- });
24611
24840
  case Vendor.Grok:
24612
- return new GenericOpenAIProvider(connector.name, {
24613
- ...config,
24614
- baseURL: config.baseURL || "https://api.x.ai/v1"
24615
- });
24616
24841
  case Vendor.DeepSeek:
24617
- return new GenericOpenAIProvider(connector.name, {
24618
- ...config,
24619
- baseURL: config.baseURL || "https://api.deepseek.com/v1"
24620
- });
24621
24842
  case Vendor.Mistral:
24622
- return new GenericOpenAIProvider(connector.name, {
24623
- ...config,
24624
- baseURL: config.baseURL || "https://api.mistral.ai/v1"
24625
- });
24626
24843
  case Vendor.Ollama:
24627
24844
  return new GenericOpenAIProvider(connector.name, {
24628
24845
  ...config,
24629
- baseURL: config.baseURL || "http://localhost:11434/v1"
24846
+ baseURL: config.baseURL || getVendorDefaultBaseURL(vendor)
24630
24847
  });
24631
24848
  case Vendor.Custom:
24632
24849
  if (!config.baseURL) {
@@ -24738,7 +24955,10 @@ var BaseAgent = class extends eventemitter3.EventEmitter {
24738
24955
  agentId: config.name,
24739
24956
  // Include storage and sessionId if session config is provided
24740
24957
  storage: config.session?.storage,
24958
+ // Thread tool execution timeout to ToolManager
24959
+ toolExecutionTimeout: config.toolExecutionTimeout,
24741
24960
  // Subclasses can add systemPrompt via their config
24961
+ // Note: context-level toolExecutionTimeout overrides agent-level if both set
24742
24962
  ...typeof config.context === "object" && config.context !== null ? config.context : {}
24743
24963
  };
24744
24964
  return AgentContextNextGen.create(contextConfig);
@@ -27178,18 +27398,18 @@ var Agent = class _Agent extends BaseAgent {
27178
27398
  (class {
27179
27399
  static DEFAULT_PATHS = [
27180
27400
  "./oneringai.config.json",
27181
- path3.join(os.homedir(), ".oneringai", "config.json")
27401
+ path2.join(os2.homedir(), ".oneringai", "config.json")
27182
27402
  ];
27183
27403
  /**
27184
27404
  * Load configuration from file
27185
27405
  */
27186
27406
  static async load(path6) {
27187
- const configPath = path6 ? path3.resolve(path6) : await this.findConfig();
27407
+ const configPath = path6 ? path2.resolve(path6) : await this.findConfig();
27188
27408
  if (!configPath) {
27189
27409
  throw new Error("Configuration file not found. Searched: " + this.DEFAULT_PATHS.join(", "));
27190
27410
  }
27191
27411
  try {
27192
- const content = await fs15.promises.readFile(configPath, "utf-8");
27412
+ const content = await fs16.promises.readFile(configPath, "utf-8");
27193
27413
  let config = JSON.parse(content);
27194
27414
  config = this.interpolateEnvVars(config);
27195
27415
  this.validate(config);
@@ -27205,13 +27425,13 @@ var Agent = class _Agent extends BaseAgent {
27205
27425
  * Load configuration synchronously
27206
27426
  */
27207
27427
  static loadSync(path6) {
27208
- const configPath = path6 ? path3.resolve(path6) : this.findConfigSync();
27428
+ const configPath = path6 ? path2.resolve(path6) : this.findConfigSync();
27209
27429
  if (!configPath) {
27210
27430
  throw new Error("Configuration file not found. Searched: " + this.DEFAULT_PATHS.join(", "));
27211
27431
  }
27212
27432
  try {
27213
- const fs18 = __require("fs");
27214
- const content = fs18.readFileSync(configPath, "utf-8");
27433
+ const fs17 = __require("fs");
27434
+ const content = fs17.readFileSync(configPath, "utf-8");
27215
27435
  let config = JSON.parse(content);
27216
27436
  config = this.interpolateEnvVars(config);
27217
27437
  this.validate(config);
@@ -27229,8 +27449,8 @@ var Agent = class _Agent extends BaseAgent {
27229
27449
  static async findConfig() {
27230
27450
  for (const path6 of this.DEFAULT_PATHS) {
27231
27451
  try {
27232
- await fs15.promises.access(path3.resolve(path6));
27233
- return path3.resolve(path6);
27452
+ await fs16.promises.access(path2.resolve(path6));
27453
+ return path2.resolve(path6);
27234
27454
  } catch {
27235
27455
  }
27236
27456
  }
@@ -27240,11 +27460,11 @@ var Agent = class _Agent extends BaseAgent {
27240
27460
  * Find configuration file synchronously
27241
27461
  */
27242
27462
  static findConfigSync() {
27243
- const fs18 = __require("fs");
27463
+ const fs17 = __require("fs");
27244
27464
  for (const path6 of this.DEFAULT_PATHS) {
27245
27465
  try {
27246
- fs18.accessSync(path3.resolve(path6));
27247
- return path3.resolve(path6);
27466
+ fs17.accessSync(path2.resolve(path6));
27467
+ return path2.resolve(path6);
27248
27468
  } catch {
27249
27469
  }
27250
27470
  }
@@ -32801,8 +33021,8 @@ var MCPRegistry = class {
32801
33021
  */
32802
33022
  static async loadFromConfigFile(path6) {
32803
33023
  try {
32804
- const configPath = path3.resolve(path6);
32805
- const content = await fs15.promises.readFile(configPath, "utf-8");
33024
+ const configPath = path2.resolve(path6);
33025
+ const content = await fs16.promises.readFile(configPath, "utf-8");
32806
33026
  const config = JSON.parse(content);
32807
33027
  if (!config.mcp) {
32808
33028
  throw new MCPError("Configuration file does not contain MCP section");
@@ -33190,7 +33410,7 @@ var OpenAITTSProvider = class extends BaseMediaProvider {
33190
33410
  client;
33191
33411
  constructor(config) {
33192
33412
  super({ apiKey: config.auth.apiKey, ...config });
33193
- this.client = new OpenAI2__default.default({
33413
+ this.client = new OpenAI3__default.default({
33194
33414
  apiKey: config.auth.apiKey,
33195
33415
  baseURL: config.baseURL,
33196
33416
  organization: config.organization,
@@ -33273,7 +33493,7 @@ var OpenAITTSProvider = class extends BaseMediaProvider {
33273
33493
  * Handle OpenAI API errors
33274
33494
  */
33275
33495
  handleError(error) {
33276
- if (error instanceof OpenAI2__default.default.APIError) {
33496
+ if (error instanceof OpenAI3__default.default.APIError) {
33277
33497
  const status = error.status;
33278
33498
  const message = error.message || "Unknown OpenAI API error";
33279
33499
  if (status === 401) {
@@ -33305,7 +33525,7 @@ var OpenAISTTProvider = class extends BaseMediaProvider {
33305
33525
  client;
33306
33526
  constructor(config) {
33307
33527
  super({ apiKey: config.auth.apiKey, ...config });
33308
- this.client = new OpenAI2__default.default({
33528
+ this.client = new OpenAI3__default.default({
33309
33529
  apiKey: config.auth.apiKey,
33310
33530
  baseURL: config.baseURL,
33311
33531
  organization: config.organization,
@@ -33407,7 +33627,7 @@ var OpenAISTTProvider = class extends BaseMediaProvider {
33407
33627
  if (Buffer.isBuffer(audio)) {
33408
33628
  return new File([new Uint8Array(audio)], "audio.wav", { type: "audio/wav" });
33409
33629
  } else if (typeof audio === "string") {
33410
- return fs15__namespace.createReadStream(audio);
33630
+ return fs16__namespace.createReadStream(audio);
33411
33631
  } else {
33412
33632
  throw new Error("Invalid audio input: must be Buffer or file path");
33413
33633
  }
@@ -33466,7 +33686,7 @@ var OpenAISTTProvider = class extends BaseMediaProvider {
33466
33686
  * Handle OpenAI API errors
33467
33687
  */
33468
33688
  handleError(error) {
33469
- if (error instanceof OpenAI2__default.default.APIError) {
33689
+ if (error instanceof OpenAI3__default.default.APIError) {
33470
33690
  const status = error.status;
33471
33691
  const message = error.message || "Unknown OpenAI API error";
33472
33692
  if (status === 401) {
@@ -33960,7 +34180,7 @@ var TextToSpeech = class _TextToSpeech {
33960
34180
  */
33961
34181
  async toFile(text, filePath, options) {
33962
34182
  const response = await this.synthesize(text, options);
33963
- await fs14__namespace.writeFile(filePath, response.audio);
34183
+ await fs15__namespace.writeFile(filePath, response.audio);
33964
34184
  }
33965
34185
  // ======================== Introspection Methods ========================
33966
34186
  /**
@@ -34308,7 +34528,7 @@ var SpeechToText = class _SpeechToText {
34308
34528
  * @param options - Optional transcription parameters
34309
34529
  */
34310
34530
  async transcribeFile(filePath, options) {
34311
- const audio = await fs14__namespace.readFile(filePath);
34531
+ const audio = await fs15__namespace.readFile(filePath);
34312
34532
  return this.transcribe(audio, options);
34313
34533
  }
34314
34534
  /**
@@ -34472,7 +34692,7 @@ var OpenAIImageProvider = class extends BaseMediaProvider {
34472
34692
  client;
34473
34693
  constructor(config) {
34474
34694
  super({ apiKey: config.auth.apiKey, ...config });
34475
- this.client = new OpenAI2__default.default({
34695
+ this.client = new OpenAI3__default.default({
34476
34696
  apiKey: config.auth.apiKey,
34477
34697
  baseURL: config.baseURL,
34478
34698
  organization: config.organization,
@@ -34634,7 +34854,7 @@ var OpenAIImageProvider = class extends BaseMediaProvider {
34634
34854
  if (Buffer.isBuffer(image)) {
34635
34855
  return new File([new Uint8Array(image)], "image.png", { type: "image/png" });
34636
34856
  }
34637
- return fs15__namespace.createReadStream(image);
34857
+ return fs16__namespace.createReadStream(image);
34638
34858
  }
34639
34859
  /**
34640
34860
  * Handle OpenAI API errors
@@ -34781,8 +35001,8 @@ var GoogleImageProvider = class extends BaseMediaProvider {
34781
35001
  if (Buffer.isBuffer(image)) {
34782
35002
  imageBytes = image.toString("base64");
34783
35003
  } else {
34784
- const fs18 = await import('fs');
34785
- const buffer = fs18.readFileSync(image);
35004
+ const fs17 = await import('fs');
35005
+ const buffer = fs17.readFileSync(image);
34786
35006
  imageBytes = buffer.toString("base64");
34787
35007
  }
34788
35008
  return {
@@ -34832,7 +35052,7 @@ var GrokImageProvider = class extends BaseMediaProvider {
34832
35052
  client;
34833
35053
  constructor(config) {
34834
35054
  super({ apiKey: config.auth.apiKey, ...config });
34835
- this.client = new OpenAI2__default.default({
35055
+ this.client = new OpenAI3__default.default({
34836
35056
  apiKey: config.auth.apiKey,
34837
35057
  baseURL: config.baseURL || GROK_API_BASE_URL,
34838
35058
  timeout: config.timeout,
@@ -34943,7 +35163,7 @@ var GrokImageProvider = class extends BaseMediaProvider {
34943
35163
  if (Buffer.isBuffer(image)) {
34944
35164
  return new File([new Uint8Array(image)], "image.png", { type: "image/png" });
34945
35165
  }
34946
- return fs15__namespace.createReadStream(image);
35166
+ return fs16__namespace.createReadStream(image);
34947
35167
  }
34948
35168
  /**
34949
35169
  * Handle API errors
@@ -36145,7 +36365,7 @@ var OpenAISoraProvider = class extends BaseMediaProvider {
36145
36365
  client;
36146
36366
  constructor(config) {
36147
36367
  super({ apiKey: config.auth.apiKey, ...config });
36148
- this.client = new OpenAI2__default.default({
36368
+ this.client = new OpenAI3__default.default({
36149
36369
  apiKey: config.auth.apiKey,
36150
36370
  baseURL: config.baseURL,
36151
36371
  organization: config.organization,
@@ -36393,8 +36613,8 @@ var OpenAISoraProvider = class extends BaseMediaProvider {
36393
36613
  return new File([new Uint8Array(image)], "input.png", { type: "image/png" });
36394
36614
  }
36395
36615
  if (!image.startsWith("http")) {
36396
- const fs18 = await import('fs');
36397
- const data = fs18.readFileSync(image);
36616
+ const fs17 = await import('fs');
36617
+ const data = fs17.readFileSync(image);
36398
36618
  return new File([new Uint8Array(data)], "input.png", { type: "image/png" });
36399
36619
  }
36400
36620
  const response = await fetch(image);
@@ -36572,7 +36792,7 @@ var GoogleVeoProvider = class extends BaseMediaProvider {
36572
36792
  if (video.videoBytes) {
36573
36793
  buffer = Buffer.from(video.videoBytes, "base64");
36574
36794
  } else if (video.uri) {
36575
- const fs18 = await import('fs/promises');
36795
+ const fs17 = await import('fs/promises');
36576
36796
  const os3 = await import('os');
36577
36797
  const path6 = await import('path');
36578
36798
  const tempDir = os3.tmpdir();
@@ -36583,11 +36803,11 @@ var GoogleVeoProvider = class extends BaseMediaProvider {
36583
36803
  // Pass as GeneratedVideo
36584
36804
  downloadPath: tempFile
36585
36805
  });
36586
- buffer = await fs18.readFile(tempFile);
36587
- await fs18.unlink(tempFile).catch(() => {
36806
+ buffer = await fs17.readFile(tempFile);
36807
+ await fs17.unlink(tempFile).catch(() => {
36588
36808
  });
36589
36809
  } catch (downloadError) {
36590
- await fs18.unlink(tempFile).catch(() => {
36810
+ await fs17.unlink(tempFile).catch(() => {
36591
36811
  });
36592
36812
  throw new ProviderError(
36593
36813
  "google",
@@ -36709,8 +36929,8 @@ var GoogleVeoProvider = class extends BaseMediaProvider {
36709
36929
  if (image.startsWith("http://") || image.startsWith("https://")) {
36710
36930
  return { imageUri: image };
36711
36931
  }
36712
- const fs18 = await import('fs/promises');
36713
- const data = await fs18.readFile(image);
36932
+ const fs17 = await import('fs/promises');
36933
+ const data = await fs17.readFile(image);
36714
36934
  return {
36715
36935
  imageBytes: data.toString("base64")
36716
36936
  };
@@ -37017,8 +37237,8 @@ var GrokImagineProvider = class extends BaseMediaProvider {
37017
37237
  if (image.startsWith("http") || image.startsWith("data:")) {
37018
37238
  return image;
37019
37239
  }
37020
- const fs18 = await import('fs');
37021
- const data = fs18.readFileSync(image);
37240
+ const fs17 = await import('fs');
37241
+ const data = fs17.readFileSync(image);
37022
37242
  const base64 = data.toString("base64");
37023
37243
  const ext = image.split(".").pop()?.toLowerCase() || "png";
37024
37244
  const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext}`;
@@ -40223,10 +40443,10 @@ function getDefaultBaseDirectory2() {
40223
40443
  if (platform2 === "win32") {
40224
40444
  const appData = process.env.APPDATA || process.env.LOCALAPPDATA;
40225
40445
  if (appData) {
40226
- return path3.join(appData, "oneringai", "agents");
40446
+ return path2.join(appData, "oneringai", "agents");
40227
40447
  }
40228
40448
  }
40229
- return path3.join(os.homedir(), ".oneringai", "agents");
40449
+ return path2.join(os2.homedir(), ".oneringai", "agents");
40230
40450
  }
40231
40451
  function sanitizeId(id) {
40232
40452
  return id.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase() || "default";
@@ -40243,8 +40463,8 @@ var FileContextStorage = class {
40243
40463
  const sanitizedAgentId = sanitizeId(config.agentId);
40244
40464
  const baseDir = config.baseDirectory ?? getDefaultBaseDirectory2();
40245
40465
  this.prettyPrint = config.prettyPrint ?? true;
40246
- this.sessionsDirectory = path3.join(baseDir, sanitizedAgentId, "sessions");
40247
- this.indexPath = path3.join(this.sessionsDirectory, "_index.json");
40466
+ this.sessionsDirectory = path2.join(baseDir, sanitizedAgentId, "sessions");
40467
+ this.indexPath = path2.join(this.sessionsDirectory, "_index.json");
40248
40468
  }
40249
40469
  /**
40250
40470
  * Save context state to a session file
@@ -40270,11 +40490,11 @@ var FileContextStorage = class {
40270
40490
  const data = this.prettyPrint ? JSON.stringify(storedSession, null, 2) : JSON.stringify(storedSession);
40271
40491
  const tempPath = `${filePath}.tmp`;
40272
40492
  try {
40273
- await fs15.promises.writeFile(tempPath, data, "utf-8");
40274
- await fs15.promises.rename(tempPath, filePath);
40493
+ await fs16.promises.writeFile(tempPath, data, "utf-8");
40494
+ await fs16.promises.rename(tempPath, filePath);
40275
40495
  } catch (error) {
40276
40496
  try {
40277
- await fs15.promises.unlink(tempPath);
40497
+ await fs16.promises.unlink(tempPath);
40278
40498
  } catch {
40279
40499
  }
40280
40500
  throw error;
@@ -40295,7 +40515,7 @@ var FileContextStorage = class {
40295
40515
  const sanitizedSessionId = sanitizeId(sessionId);
40296
40516
  const filePath = this.getFilePath(sanitizedSessionId);
40297
40517
  try {
40298
- await fs15.promises.unlink(filePath);
40518
+ await fs16.promises.unlink(filePath);
40299
40519
  } catch (error) {
40300
40520
  if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
40301
40521
  throw error;
@@ -40310,7 +40530,7 @@ var FileContextStorage = class {
40310
40530
  const sanitizedSessionId = sanitizeId(sessionId);
40311
40531
  const filePath = this.getFilePath(sanitizedSessionId);
40312
40532
  try {
40313
- await fs15.promises.access(filePath);
40533
+ await fs16.promises.access(filePath);
40314
40534
  return true;
40315
40535
  } catch {
40316
40536
  return false;
@@ -40375,7 +40595,7 @@ var FileContextStorage = class {
40375
40595
  const sanitizedSessionId = sanitizeId(sessionId);
40376
40596
  const filePath = this.getFilePath(sanitizedSessionId);
40377
40597
  const data = this.prettyPrint ? JSON.stringify(stored, null, 2) : JSON.stringify(stored);
40378
- await fs15.promises.writeFile(filePath, data, "utf-8");
40598
+ await fs16.promises.writeFile(filePath, data, "utf-8");
40379
40599
  await this.updateIndex(stored);
40380
40600
  }
40381
40601
  /**
@@ -40396,13 +40616,13 @@ var FileContextStorage = class {
40396
40616
  */
40397
40617
  async rebuildIndex() {
40398
40618
  await this.ensureDirectory();
40399
- const files = await fs15.promises.readdir(this.sessionsDirectory);
40619
+ const files = await fs16.promises.readdir(this.sessionsDirectory);
40400
40620
  const sessionFiles = files.filter((f) => f.endsWith(".json") && !f.startsWith("_"));
40401
40621
  const entries = [];
40402
40622
  for (const file of sessionFiles) {
40403
40623
  try {
40404
- const filePath = path3.join(this.sessionsDirectory, file);
40405
- const data = await fs15.promises.readFile(filePath, "utf-8");
40624
+ const filePath = path2.join(this.sessionsDirectory, file);
40625
+ const data = await fs16.promises.readFile(filePath, "utf-8");
40406
40626
  const stored = JSON.parse(data);
40407
40627
  entries.push(this.storedToIndexEntry(stored));
40408
40628
  } catch {
@@ -40420,11 +40640,11 @@ var FileContextStorage = class {
40420
40640
  // Private Helpers
40421
40641
  // ==========================================================================
40422
40642
  getFilePath(sanitizedSessionId) {
40423
- return path3.join(this.sessionsDirectory, `${sanitizedSessionId}.json`);
40643
+ return path2.join(this.sessionsDirectory, `${sanitizedSessionId}.json`);
40424
40644
  }
40425
40645
  async ensureDirectory() {
40426
40646
  try {
40427
- await fs15.promises.mkdir(this.sessionsDirectory, { recursive: true });
40647
+ await fs16.promises.mkdir(this.sessionsDirectory, { recursive: true });
40428
40648
  } catch (error) {
40429
40649
  if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
40430
40650
  throw error;
@@ -40434,7 +40654,7 @@ var FileContextStorage = class {
40434
40654
  async loadRaw(sanitizedSessionId) {
40435
40655
  const filePath = this.getFilePath(sanitizedSessionId);
40436
40656
  try {
40437
- const data = await fs15.promises.readFile(filePath, "utf-8");
40657
+ const data = await fs16.promises.readFile(filePath, "utf-8");
40438
40658
  return JSON.parse(data);
40439
40659
  } catch (error) {
40440
40660
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -40452,7 +40672,7 @@ var FileContextStorage = class {
40452
40672
  return this.index;
40453
40673
  }
40454
40674
  try {
40455
- const data = await fs15.promises.readFile(this.indexPath, "utf-8");
40675
+ const data = await fs16.promises.readFile(this.indexPath, "utf-8");
40456
40676
  this.index = JSON.parse(data);
40457
40677
  return this.index;
40458
40678
  } catch (error) {
@@ -40473,7 +40693,7 @@ var FileContextStorage = class {
40473
40693
  await this.ensureDirectory();
40474
40694
  this.index.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
40475
40695
  const data = this.prettyPrint ? JSON.stringify(this.index, null, 2) : JSON.stringify(this.index);
40476
- await fs15.promises.writeFile(this.indexPath, data, "utf-8");
40696
+ await fs16.promises.writeFile(this.indexPath, data, "utf-8");
40477
40697
  }
40478
40698
  async updateIndex(stored) {
40479
40699
  const index = await this.loadIndex();
@@ -40511,10 +40731,10 @@ function getDefaultBaseDirectory3() {
40511
40731
  if (platform2 === "win32") {
40512
40732
  const appData = process.env.APPDATA || process.env.LOCALAPPDATA;
40513
40733
  if (appData) {
40514
- return path3.join(appData, "oneringai", "agents");
40734
+ return path2.join(appData, "oneringai", "agents");
40515
40735
  }
40516
40736
  }
40517
- return path3.join(os.homedir(), ".oneringai", "agents");
40737
+ return path2.join(os2.homedir(), ".oneringai", "agents");
40518
40738
  }
40519
40739
  function sanitizeAgentId2(agentId) {
40520
40740
  return agentId.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase() || "default";
@@ -40527,15 +40747,15 @@ var FileAgentDefinitionStorage = class {
40527
40747
  constructor(config = {}) {
40528
40748
  this.baseDirectory = config.baseDirectory ?? getDefaultBaseDirectory3();
40529
40749
  this.prettyPrint = config.prettyPrint ?? true;
40530
- this.indexPath = path3.join(this.baseDirectory, "_agents_index.json");
40750
+ this.indexPath = path2.join(this.baseDirectory, "_agents_index.json");
40531
40751
  }
40532
40752
  /**
40533
40753
  * Save an agent definition
40534
40754
  */
40535
40755
  async save(definition) {
40536
40756
  const sanitizedId = sanitizeAgentId2(definition.agentId);
40537
- const agentDir = path3.join(this.baseDirectory, sanitizedId);
40538
- const filePath = path3.join(agentDir, "definition.json");
40757
+ const agentDir = path2.join(this.baseDirectory, sanitizedId);
40758
+ const filePath = path2.join(agentDir, "definition.json");
40539
40759
  await this.ensureDirectory(agentDir);
40540
40760
  const now = (/* @__PURE__ */ new Date()).toISOString();
40541
40761
  if (!definition.createdAt) {
@@ -40547,11 +40767,11 @@ var FileAgentDefinitionStorage = class {
40547
40767
  const data = this.prettyPrint ? JSON.stringify(definition, null, 2) : JSON.stringify(definition);
40548
40768
  const tempPath = `${filePath}.tmp`;
40549
40769
  try {
40550
- await fs15.promises.writeFile(tempPath, data, "utf-8");
40551
- await fs15.promises.rename(tempPath, filePath);
40770
+ await fs16.promises.writeFile(tempPath, data, "utf-8");
40771
+ await fs16.promises.rename(tempPath, filePath);
40552
40772
  } catch (error) {
40553
40773
  try {
40554
- await fs15.promises.unlink(tempPath);
40774
+ await fs16.promises.unlink(tempPath);
40555
40775
  } catch {
40556
40776
  }
40557
40777
  throw error;
@@ -40570,10 +40790,10 @@ var FileAgentDefinitionStorage = class {
40570
40790
  */
40571
40791
  async delete(agentId) {
40572
40792
  const sanitizedId = sanitizeAgentId2(agentId);
40573
- const agentDir = path3.join(this.baseDirectory, sanitizedId);
40574
- const filePath = path3.join(agentDir, "definition.json");
40793
+ const agentDir = path2.join(this.baseDirectory, sanitizedId);
40794
+ const filePath = path2.join(agentDir, "definition.json");
40575
40795
  try {
40576
- await fs15.promises.unlink(filePath);
40796
+ await fs16.promises.unlink(filePath);
40577
40797
  } catch (error) {
40578
40798
  if (error instanceof Error && "code" in error && error.code !== "ENOENT") {
40579
40799
  throw error;
@@ -40586,9 +40806,9 @@ var FileAgentDefinitionStorage = class {
40586
40806
  */
40587
40807
  async exists(agentId) {
40588
40808
  const sanitizedId = sanitizeAgentId2(agentId);
40589
- const filePath = path3.join(this.baseDirectory, sanitizedId, "definition.json");
40809
+ const filePath = path2.join(this.baseDirectory, sanitizedId, "definition.json");
40590
40810
  try {
40591
- await fs15.promises.access(filePath);
40811
+ await fs16.promises.access(filePath);
40592
40812
  return true;
40593
40813
  } catch {
40594
40814
  return false;
@@ -40650,13 +40870,13 @@ var FileAgentDefinitionStorage = class {
40650
40870
  */
40651
40871
  async rebuildIndex() {
40652
40872
  await this.ensureDirectory(this.baseDirectory);
40653
- const entries = await fs15.promises.readdir(this.baseDirectory, { withFileTypes: true });
40873
+ const entries = await fs16.promises.readdir(this.baseDirectory, { withFileTypes: true });
40654
40874
  const agentDirs = entries.filter((e) => e.isDirectory() && !e.name.startsWith("_"));
40655
40875
  const indexEntries = [];
40656
40876
  for (const dir of agentDirs) {
40657
40877
  try {
40658
- const filePath = path3.join(this.baseDirectory, dir.name, "definition.json");
40659
- const data = await fs15.promises.readFile(filePath, "utf-8");
40878
+ const filePath = path2.join(this.baseDirectory, dir.name, "definition.json");
40879
+ const data = await fs16.promises.readFile(filePath, "utf-8");
40660
40880
  const definition = JSON.parse(data);
40661
40881
  indexEntries.push(this.definitionToIndexEntry(definition));
40662
40882
  } catch {
@@ -40674,7 +40894,7 @@ var FileAgentDefinitionStorage = class {
40674
40894
  // ==========================================================================
40675
40895
  async ensureDirectory(dir) {
40676
40896
  try {
40677
- await fs15.promises.mkdir(dir, { recursive: true });
40897
+ await fs16.promises.mkdir(dir, { recursive: true });
40678
40898
  } catch (error) {
40679
40899
  if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
40680
40900
  throw error;
@@ -40682,9 +40902,9 @@ var FileAgentDefinitionStorage = class {
40682
40902
  }
40683
40903
  }
40684
40904
  async loadRaw(sanitizedId) {
40685
- const filePath = path3.join(this.baseDirectory, sanitizedId, "definition.json");
40905
+ const filePath = path2.join(this.baseDirectory, sanitizedId, "definition.json");
40686
40906
  try {
40687
- const data = await fs15.promises.readFile(filePath, "utf-8");
40907
+ const data = await fs16.promises.readFile(filePath, "utf-8");
40688
40908
  return JSON.parse(data);
40689
40909
  } catch (error) {
40690
40910
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -40702,7 +40922,7 @@ var FileAgentDefinitionStorage = class {
40702
40922
  return this.index;
40703
40923
  }
40704
40924
  try {
40705
- const data = await fs15.promises.readFile(this.indexPath, "utf-8");
40925
+ const data = await fs16.promises.readFile(this.indexPath, "utf-8");
40706
40926
  this.index = JSON.parse(data);
40707
40927
  return this.index;
40708
40928
  } catch (error) {
@@ -40722,7 +40942,7 @@ var FileAgentDefinitionStorage = class {
40722
40942
  await this.ensureDirectory(this.baseDirectory);
40723
40943
  this.index.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
40724
40944
  const data = this.prettyPrint ? JSON.stringify(this.index, null, 2) : JSON.stringify(this.index);
40725
- await fs15.promises.writeFile(this.indexPath, data, "utf-8");
40945
+ await fs16.promises.writeFile(this.indexPath, data, "utf-8");
40726
40946
  }
40727
40947
  async updateIndex(definition) {
40728
40948
  const index = await this.loadIndex();
@@ -40755,6 +40975,126 @@ var FileAgentDefinitionStorage = class {
40755
40975
  function createFileAgentDefinitionStorage(config) {
40756
40976
  return new FileAgentDefinitionStorage(config);
40757
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
+ }
40758
41098
 
40759
41099
  // src/capabilities/agents/StreamHelpers.ts
40760
41100
  var StreamHelpers = class {
@@ -41677,7 +42017,7 @@ var ConnectorTools = class {
41677
42017
  static createGenericAPITool(connector, options) {
41678
42018
  const toolName = options?.toolName ?? `${connector.name}_api`;
41679
42019
  const userId = options?.userId;
41680
- const description = options?.description ?? `Make an authenticated API call to ${connector.displayName}.` + (connector.baseURL ? ` Base URL: ${connector.baseURL}` : " Provide full URL in endpoint.");
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.';
41681
42021
  return {
41682
42022
  definition: {
41683
42023
  type: "function",
@@ -41694,15 +42034,15 @@ var ConnectorTools = class {
41694
42034
  },
41695
42035
  endpoint: {
41696
42036
  type: "string",
41697
- description: "API endpoint (relative to base URL) or full URL"
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.'
41698
42038
  },
41699
42039
  body: {
41700
42040
  type: "object",
41701
- description: "Request body (for POST/PUT/PATCH)"
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.'
41702
42042
  },
41703
42043
  queryParams: {
41704
42044
  type: "object",
41705
- description: "URL query parameters"
42045
+ description: 'URL query parameters (for filtering/pagination on GET requests). Do NOT use for POST/PUT/PATCH data \u2014 use "body" instead.'
41706
42046
  },
41707
42047
  headers: {
41708
42048
  type: "object",
@@ -41767,7 +42107,10 @@ var ConnectorTools = class {
41767
42107
  };
41768
42108
  }
41769
42109
  },
41770
- describeCall: (args) => `${args.method} ${args.endpoint}`,
42110
+ describeCall: (args) => {
42111
+ const bodyInfo = args.body ? ` body=${JSON.stringify(args.body).slice(0, 100)}` : "";
42112
+ return `${args.method} ${args.endpoint}${bodyInfo}`;
42113
+ },
41771
42114
  permission: options?.permission ?? {
41772
42115
  scope: "session",
41773
42116
  riskLevel: "medium",
@@ -41802,8 +42145,8 @@ var FileStorage = class {
41802
42145
  }
41803
42146
  async ensureDirectory() {
41804
42147
  try {
41805
- await fs14__namespace.mkdir(this.directory, { recursive: true });
41806
- await fs14__namespace.chmod(this.directory, 448);
42148
+ await fs15__namespace.mkdir(this.directory, { recursive: true });
42149
+ await fs15__namespace.chmod(this.directory, 448);
41807
42150
  } catch (error) {
41808
42151
  }
41809
42152
  }
@@ -41812,20 +42155,20 @@ var FileStorage = class {
41812
42155
  */
41813
42156
  getFilePath(key) {
41814
42157
  const hash = crypto2__namespace.createHash("sha256").update(key).digest("hex");
41815
- return path3__namespace.join(this.directory, `${hash}.token`);
42158
+ return path2__namespace.join(this.directory, `${hash}.token`);
41816
42159
  }
41817
42160
  async storeToken(key, token) {
41818
42161
  await this.ensureDirectory();
41819
42162
  const filePath = this.getFilePath(key);
41820
42163
  const plaintext = JSON.stringify(token);
41821
42164
  const encrypted = encrypt(plaintext, this.encryptionKey);
41822
- await fs14__namespace.writeFile(filePath, encrypted, "utf8");
41823
- await fs14__namespace.chmod(filePath, 384);
42165
+ await fs15__namespace.writeFile(filePath, encrypted, "utf8");
42166
+ await fs15__namespace.chmod(filePath, 384);
41824
42167
  }
41825
42168
  async getToken(key) {
41826
42169
  const filePath = this.getFilePath(key);
41827
42170
  try {
41828
- const encrypted = await fs14__namespace.readFile(filePath, "utf8");
42171
+ const encrypted = await fs15__namespace.readFile(filePath, "utf8");
41829
42172
  const decrypted = decrypt(encrypted, this.encryptionKey);
41830
42173
  return JSON.parse(decrypted);
41831
42174
  } catch (error) {
@@ -41834,7 +42177,7 @@ var FileStorage = class {
41834
42177
  }
41835
42178
  console.error("Failed to read/decrypt token file:", error);
41836
42179
  try {
41837
- await fs14__namespace.unlink(filePath);
42180
+ await fs15__namespace.unlink(filePath);
41838
42181
  } catch {
41839
42182
  }
41840
42183
  return null;
@@ -41843,7 +42186,7 @@ var FileStorage = class {
41843
42186
  async deleteToken(key) {
41844
42187
  const filePath = this.getFilePath(key);
41845
42188
  try {
41846
- await fs14__namespace.unlink(filePath);
42189
+ await fs15__namespace.unlink(filePath);
41847
42190
  } catch (error) {
41848
42191
  if (error.code !== "ENOENT") {
41849
42192
  throw error;
@@ -41853,7 +42196,7 @@ var FileStorage = class {
41853
42196
  async hasToken(key) {
41854
42197
  const filePath = this.getFilePath(key);
41855
42198
  try {
41856
- await fs14__namespace.access(filePath);
42199
+ await fs15__namespace.access(filePath);
41857
42200
  return true;
41858
42201
  } catch {
41859
42202
  return false;
@@ -41864,7 +42207,7 @@ var FileStorage = class {
41864
42207
  */
41865
42208
  async listTokens() {
41866
42209
  try {
41867
- const files = await fs14__namespace.readdir(this.directory);
42210
+ const files = await fs15__namespace.readdir(this.directory);
41868
42211
  return files.filter((f) => f.endsWith(".token")).map((f) => f.replace(".token", ""));
41869
42212
  } catch {
41870
42213
  return [];
@@ -41875,10 +42218,10 @@ var FileStorage = class {
41875
42218
  */
41876
42219
  async clearAll() {
41877
42220
  try {
41878
- const files = await fs14__namespace.readdir(this.directory);
42221
+ const files = await fs15__namespace.readdir(this.directory);
41879
42222
  const tokenFiles = files.filter((f) => f.endsWith(".token"));
41880
42223
  await Promise.all(
41881
- tokenFiles.map((f) => fs14__namespace.unlink(path3__namespace.join(this.directory, f)).catch(() => {
42224
+ tokenFiles.map((f) => fs15__namespace.unlink(path2__namespace.join(this.directory, f)).catch(() => {
41882
42225
  }))
41883
42226
  );
41884
42227
  } catch {
@@ -42146,22 +42489,26 @@ var ConnectorConfigStore = class {
42146
42489
  * Encrypt secrets in ConnectorAuth based on auth type
42147
42490
  */
42148
42491
  encryptAuthSecrets(auth2) {
42492
+ const encryptedExtra = this.encryptExtra(auth2.extra);
42149
42493
  switch (auth2.type) {
42150
42494
  case "api_key":
42151
42495
  return {
42152
42496
  ...auth2,
42153
- apiKey: this.encryptValue(auth2.apiKey)
42497
+ apiKey: this.encryptValue(auth2.apiKey),
42498
+ ...encryptedExtra ? { extra: encryptedExtra } : {}
42154
42499
  };
42155
42500
  case "oauth":
42156
42501
  return {
42157
42502
  ...auth2,
42158
42503
  clientSecret: auth2.clientSecret ? this.encryptValue(auth2.clientSecret) : void 0,
42159
- privateKey: auth2.privateKey ? this.encryptValue(auth2.privateKey) : void 0
42504
+ privateKey: auth2.privateKey ? this.encryptValue(auth2.privateKey) : void 0,
42505
+ ...encryptedExtra ? { extra: encryptedExtra } : {}
42160
42506
  };
42161
42507
  case "jwt":
42162
42508
  return {
42163
42509
  ...auth2,
42164
- privateKey: this.encryptValue(auth2.privateKey)
42510
+ privateKey: this.encryptValue(auth2.privateKey),
42511
+ ...encryptedExtra ? { extra: encryptedExtra } : {}
42165
42512
  };
42166
42513
  default:
42167
42514
  return auth2;
@@ -42171,27 +42518,53 @@ var ConnectorConfigStore = class {
42171
42518
  * Decrypt secrets in ConnectorAuth based on auth type
42172
42519
  */
42173
42520
  decryptAuthSecrets(auth2) {
42521
+ const decryptedExtra = this.decryptExtra(auth2.extra);
42174
42522
  switch (auth2.type) {
42175
42523
  case "api_key":
42176
42524
  return {
42177
42525
  ...auth2,
42178
- apiKey: this.decryptValue(auth2.apiKey)
42526
+ apiKey: this.decryptValue(auth2.apiKey),
42527
+ ...decryptedExtra ? { extra: decryptedExtra } : {}
42179
42528
  };
42180
42529
  case "oauth":
42181
42530
  return {
42182
42531
  ...auth2,
42183
42532
  clientSecret: auth2.clientSecret ? this.decryptValue(auth2.clientSecret) : void 0,
42184
- privateKey: auth2.privateKey ? this.decryptValue(auth2.privateKey) : void 0
42533
+ privateKey: auth2.privateKey ? this.decryptValue(auth2.privateKey) : void 0,
42534
+ ...decryptedExtra ? { extra: decryptedExtra } : {}
42185
42535
  };
42186
42536
  case "jwt":
42187
42537
  return {
42188
42538
  ...auth2,
42189
- privateKey: this.decryptValue(auth2.privateKey)
42539
+ privateKey: this.decryptValue(auth2.privateKey),
42540
+ ...decryptedExtra ? { extra: decryptedExtra } : {}
42190
42541
  };
42191
42542
  default:
42192
42543
  return auth2;
42193
42544
  }
42194
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
+ }
42195
42568
  /**
42196
42569
  * Encrypt a single value if not already encrypted
42197
42570
  */
@@ -42269,20 +42642,20 @@ var FileConnectorStorage = class {
42269
42642
  throw new Error("FileConnectorStorage requires a directory path");
42270
42643
  }
42271
42644
  this.directory = config.directory;
42272
- this.indexPath = path3__namespace.join(this.directory, "_index.json");
42645
+ this.indexPath = path2__namespace.join(this.directory, "_index.json");
42273
42646
  }
42274
42647
  async save(name, stored) {
42275
42648
  await this.ensureDirectory();
42276
42649
  const filePath = this.getFilePath(name);
42277
42650
  const json = JSON.stringify(stored, null, 2);
42278
- await fs14__namespace.writeFile(filePath, json, "utf8");
42279
- await fs14__namespace.chmod(filePath, 384);
42651
+ await fs15__namespace.writeFile(filePath, json, "utf8");
42652
+ await fs15__namespace.chmod(filePath, 384);
42280
42653
  await this.updateIndex(name, "add");
42281
42654
  }
42282
42655
  async get(name) {
42283
42656
  const filePath = this.getFilePath(name);
42284
42657
  try {
42285
- const json = await fs14__namespace.readFile(filePath, "utf8");
42658
+ const json = await fs15__namespace.readFile(filePath, "utf8");
42286
42659
  return JSON.parse(json);
42287
42660
  } catch (error) {
42288
42661
  const err = error;
@@ -42295,7 +42668,7 @@ var FileConnectorStorage = class {
42295
42668
  async delete(name) {
42296
42669
  const filePath = this.getFilePath(name);
42297
42670
  try {
42298
- await fs14__namespace.unlink(filePath);
42671
+ await fs15__namespace.unlink(filePath);
42299
42672
  await this.updateIndex(name, "remove");
42300
42673
  return true;
42301
42674
  } catch (error) {
@@ -42309,7 +42682,7 @@ var FileConnectorStorage = class {
42309
42682
  async has(name) {
42310
42683
  const filePath = this.getFilePath(name);
42311
42684
  try {
42312
- await fs14__namespace.access(filePath);
42685
+ await fs15__namespace.access(filePath);
42313
42686
  return true;
42314
42687
  } catch {
42315
42688
  return false;
@@ -42335,13 +42708,13 @@ var FileConnectorStorage = class {
42335
42708
  */
42336
42709
  async clear() {
42337
42710
  try {
42338
- const files = await fs14__namespace.readdir(this.directory);
42711
+ const files = await fs15__namespace.readdir(this.directory);
42339
42712
  const connectorFiles = files.filter(
42340
42713
  (f) => f.endsWith(".connector.json") || f === "_index.json"
42341
42714
  );
42342
42715
  await Promise.all(
42343
42716
  connectorFiles.map(
42344
- (f) => fs14__namespace.unlink(path3__namespace.join(this.directory, f)).catch(() => {
42717
+ (f) => fs15__namespace.unlink(path2__namespace.join(this.directory, f)).catch(() => {
42345
42718
  })
42346
42719
  )
42347
42720
  );
@@ -42354,7 +42727,7 @@ var FileConnectorStorage = class {
42354
42727
  */
42355
42728
  getFilePath(name) {
42356
42729
  const hash = this.hashName(name);
42357
- return path3__namespace.join(this.directory, `${hash}.connector.json`);
42730
+ return path2__namespace.join(this.directory, `${hash}.connector.json`);
42358
42731
  }
42359
42732
  /**
42360
42733
  * Hash connector name to prevent enumeration
@@ -42368,8 +42741,8 @@ var FileConnectorStorage = class {
42368
42741
  async ensureDirectory() {
42369
42742
  if (this.initialized) return;
42370
42743
  try {
42371
- await fs14__namespace.mkdir(this.directory, { recursive: true });
42372
- await fs14__namespace.chmod(this.directory, 448);
42744
+ await fs15__namespace.mkdir(this.directory, { recursive: true });
42745
+ await fs15__namespace.chmod(this.directory, 448);
42373
42746
  this.initialized = true;
42374
42747
  } catch {
42375
42748
  this.initialized = true;
@@ -42380,7 +42753,7 @@ var FileConnectorStorage = class {
42380
42753
  */
42381
42754
  async loadIndex() {
42382
42755
  try {
42383
- const json = await fs14__namespace.readFile(this.indexPath, "utf8");
42756
+ const json = await fs15__namespace.readFile(this.indexPath, "utf8");
42384
42757
  return JSON.parse(json);
42385
42758
  } catch {
42386
42759
  return { connectors: {} };
@@ -42398,8 +42771,8 @@ var FileConnectorStorage = class {
42398
42771
  delete index.connectors[hash];
42399
42772
  }
42400
42773
  const json = JSON.stringify(index, null, 2);
42401
- await fs14__namespace.writeFile(this.indexPath, json, "utf8");
42402
- await fs14__namespace.chmod(this.indexPath, 384);
42774
+ await fs15__namespace.writeFile(this.indexPath, json, "utf8");
42775
+ await fs15__namespace.chmod(this.indexPath, 384);
42403
42776
  }
42404
42777
  };
42405
42778
 
@@ -42444,11 +42817,19 @@ function buildAuthConfig(authTemplate, credentials) {
42444
42817
  if (!credentials.apiKey) {
42445
42818
  throw new Error("API key is required for api_key auth");
42446
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
+ }
42447
42827
  return {
42448
42828
  type: "api_key",
42449
42829
  apiKey: credentials.apiKey,
42450
42830
  headerName: defaults.headerName ?? "Authorization",
42451
- headerPrefix: defaults.headerPrefix ?? "Bearer"
42831
+ headerPrefix: defaults.headerPrefix ?? "Bearer",
42832
+ ...Object.keys(extra).length > 0 ? { extra } : {}
42452
42833
  };
42453
42834
  }
42454
42835
  if (!authTemplate.flow) {
@@ -42718,8 +43099,9 @@ var slackTemplate = {
42718
43099
  id: "bot-token",
42719
43100
  name: "Bot Token",
42720
43101
  type: "api_key",
42721
- 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.",
42722
43103
  requiredFields: ["apiKey"],
43104
+ optionalFields: ["appToken", "signingSecret"],
42723
43105
  defaults: {
42724
43106
  type: "api_key",
42725
43107
  headerName: "Authorization",
@@ -44557,14 +44939,14 @@ function createMessageWithImages(text, imageUrls, role = "user" /* USER */) {
44557
44939
  var execAsync = util.promisify(child_process.exec);
44558
44940
  function cleanupTempFile(filePath) {
44559
44941
  try {
44560
- if (fs15__namespace.existsSync(filePath)) {
44561
- fs15__namespace.unlinkSync(filePath);
44942
+ if (fs16__namespace.existsSync(filePath)) {
44943
+ fs16__namespace.unlinkSync(filePath);
44562
44944
  }
44563
44945
  } catch {
44564
44946
  }
44565
44947
  }
44566
44948
  async function readClipboardImage() {
44567
- const platform2 = os__namespace.platform();
44949
+ const platform2 = os2__namespace.platform();
44568
44950
  try {
44569
44951
  switch (platform2) {
44570
44952
  case "darwin":
@@ -44587,7 +44969,7 @@ async function readClipboardImage() {
44587
44969
  }
44588
44970
  }
44589
44971
  async function readClipboardImageMac() {
44590
- const tempFile = path3__namespace.join(os__namespace.tmpdir(), `clipboard-${Date.now()}.png`);
44972
+ const tempFile = path2__namespace.join(os2__namespace.tmpdir(), `clipboard-${Date.now()}.png`);
44591
44973
  try {
44592
44974
  try {
44593
44975
  await execAsync(`pngpaste "${tempFile}"`);
@@ -44609,7 +44991,7 @@ async function readClipboardImageMac() {
44609
44991
  end try
44610
44992
  `;
44611
44993
  const { stdout } = await execAsync(`osascript -e '${script}'`);
44612
- if (stdout.includes("success") || fs15__namespace.existsSync(tempFile)) {
44994
+ if (stdout.includes("success") || fs16__namespace.existsSync(tempFile)) {
44613
44995
  return await convertFileToDataUri(tempFile);
44614
44996
  }
44615
44997
  return {
@@ -44622,18 +45004,18 @@ async function readClipboardImageMac() {
44622
45004
  }
44623
45005
  }
44624
45006
  async function readClipboardImageLinux() {
44625
- const tempFile = path3__namespace.join(os__namespace.tmpdir(), `clipboard-${Date.now()}.png`);
45007
+ const tempFile = path2__namespace.join(os2__namespace.tmpdir(), `clipboard-${Date.now()}.png`);
44626
45008
  try {
44627
45009
  try {
44628
45010
  await execAsync(`xclip -selection clipboard -t image/png -o > "${tempFile}"`);
44629
- if (fs15__namespace.existsSync(tempFile) && fs15__namespace.statSync(tempFile).size > 0) {
45011
+ if (fs16__namespace.existsSync(tempFile) && fs16__namespace.statSync(tempFile).size > 0) {
44630
45012
  return await convertFileToDataUri(tempFile);
44631
45013
  }
44632
45014
  } catch {
44633
45015
  }
44634
45016
  try {
44635
45017
  await execAsync(`wl-paste -t image/png > "${tempFile}"`);
44636
- if (fs15__namespace.existsSync(tempFile) && fs15__namespace.statSync(tempFile).size > 0) {
45018
+ if (fs16__namespace.existsSync(tempFile) && fs16__namespace.statSync(tempFile).size > 0) {
44637
45019
  return await convertFileToDataUri(tempFile);
44638
45020
  }
44639
45021
  } catch {
@@ -44647,7 +45029,7 @@ async function readClipboardImageLinux() {
44647
45029
  }
44648
45030
  }
44649
45031
  async function readClipboardImageWindows() {
44650
- const tempFile = path3__namespace.join(os__namespace.tmpdir(), `clipboard-${Date.now()}.png`);
45032
+ const tempFile = path2__namespace.join(os2__namespace.tmpdir(), `clipboard-${Date.now()}.png`);
44651
45033
  try {
44652
45034
  const psScript = `
44653
45035
  Add-Type -AssemblyName System.Windows.Forms;
@@ -44660,7 +45042,7 @@ async function readClipboardImageWindows() {
44660
45042
  }
44661
45043
  `;
44662
45044
  await execAsync(`powershell -Command "${psScript}"`);
44663
- if (fs15__namespace.existsSync(tempFile) && fs15__namespace.statSync(tempFile).size > 0) {
45045
+ if (fs16__namespace.existsSync(tempFile) && fs16__namespace.statSync(tempFile).size > 0) {
44664
45046
  return await convertFileToDataUri(tempFile);
44665
45047
  }
44666
45048
  return {
@@ -44673,7 +45055,7 @@ async function readClipboardImageWindows() {
44673
45055
  }
44674
45056
  async function convertFileToDataUri(filePath) {
44675
45057
  try {
44676
- const imageBuffer = fs15__namespace.readFileSync(filePath);
45058
+ const imageBuffer = fs16__namespace.readFileSync(filePath);
44677
45059
  const base64Image = imageBuffer.toString("base64");
44678
45060
  const magic = imageBuffer.slice(0, 4).toString("hex");
44679
45061
  let mimeType = "image/png";
@@ -44700,7 +45082,7 @@ async function convertFileToDataUri(filePath) {
44700
45082
  }
44701
45083
  }
44702
45084
  async function hasClipboardImage() {
44703
- const platform2 = os__namespace.platform();
45085
+ const platform2 = os2__namespace.platform();
44704
45086
  try {
44705
45087
  switch (platform2) {
44706
45088
  case "darwin":
@@ -44918,17 +45300,24 @@ __export(tools_exports, {
44918
45300
  ConnectorTools: () => ConnectorTools,
44919
45301
  DEFAULT_FILESYSTEM_CONFIG: () => DEFAULT_FILESYSTEM_CONFIG,
44920
45302
  DEFAULT_SHELL_CONFIG: () => DEFAULT_SHELL_CONFIG,
44921
- FileMediaOutputHandler: () => FileMediaOutputHandler,
45303
+ FileMediaOutputHandler: () => FileMediaStorage,
44922
45304
  ToolRegistry: () => ToolRegistry,
44923
45305
  bash: () => bash,
44924
45306
  createBashTool: () => createBashTool,
45307
+ createCreatePRTool: () => createCreatePRTool,
44925
45308
  createEditFileTool: () => createEditFileTool,
44926
45309
  createExecuteJavaScriptTool: () => createExecuteJavaScriptTool,
45310
+ createGetPRTool: () => createGetPRTool,
45311
+ createGitHubReadFileTool: () => createGitHubReadFileTool,
44927
45312
  createGlobTool: () => createGlobTool,
44928
45313
  createGrepTool: () => createGrepTool,
44929
45314
  createImageGenerationTool: () => createImageGenerationTool,
44930
45315
  createListDirectoryTool: () => createListDirectoryTool,
45316
+ createPRCommentsTool: () => createPRCommentsTool,
45317
+ createPRFilesTool: () => createPRFilesTool,
44931
45318
  createReadFileTool: () => createReadFileTool,
45319
+ createSearchCodeTool: () => createSearchCodeTool,
45320
+ createSearchFilesTool: () => createSearchFilesTool,
44932
45321
  createSpeechToTextTool: () => createSpeechToTextTool,
44933
45322
  createTextToSpeechTool: () => createTextToSpeechTool,
44934
45323
  createVideoTools: () => createVideoTools,
@@ -44940,6 +45329,7 @@ __export(tools_exports, {
44940
45329
  getAllBuiltInTools: () => getAllBuiltInTools,
44941
45330
  getBackgroundOutput: () => getBackgroundOutput,
44942
45331
  getMediaOutputHandler: () => getMediaOutputHandler,
45332
+ getMediaStorage: () => getMediaStorage,
44943
45333
  getToolByName: () => getToolByName,
44944
45334
  getToolCategories: () => getToolCategories,
44945
45335
  getToolRegistry: () => getToolRegistry,
@@ -44952,15 +45342,18 @@ __export(tools_exports, {
44952
45342
  jsonManipulator: () => jsonManipulator,
44953
45343
  killBackgroundProcess: () => killBackgroundProcess,
44954
45344
  listDirectory: () => listDirectory,
44955
- readFile: () => readFile4,
45345
+ parseRepository: () => parseRepository,
45346
+ readFile: () => readFile5,
45347
+ resolveRepository: () => resolveRepository,
44956
45348
  setMediaOutputHandler: () => setMediaOutputHandler,
45349
+ setMediaStorage: () => setMediaStorage,
44957
45350
  toolRegistry: () => toolRegistry,
44958
45351
  validatePath: () => validatePath,
44959
45352
  webFetch: () => webFetch,
44960
45353
  webFetchJS: () => webFetchJS,
44961
45354
  webScrape: () => webScrape,
44962
45355
  webSearch: () => webSearch,
44963
- writeFile: () => writeFile4
45356
+ writeFile: () => writeFile5
44964
45357
  });
44965
45358
  var DEFAULT_FILESYSTEM_CONFIG = {
44966
45359
  workingDirectory: process.cwd(),
@@ -45019,15 +45412,15 @@ function validatePath(inputPath, config = {}) {
45019
45412
  const blockedDirs = config.blockedDirectories || DEFAULT_FILESYSTEM_CONFIG.blockedDirectories;
45020
45413
  let expandedPath = inputPath;
45021
45414
  if (inputPath.startsWith("~/")) {
45022
- expandedPath = path3.resolve(os.homedir(), inputPath.slice(2));
45415
+ expandedPath = path2.resolve(os2.homedir(), inputPath.slice(2));
45023
45416
  } else if (inputPath === "~") {
45024
- expandedPath = os.homedir();
45417
+ expandedPath = os2.homedir();
45025
45418
  }
45026
45419
  let resolvedPath;
45027
- if (path3.isAbsolute(expandedPath)) {
45028
- resolvedPath = path3.normalize(expandedPath);
45420
+ if (path2.isAbsolute(expandedPath)) {
45421
+ resolvedPath = path2.normalize(expandedPath);
45029
45422
  } else {
45030
- resolvedPath = path3.resolve(workingDir, expandedPath);
45423
+ resolvedPath = path2.resolve(workingDir, expandedPath);
45031
45424
  }
45032
45425
  const pathSegments = resolvedPath.split("/").filter(Boolean);
45033
45426
  for (const blocked of blockedDirs) {
@@ -45040,7 +45433,7 @@ function validatePath(inputPath, config = {}) {
45040
45433
  };
45041
45434
  }
45042
45435
  } else {
45043
- const blockedPath = path3.isAbsolute(blocked) ? blocked : path3.resolve(workingDir, blocked);
45436
+ const blockedPath = path2.isAbsolute(blocked) ? blocked : path2.resolve(workingDir, blocked);
45044
45437
  if (resolvedPath.startsWith(blockedPath + "/") || resolvedPath === blockedPath) {
45045
45438
  return {
45046
45439
  valid: false,
@@ -45053,7 +45446,7 @@ function validatePath(inputPath, config = {}) {
45053
45446
  if (allowedDirs.length > 0) {
45054
45447
  let isAllowed = false;
45055
45448
  for (const allowed of allowedDirs) {
45056
- const allowedPath = path3.isAbsolute(allowed) ? allowed : path3.resolve(workingDir, allowed);
45449
+ const allowedPath = path2.isAbsolute(allowed) ? allowed : path2.resolve(workingDir, allowed);
45057
45450
  if (resolvedPath.startsWith(allowedPath + "/") || resolvedPath === allowedPath) {
45058
45451
  isAllowed = true;
45059
45452
  break;
@@ -45071,9 +45464,9 @@ function validatePath(inputPath, config = {}) {
45071
45464
  }
45072
45465
  function expandTilde(inputPath) {
45073
45466
  if (inputPath.startsWith("~/")) {
45074
- return path3.resolve(os.homedir(), inputPath.slice(2));
45467
+ return path2.resolve(os2.homedir(), inputPath.slice(2));
45075
45468
  } else if (inputPath === "~") {
45076
- return os.homedir();
45469
+ return os2.homedir();
45077
45470
  }
45078
45471
  return inputPath;
45079
45472
  }
@@ -45148,7 +45541,7 @@ EXAMPLES:
45148
45541
  };
45149
45542
  }
45150
45543
  const resolvedPath = validation.resolvedPath;
45151
- if (!fs15.existsSync(resolvedPath)) {
45544
+ if (!fs16.existsSync(resolvedPath)) {
45152
45545
  return {
45153
45546
  success: false,
45154
45547
  error: `File not found: ${file_path}`,
@@ -45156,7 +45549,7 @@ EXAMPLES:
45156
45549
  };
45157
45550
  }
45158
45551
  try {
45159
- const stats = await fs14.stat(resolvedPath);
45552
+ const stats = await fs15.stat(resolvedPath);
45160
45553
  if (!stats.isFile()) {
45161
45554
  return {
45162
45555
  success: false,
@@ -45172,7 +45565,7 @@ EXAMPLES:
45172
45565
  size: stats.size
45173
45566
  };
45174
45567
  }
45175
- const content = await fs14.readFile(resolvedPath, "utf-8");
45568
+ const content = await fs15.readFile(resolvedPath, "utf-8");
45176
45569
  const allLines = content.split("\n");
45177
45570
  const totalLines = allLines.length;
45178
45571
  const startIndex = Math.max(0, offset - 1);
@@ -45213,7 +45606,7 @@ EXAMPLES:
45213
45606
  }
45214
45607
  };
45215
45608
  }
45216
- var readFile4 = createReadFileTool();
45609
+ var readFile5 = createReadFileTool();
45217
45610
  function createWriteFileTool(config = {}) {
45218
45611
  const mergedConfig = { ...DEFAULT_FILESYSTEM_CONFIG, ...config };
45219
45612
  return {
@@ -45277,13 +45670,13 @@ EXAMPLES:
45277
45670
  };
45278
45671
  }
45279
45672
  const resolvedPath = validation.resolvedPath;
45280
- const fileExists = fs15.existsSync(resolvedPath);
45673
+ const fileExists = fs16.existsSync(resolvedPath);
45281
45674
  try {
45282
- const parentDir = path3.dirname(resolvedPath);
45283
- if (!fs15.existsSync(parentDir)) {
45284
- await fs14.mkdir(parentDir, { recursive: true });
45675
+ const parentDir = path2.dirname(resolvedPath);
45676
+ if (!fs16.existsSync(parentDir)) {
45677
+ await fs15.mkdir(parentDir, { recursive: true });
45285
45678
  }
45286
- await fs14.writeFile(resolvedPath, content, "utf-8");
45679
+ await fs15.writeFile(resolvedPath, content, "utf-8");
45287
45680
  return {
45288
45681
  success: true,
45289
45682
  path: file_path,
@@ -45300,7 +45693,7 @@ EXAMPLES:
45300
45693
  }
45301
45694
  };
45302
45695
  }
45303
- var writeFile4 = createWriteFileTool();
45696
+ var writeFile5 = createWriteFileTool();
45304
45697
  function createEditFileTool(config = {}) {
45305
45698
  const mergedConfig = { ...DEFAULT_FILESYSTEM_CONFIG, ...config };
45306
45699
  return {
@@ -45386,7 +45779,7 @@ EXAMPLES:
45386
45779
  };
45387
45780
  }
45388
45781
  const resolvedPath = validation.resolvedPath;
45389
- if (!fs15.existsSync(resolvedPath)) {
45782
+ if (!fs16.existsSync(resolvedPath)) {
45390
45783
  return {
45391
45784
  success: false,
45392
45785
  error: `File not found: ${file_path}`,
@@ -45394,7 +45787,7 @@ EXAMPLES:
45394
45787
  };
45395
45788
  }
45396
45789
  try {
45397
- const content = await fs14.readFile(resolvedPath, "utf-8");
45790
+ const content = await fs15.readFile(resolvedPath, "utf-8");
45398
45791
  let occurrences = 0;
45399
45792
  let searchIndex = 0;
45400
45793
  while (true) {
@@ -45433,7 +45826,7 @@ EXAMPLES:
45433
45826
  } else {
45434
45827
  newContent = content.replace(old_string, new_string);
45435
45828
  }
45436
- await fs14.writeFile(resolvedPath, newContent, "utf-8");
45829
+ await fs15.writeFile(resolvedPath, newContent, "utf-8");
45437
45830
  const diffPreview = generateDiffPreview(old_string, new_string);
45438
45831
  return {
45439
45832
  success: true,
@@ -45489,11 +45882,11 @@ async function findFiles(dir, pattern, baseDir, config, results = [], depth = 0)
45489
45882
  return results;
45490
45883
  }
45491
45884
  try {
45492
- const entries = await fs14.readdir(dir, { withFileTypes: true });
45885
+ const entries = await fs15.readdir(dir, { withFileTypes: true });
45493
45886
  for (const entry of entries) {
45494
45887
  if (results.length >= config.maxResults) break;
45495
- const fullPath = path3.join(dir, entry.name);
45496
- const relativePath = path3.relative(baseDir, fullPath);
45888
+ const fullPath = path2.join(dir, entry.name);
45889
+ const relativePath = path2.relative(baseDir, fullPath);
45497
45890
  if (entry.isDirectory()) {
45498
45891
  const isBlocked = config.blockedDirectories.some(
45499
45892
  (blocked) => entry.name === blocked || relativePath.includes(`/${blocked}/`) || relativePath.startsWith(`${blocked}/`)
@@ -45503,7 +45896,7 @@ async function findFiles(dir, pattern, baseDir, config, results = [], depth = 0)
45503
45896
  } else if (entry.isFile()) {
45504
45897
  if (matchGlobPattern(pattern, relativePath)) {
45505
45898
  try {
45506
- const stats = await fs14.stat(fullPath);
45899
+ const stats = await fs15.stat(fullPath);
45507
45900
  results.push({
45508
45901
  path: relativePath,
45509
45902
  mtime: stats.mtimeMs
@@ -45585,7 +45978,7 @@ WHEN TO USE:
45585
45978
  };
45586
45979
  }
45587
45980
  const resolvedDir = validation.resolvedPath;
45588
- if (!fs15.existsSync(resolvedDir)) {
45981
+ if (!fs16.existsSync(resolvedDir)) {
45589
45982
  return {
45590
45983
  success: false,
45591
45984
  error: `Directory not found: ${searchDir}`
@@ -45640,9 +46033,9 @@ async function findFilesToSearch(dir, baseDir, config, globPattern, fileType, fi
45640
46033
  return files;
45641
46034
  }
45642
46035
  try {
45643
- const entries = await fs14.readdir(dir, { withFileTypes: true });
46036
+ const entries = await fs15.readdir(dir, { withFileTypes: true });
45644
46037
  for (const entry of entries) {
45645
- const fullPath = path3.join(dir, entry.name);
46038
+ const fullPath = path2.join(dir, entry.name);
45646
46039
  if (entry.isDirectory()) {
45647
46040
  const isBlocked = config.blockedDirectories.some(
45648
46041
  (blocked) => entry.name === blocked
@@ -45654,7 +46047,7 @@ async function findFilesToSearch(dir, baseDir, config, globPattern, fileType, fi
45654
46047
  if (fileType) {
45655
46048
  const extensions = FILE_TYPE_MAP[fileType.toLowerCase()];
45656
46049
  if (extensions) {
45657
- const ext = path3.extname(entry.name).toLowerCase();
46050
+ const ext = path2.extname(entry.name).toLowerCase();
45658
46051
  if (!extensions.includes(ext)) continue;
45659
46052
  }
45660
46053
  }
@@ -45673,7 +46066,7 @@ async function findFilesToSearch(dir, baseDir, config, globPattern, fileType, fi
45673
46066
  async function searchFile(filePath, regex, contextBefore, contextAfter) {
45674
46067
  const matches = [];
45675
46068
  try {
45676
- const content = await fs14.readFile(filePath, "utf-8");
46069
+ const content = await fs15.readFile(filePath, "utf-8");
45677
46070
  const lines = content.split("\n");
45678
46071
  for (let i = 0; i < lines.length; i++) {
45679
46072
  const line = lines[i] ?? "";
@@ -45814,7 +46207,7 @@ WHEN TO USE:
45814
46207
  };
45815
46208
  }
45816
46209
  const resolvedPath = validation.resolvedPath;
45817
- if (!fs15.existsSync(resolvedPath)) {
46210
+ if (!fs16.existsSync(resolvedPath)) {
45818
46211
  return {
45819
46212
  success: false,
45820
46213
  error: `Path not found: ${searchPath}`
@@ -45830,7 +46223,7 @@ WHEN TO USE:
45830
46223
  };
45831
46224
  }
45832
46225
  try {
45833
- const stats = await fs14.stat(resolvedPath);
46226
+ const stats = await fs15.stat(resolvedPath);
45834
46227
  let filesToSearch;
45835
46228
  if (stats.isFile()) {
45836
46229
  filesToSearch = [resolvedPath];
@@ -45856,7 +46249,7 @@ WHEN TO USE:
45856
46249
  );
45857
46250
  if (matches.length > 0) {
45858
46251
  filesMatched++;
45859
- const relativePath = path3.relative(resolvedPath, file) || file;
46252
+ const relativePath = path2.relative(resolvedPath, file) || file;
45860
46253
  for (const match of matches) {
45861
46254
  match.file = relativePath;
45862
46255
  }
@@ -45918,11 +46311,11 @@ async function listDir(dir, baseDir, config, recursive, filter, maxDepth = 3, cu
45918
46311
  return entries;
45919
46312
  }
45920
46313
  try {
45921
- const dirEntries = await fs14.readdir(dir, { withFileTypes: true });
46314
+ const dirEntries = await fs15.readdir(dir, { withFileTypes: true });
45922
46315
  for (const entry of dirEntries) {
45923
46316
  if (entries.length >= config.maxResults) break;
45924
- const fullPath = path3.join(dir, entry.name);
45925
- const relativePath = path3.relative(baseDir, fullPath);
46317
+ const fullPath = path2.join(dir, entry.name);
46318
+ const relativePath = path2.relative(baseDir, fullPath);
45926
46319
  if (entry.isDirectory() && config.blockedDirectories.includes(entry.name)) {
45927
46320
  continue;
45928
46321
  }
@@ -45936,7 +46329,7 @@ async function listDir(dir, baseDir, config, recursive, filter, maxDepth = 3, cu
45936
46329
  }
45937
46330
  if (filter === "directories" && !isDir) continue;
45938
46331
  try {
45939
- const stats = await fs14.stat(fullPath);
46332
+ const stats = await fs15.stat(fullPath);
45940
46333
  const dirEntry = {
45941
46334
  name: entry.name,
45942
46335
  path: relativePath,
@@ -46032,14 +46425,14 @@ EXAMPLES:
46032
46425
  };
46033
46426
  }
46034
46427
  const resolvedPath = validation.resolvedPath;
46035
- if (!fs15.existsSync(resolvedPath)) {
46428
+ if (!fs16.existsSync(resolvedPath)) {
46036
46429
  return {
46037
46430
  success: false,
46038
46431
  error: `Directory not found: ${path6}`
46039
46432
  };
46040
46433
  }
46041
46434
  try {
46042
- const stats = await fs14.stat(resolvedPath);
46435
+ const stats = await fs15.stat(resolvedPath);
46043
46436
  if (!stats.isDirectory()) {
46044
46437
  return {
46045
46438
  success: false,
@@ -46227,7 +46620,8 @@ EXAMPLES:
46227
46620
  shell: mergedConfig.shell,
46228
46621
  cwd: mergedConfig.workingDirectory,
46229
46622
  env,
46230
- stdio: ["pipe", "pipe", "pipe"]
46623
+ stdio: ["pipe", "pipe", "pipe"],
46624
+ detached: true
46231
46625
  });
46232
46626
  if (run_in_background && mergedConfig.allowBackground) {
46233
46627
  const bgId = generateBackgroundId();
@@ -46254,14 +46648,27 @@ EXAMPLES:
46254
46648
  let stdout = "";
46255
46649
  let stderr = "";
46256
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;
46257
46664
  const timeoutId = setTimeout(() => {
46258
46665
  killed = true;
46259
- childProcess.kill("SIGTERM");
46666
+ killProcessGroup("SIGTERM");
46260
46667
  setTimeout(() => {
46261
46668
  if (!childProcess.killed) {
46262
- childProcess.kill("SIGKILL");
46669
+ killProcessGroup("SIGKILL");
46263
46670
  }
46264
- }, 5e3);
46671
+ }, GRACEFUL_KILL_WAIT_MS);
46265
46672
  }, effectiveTimeout);
46266
46673
  childProcess.stdout.on("data", (data) => {
46267
46674
  stdout += data.toString();
@@ -46275,8 +46682,28 @@ EXAMPLES:
46275
46682
  stderr = stderr.slice(-mergedConfig.maxOutputSize);
46276
46683
  }
46277
46684
  });
46278
- childProcess.on("close", (code, signal) => {
46685
+ let resolved = false;
46686
+ const safeResolve = (result) => {
46687
+ if (resolved) return;
46688
+ resolved = true;
46279
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) => {
46280
46707
  const duration = Date.now() - startTime;
46281
46708
  let truncated = false;
46282
46709
  if (stdout.length > mergedConfig.maxOutputSize) {
@@ -46288,7 +46715,7 @@ EXAMPLES:
46288
46715
  truncated = true;
46289
46716
  }
46290
46717
  if (killed) {
46291
- resolve4({
46718
+ safeResolve({
46292
46719
  success: false,
46293
46720
  stdout,
46294
46721
  stderr,
@@ -46299,7 +46726,7 @@ EXAMPLES:
46299
46726
  error: `Command timed out after ${effectiveTimeout}ms`
46300
46727
  });
46301
46728
  } else {
46302
- resolve4({
46729
+ safeResolve({
46303
46730
  success: code === 0,
46304
46731
  stdout,
46305
46732
  stderr,
@@ -46312,8 +46739,7 @@ EXAMPLES:
46312
46739
  }
46313
46740
  });
46314
46741
  childProcess.on("error", (error) => {
46315
- clearTimeout(timeoutId);
46316
- resolve4({
46742
+ safeResolve({
46317
46743
  success: false,
46318
46744
  error: `Failed to execute command: ${error.message}`,
46319
46745
  duration: Date.now() - startTime
@@ -47579,8 +48005,8 @@ async function tryNative(args, startTime, attemptedMethods) {
47579
48005
  method: "native",
47580
48006
  title: result.title,
47581
48007
  content: cleanContent,
47582
- // Note: raw HTML not available with native method (returns markdown instead)
47583
- markdown: args.includeMarkdown ? cleanContent : void 0,
48008
+ // Native method already returns markdown-like content no separate markdown field needed
48009
+ // (would just duplicate content and waste tokens)
47584
48010
  qualityScore: result.qualityScore,
47585
48011
  durationMs: Date.now() - startTime,
47586
48012
  attemptedMethods,
@@ -47616,8 +48042,7 @@ async function tryJS(args, startTime, attemptedMethods) {
47616
48042
  method: "js",
47617
48043
  title: result.title,
47618
48044
  content: cleanContent,
47619
- // Note: raw HTML not available with JS method (returns markdown instead)
47620
- markdown: args.includeMarkdown ? cleanContent : void 0,
48045
+ // JS method already returns markdown-like content no separate markdown field needed
47621
48046
  qualityScore: result.success ? 80 : 0,
47622
48047
  durationMs: Date.now() - startTime,
47623
48048
  attemptedMethods,
@@ -47649,8 +48074,11 @@ async function tryAPI(connectorName, args, startTime, attemptedMethods) {
47649
48074
  includeLinks: args.includeLinks
47650
48075
  };
47651
48076
  const result = await provider.scrape(args.url, options);
47652
- const cleanContent = stripBase64DataUris(result.result?.content || "");
47653
- const cleanMarkdown = result.result?.markdown ? stripBase64DataUris(result.result.markdown) : void 0;
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;
47654
48082
  return {
47655
48083
  success: result.success,
47656
48084
  url: args.url,
@@ -47660,7 +48088,7 @@ async function tryAPI(connectorName, args, startTime, attemptedMethods) {
47660
48088
  content: cleanContent,
47661
48089
  html: result.result?.html,
47662
48090
  // Keep raw HTML as-is (only used if explicitly requested)
47663
- markdown: cleanMarkdown,
48091
+ markdown: isDuplicate ? void 0 : cleanMarkdown,
47664
48092
  metadata: result.result?.metadata,
47665
48093
  links: result.result?.links,
47666
48094
  qualityScore: result.success ? 90 : 0,
@@ -47875,68 +48303,25 @@ async function executeInVM(code, input, timeout, logs) {
47875
48303
  const result = await resultPromise;
47876
48304
  return result !== void 0 ? result : sandbox.output;
47877
48305
  }
47878
- var MIME_TYPES = {
47879
- png: "image/png",
47880
- jpeg: "image/jpeg",
47881
- jpg: "image/jpeg",
47882
- webp: "image/webp",
47883
- gif: "image/gif",
47884
- mp4: "video/mp4",
47885
- webm: "video/webm",
47886
- mp3: "audio/mpeg",
47887
- wav: "audio/wav",
47888
- opus: "audio/opus",
47889
- ogg: "audio/ogg",
47890
- aac: "audio/aac",
47891
- flac: "audio/flac",
47892
- pcm: "audio/pcm"
47893
- };
47894
- var FileMediaOutputHandler = class {
47895
- outputDir;
47896
- initialized = false;
47897
- constructor(outputDir) {
47898
- this.outputDir = outputDir ?? path3__namespace.join(os__namespace.tmpdir(), "oneringai-media");
47899
- }
47900
- async save(data, metadata) {
47901
- if (!this.initialized) {
47902
- await fs14__namespace.mkdir(this.outputDir, { recursive: true });
47903
- this.initialized = true;
47904
- }
47905
- const filename = metadata.suggestedFilename ?? this.generateFilename(metadata);
47906
- const filePath = path3__namespace.join(this.outputDir, filename);
47907
- await fs14__namespace.writeFile(filePath, data);
47908
- const format = metadata.format.toLowerCase();
47909
- const mimeType = MIME_TYPES[format] ?? `application/octet-stream`;
47910
- return {
47911
- location: filePath,
47912
- mimeType,
47913
- size: data.length
47914
- };
47915
- }
47916
- generateFilename(metadata) {
47917
- const timestamp = Date.now();
47918
- const random2 = crypto2__namespace.randomBytes(4).toString("hex");
47919
- const indexSuffix = metadata.index != null ? `_${metadata.index}` : "";
47920
- return `${metadata.type}_${timestamp}_${random2}${indexSuffix}.${metadata.format}`;
47921
- }
47922
- };
47923
48306
 
47924
48307
  // src/tools/multimedia/config.ts
47925
- var _outputHandler = null;
47926
- function getMediaOutputHandler() {
47927
- if (!_outputHandler) {
47928
- _outputHandler = new FileMediaOutputHandler();
48308
+ var _storage = null;
48309
+ function getMediaStorage() {
48310
+ if (!_storage) {
48311
+ _storage = new FileMediaStorage();
47929
48312
  }
47930
- return _outputHandler;
48313
+ return _storage;
47931
48314
  }
47932
- function setMediaOutputHandler(handler) {
47933
- _outputHandler = handler;
48315
+ function setMediaStorage(storage) {
48316
+ _storage = storage;
47934
48317
  }
48318
+ var getMediaOutputHandler = getMediaStorage;
48319
+ var setMediaOutputHandler = setMediaStorage;
47935
48320
 
47936
48321
  // src/tools/multimedia/imageGeneration.ts
47937
- function createImageGenerationTool(connector, outputHandler) {
48322
+ function createImageGenerationTool(connector, storage, userId) {
47938
48323
  const vendor = connector.vendor;
47939
- const handler = outputHandler ?? getMediaOutputHandler();
48324
+ const handler = storage ?? getMediaStorage();
47940
48325
  const vendorModels = vendor ? getImageModelsByVendor(vendor) : [];
47941
48326
  const modelNames = vendorModels.map((m) => m.name);
47942
48327
  const properties = {
@@ -48009,8 +48394,9 @@ function createImageGenerationTool(connector, outputHandler) {
48009
48394
  }
48010
48395
  }
48011
48396
  },
48012
- execute: async (args) => {
48397
+ execute: async (args, context) => {
48013
48398
  try {
48399
+ const effectiveUserId = userId ?? context?.userId;
48014
48400
  const imageGen = ImageGeneration.create({ connector });
48015
48401
  const response = await imageGen.generate({
48016
48402
  prompt: args.prompt,
@@ -48041,7 +48427,8 @@ function createImageGenerationTool(connector, outputHandler) {
48041
48427
  format,
48042
48428
  model: modelName,
48043
48429
  vendor: vendor || "unknown",
48044
- index: response.data.length > 1 ? i : void 0
48430
+ index: response.data.length > 1 ? i : void 0,
48431
+ userId: effectiveUserId
48045
48432
  });
48046
48433
  images.push({
48047
48434
  location: result.location,
@@ -48068,9 +48455,9 @@ function createImageGenerationTool(connector, outputHandler) {
48068
48455
 
48069
48456
  // src/tools/multimedia/videoGeneration.ts
48070
48457
  var videoGenInstances = /* @__PURE__ */ new Map();
48071
- function createVideoTools(connector, outputHandler) {
48458
+ function createVideoTools(connector, storage, userId) {
48072
48459
  const vendor = connector.vendor;
48073
- const handler = outputHandler ?? getMediaOutputHandler();
48460
+ const handler = storage ?? getMediaStorage();
48074
48461
  const vendorModels = vendor ? getVideoModelsByVendor(vendor) : [];
48075
48462
  const modelNames = vendorModels.map((m) => m.name);
48076
48463
  const generateProperties = {
@@ -48134,7 +48521,7 @@ function createVideoTools(connector, outputHandler) {
48134
48521
  }
48135
48522
  }
48136
48523
  },
48137
- execute: async (args) => {
48524
+ execute: async (args, _context) => {
48138
48525
  try {
48139
48526
  const videoGen = VideoGeneration.create({ connector });
48140
48527
  const response = await videoGen.generate({
@@ -48183,8 +48570,9 @@ function createVideoTools(connector, outputHandler) {
48183
48570
  }
48184
48571
  }
48185
48572
  },
48186
- execute: async (args) => {
48573
+ execute: async (args, context) => {
48187
48574
  try {
48575
+ const effectiveUserId = userId ?? context?.userId;
48188
48576
  let videoGen = videoGenInstances.get(args.jobId);
48189
48577
  if (!videoGen) {
48190
48578
  videoGen = VideoGeneration.create({ connector });
@@ -48210,7 +48598,8 @@ function createVideoTools(connector, outputHandler) {
48210
48598
  type: "video",
48211
48599
  format,
48212
48600
  model: modelName,
48213
- vendor: vendor || "unknown"
48601
+ vendor: vendor || "unknown",
48602
+ userId: effectiveUserId
48214
48603
  });
48215
48604
  videoGenInstances.delete(args.jobId);
48216
48605
  return {
@@ -48258,9 +48647,9 @@ function createVideoTools(connector, outputHandler) {
48258
48647
  }
48259
48648
 
48260
48649
  // src/tools/multimedia/textToSpeech.ts
48261
- function createTextToSpeechTool(connector, outputHandler) {
48650
+ function createTextToSpeechTool(connector, storage, userId) {
48262
48651
  const vendor = connector.vendor;
48263
- const handler = outputHandler ?? getMediaOutputHandler();
48652
+ const handler = storage ?? getMediaStorage();
48264
48653
  const vendorModels = vendor ? getTTSModelsByVendor(vendor) : [];
48265
48654
  const modelNames = vendorModels.map((m) => m.name);
48266
48655
  const properties = {
@@ -48321,8 +48710,9 @@ function createTextToSpeechTool(connector, outputHandler) {
48321
48710
  }
48322
48711
  }
48323
48712
  },
48324
- execute: async (args) => {
48713
+ execute: async (args, context) => {
48325
48714
  try {
48715
+ const effectiveUserId = userId ?? context?.userId;
48326
48716
  const tts = TextToSpeech.create({
48327
48717
  connector,
48328
48718
  model: args.model,
@@ -48336,7 +48726,8 @@ function createTextToSpeechTool(connector, outputHandler) {
48336
48726
  type: "audio",
48337
48727
  format,
48338
48728
  model: args.model || modelNames[0] || "unknown",
48339
- vendor: vendor || "unknown"
48729
+ vendor: vendor || "unknown",
48730
+ userId: effectiveUserId
48340
48731
  });
48341
48732
  return {
48342
48733
  success: true,
@@ -48359,14 +48750,17 @@ function createTextToSpeechTool(connector, outputHandler) {
48359
48750
  }
48360
48751
  };
48361
48752
  }
48362
- function createSpeechToTextTool(connector) {
48753
+
48754
+ // src/tools/multimedia/speechToText.ts
48755
+ function createSpeechToTextTool(connector, storage, _userId) {
48363
48756
  const vendor = connector.vendor;
48757
+ const handler = storage ?? getMediaStorage();
48364
48758
  const vendorModels = vendor ? getSTTModelsByVendor(vendor) : [];
48365
48759
  const modelNames = vendorModels.map((m) => m.name);
48366
48760
  const properties = {
48367
- audioFilePath: {
48761
+ audioSource: {
48368
48762
  type: "string",
48369
- description: "Path to the audio file to transcribe"
48763
+ description: "Path or location of the audio file to transcribe (file path, storage location, etc.)"
48370
48764
  }
48371
48765
  };
48372
48766
  if (modelNames.length > 0) {
@@ -48394,13 +48788,19 @@ function createSpeechToTextTool(connector) {
48394
48788
  parameters: {
48395
48789
  type: "object",
48396
48790
  properties,
48397
- required: ["audioFilePath"]
48791
+ required: ["audioSource"]
48398
48792
  }
48399
48793
  }
48400
48794
  },
48401
- execute: async (args) => {
48795
+ execute: async (args, _context) => {
48402
48796
  try {
48403
- const audioBuffer = await fs14__namespace.readFile(args.audioFilePath);
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
+ }
48404
48804
  const stt = SpeechToText.create({
48405
48805
  connector,
48406
48806
  model: args.model,
@@ -48422,7 +48822,7 @@ function createSpeechToTextTool(connector) {
48422
48822
  };
48423
48823
  }
48424
48824
  },
48425
- describeCall: (args) => args.audioFilePath,
48825
+ describeCall: (args) => args.audioSource,
48426
48826
  permission: {
48427
48827
  scope: "session",
48428
48828
  riskLevel: "low",
@@ -48437,21 +48837,22 @@ var VENDOR_CAPABILITIES = {
48437
48837
  [Vendor.Google]: ["image", "video", "tts"],
48438
48838
  [Vendor.Grok]: ["image", "video"]
48439
48839
  };
48440
- function registerMultimediaTools() {
48840
+ function registerMultimediaTools(storage) {
48441
48841
  for (const [vendor, capabilities] of Object.entries(VENDOR_CAPABILITIES)) {
48442
- ConnectorTools.registerService(vendor, (connector, _userId) => {
48842
+ ConnectorTools.registerService(vendor, (connector, userId) => {
48843
+ const handler = getMediaStorage();
48443
48844
  const tools = [];
48444
48845
  if (capabilities.includes("image")) {
48445
- tools.push(createImageGenerationTool(connector));
48846
+ tools.push(createImageGenerationTool(connector, handler, userId));
48446
48847
  }
48447
48848
  if (capabilities.includes("video")) {
48448
- tools.push(...createVideoTools(connector));
48849
+ tools.push(...createVideoTools(connector, handler, userId));
48449
48850
  }
48450
48851
  if (capabilities.includes("tts")) {
48451
- tools.push(createTextToSpeechTool(connector));
48852
+ tools.push(createTextToSpeechTool(connector, handler, userId));
48452
48853
  }
48453
48854
  if (capabilities.includes("stt")) {
48454
- tools.push(createSpeechToTextTool(connector));
48855
+ tools.push(createSpeechToTextTool(connector, handler));
48455
48856
  }
48456
48857
  return tools;
48457
48858
  });
@@ -48461,6 +48862,851 @@ function registerMultimediaTools() {
48461
48862
  // src/tools/multimedia/index.ts
48462
48863
  registerMultimediaTools();
48463
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
+
48464
49710
  // src/tools/registry.generated.ts
48465
49711
  var toolRegistry = [
48466
49712
  {
@@ -48514,7 +49760,7 @@ var toolRegistry = [
48514
49760
  displayName: "Read File",
48515
49761
  category: "filesystem",
48516
49762
  description: "Read content from a file on the local filesystem.",
48517
- tool: readFile4,
49763
+ tool: readFile5,
48518
49764
  safeByDefault: true
48519
49765
  },
48520
49766
  {
@@ -48523,7 +49769,7 @@ var toolRegistry = [
48523
49769
  displayName: "Write File",
48524
49770
  category: "filesystem",
48525
49771
  description: "Write content to a file on the local filesystem.",
48526
- tool: writeFile4,
49772
+ tool: writeFile5,
48527
49773
  safeByDefault: false
48528
49774
  },
48529
49775
  {
@@ -48752,8 +49998,8 @@ var ToolRegistry = class {
48752
49998
 
48753
49999
  // src/tools/index.ts
48754
50000
  var developerTools = [
48755
- readFile4,
48756
- writeFile4,
50001
+ readFile5,
50002
+ writeFile5,
48757
50003
  editFile,
48758
50004
  glob,
48759
50005
  grep,
@@ -48977,7 +50223,8 @@ exports.ExternalDependencyHandler = ExternalDependencyHandler;
48977
50223
  exports.FileAgentDefinitionStorage = FileAgentDefinitionStorage;
48978
50224
  exports.FileConnectorStorage = FileConnectorStorage;
48979
50225
  exports.FileContextStorage = FileContextStorage;
48980
- exports.FileMediaOutputHandler = FileMediaOutputHandler;
50226
+ exports.FileMediaOutputHandler = FileMediaStorage;
50227
+ exports.FileMediaStorage = FileMediaStorage;
48981
50228
  exports.FilePersistentInstructionsStorage = FilePersistentInstructionsStorage;
48982
50229
  exports.FileStorage = FileStorage;
48983
50230
  exports.HookManager = HookManager;
@@ -49083,11 +50330,15 @@ exports.createAgentStorage = createAgentStorage;
49083
50330
  exports.createAuthenticatedFetch = createAuthenticatedFetch;
49084
50331
  exports.createBashTool = createBashTool;
49085
50332
  exports.createConnectorFromTemplate = createConnectorFromTemplate;
50333
+ exports.createCreatePRTool = createCreatePRTool;
49086
50334
  exports.createEditFileTool = createEditFileTool;
49087
50335
  exports.createEstimator = createEstimator;
49088
50336
  exports.createExecuteJavaScriptTool = createExecuteJavaScriptTool;
49089
50337
  exports.createFileAgentDefinitionStorage = createFileAgentDefinitionStorage;
49090
50338
  exports.createFileContextStorage = createFileContextStorage;
50339
+ exports.createFileMediaStorage = createFileMediaStorage;
50340
+ exports.createGetPRTool = createGetPRTool;
50341
+ exports.createGitHubReadFileTool = createGitHubReadFileTool;
49091
50342
  exports.createGlobTool = createGlobTool;
49092
50343
  exports.createGrepTool = createGrepTool;
49093
50344
  exports.createImageGenerationTool = createImageGenerationTool;
@@ -49095,9 +50346,13 @@ exports.createImageProvider = createImageProvider;
49095
50346
  exports.createListDirectoryTool = createListDirectoryTool;
49096
50347
  exports.createMessageWithImages = createMessageWithImages;
49097
50348
  exports.createMetricsCollector = createMetricsCollector;
50349
+ exports.createPRCommentsTool = createPRCommentsTool;
50350
+ exports.createPRFilesTool = createPRFilesTool;
49098
50351
  exports.createPlan = createPlan;
49099
50352
  exports.createProvider = createProvider;
49100
50353
  exports.createReadFileTool = createReadFileTool;
50354
+ exports.createSearchCodeTool = createSearchCodeTool;
50355
+ exports.createSearchFilesTool = createSearchFilesTool;
49101
50356
  exports.createSpeechToTextTool = createSpeechToTextTool;
49102
50357
  exports.createTask = createTask;
49103
50358
  exports.createTextMessage = createTextMessage;
@@ -49137,6 +50392,7 @@ exports.getImageModelInfo = getImageModelInfo;
49137
50392
  exports.getImageModelsByVendor = getImageModelsByVendor;
49138
50393
  exports.getImageModelsWithFeature = getImageModelsWithFeature;
49139
50394
  exports.getMediaOutputHandler = getMediaOutputHandler;
50395
+ exports.getMediaStorage = getMediaStorage;
49140
50396
  exports.getModelInfo = getModelInfo;
49141
50397
  exports.getModelsByVendor = getModelsByVendor;
49142
50398
  exports.getNextExecutableTasks = getNextExecutableTasks;
@@ -49159,6 +50415,7 @@ exports.getToolsByCategory = getToolsByCategory;
49159
50415
  exports.getToolsRequiringConnector = getToolsRequiringConnector;
49160
50416
  exports.getVendorAuthTemplate = getVendorAuthTemplate;
49161
50417
  exports.getVendorColor = getVendorColor;
50418
+ exports.getVendorDefaultBaseURL = getVendorDefaultBaseURL;
49162
50419
  exports.getVendorInfo = getVendorInfo;
49163
50420
  exports.getVendorLogo = getVendorLogo;
49164
50421
  exports.getVendorLogoCdnUrl = getVendorLogoCdnUrl;
@@ -49197,15 +50454,18 @@ exports.listVendors = listVendors;
49197
50454
  exports.listVendorsByAuthType = listVendorsByAuthType;
49198
50455
  exports.listVendorsByCategory = listVendorsByCategory;
49199
50456
  exports.listVendorsWithLogos = listVendorsWithLogos;
50457
+ exports.parseRepository = parseRepository;
49200
50458
  exports.readClipboardImage = readClipboardImage;
49201
- exports.readFile = readFile4;
50459
+ exports.readFile = readFile5;
49202
50460
  exports.registerScrapeProvider = registerScrapeProvider;
49203
50461
  exports.resolveConnector = resolveConnector;
49204
50462
  exports.resolveDependencies = resolveDependencies;
50463
+ exports.resolveRepository = resolveRepository;
49205
50464
  exports.retryWithBackoff = retryWithBackoff;
49206
50465
  exports.scopeEquals = scopeEquals;
49207
50466
  exports.scopeMatches = scopeMatches;
49208
50467
  exports.setMediaOutputHandler = setMediaOutputHandler;
50468
+ exports.setMediaStorage = setMediaStorage;
49209
50469
  exports.setMetricsCollector = setMetricsCollector;
49210
50470
  exports.simpleTokenEstimator = simpleTokenEstimator;
49211
50471
  exports.toConnectorOptions = toConnectorOptions;
@@ -49213,6 +50473,6 @@ exports.toolRegistry = toolRegistry;
49213
50473
  exports.tools = tools_exports;
49214
50474
  exports.updateTaskStatus = updateTaskStatus;
49215
50475
  exports.validatePath = validatePath;
49216
- exports.writeFile = writeFile4;
50476
+ exports.writeFile = writeFile5;
49217
50477
  //# sourceMappingURL=index.cjs.map
49218
50478
  //# sourceMappingURL=index.cjs.map