@everworker/oneringai 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import * as crypto2 from 'crypto';
2
2
  import { randomUUID } from 'crypto';
3
3
  import { importPKCS8, SignJWT } from 'jose';
4
- import * as fs15 from 'fs';
4
+ import * as fs16 from 'fs';
5
5
  import { promises, existsSync } from 'fs';
6
6
  import { EventEmitter } from 'eventemitter3';
7
- import * as path3 from 'path';
7
+ import * as path2 from 'path';
8
8
  import { join, resolve, dirname, relative, isAbsolute, normalize, extname } from 'path';
9
- import * as os from 'os';
9
+ import * as os2 from 'os';
10
10
  import { homedir } from 'os';
11
- import OpenAI2 from 'openai';
11
+ import OpenAI3 from 'openai';
12
12
  import Anthropic from '@anthropic-ai/sdk';
13
13
  import { GoogleGenAI } from '@google/genai';
14
14
  import 'zod/v3';
@@ -16,7 +16,7 @@ import * as z4mini from 'zod/v4-mini';
16
16
  import * as z from 'zod/v4';
17
17
  import process2 from 'process';
18
18
  import { PassThrough } from 'stream';
19
- import * as fs14 from 'fs/promises';
19
+ import * as fs15 from 'fs/promises';
20
20
  import { stat, readFile, mkdir, writeFile, readdir } from 'fs/promises';
21
21
  import * as simpleIcons from 'simple-icons';
22
22
  import { exec, spawn } from 'child_process';
@@ -600,7 +600,7 @@ var init_JWTBearer = __esm({
600
600
  this.privateKey = config.privateKey;
601
601
  } else if (config.privateKeyPath) {
602
602
  try {
603
- this.privateKey = fs15.readFileSync(config.privateKeyPath, "utf8");
603
+ this.privateKey = fs16.readFileSync(config.privateKeyPath, "utf8");
604
604
  } catch (error) {
605
605
  throw new Error(`Failed to read private key from ${config.privateKeyPath}: ${error.message}`);
606
606
  }
@@ -1250,11 +1250,11 @@ var init_Logger = __esm({
1250
1250
  */
1251
1251
  initFileStream(filePath) {
1252
1252
  try {
1253
- const dir = path3.dirname(filePath);
1254
- if (!fs15.existsSync(dir)) {
1255
- fs15.mkdirSync(dir, { recursive: true });
1253
+ const dir = path2.dirname(filePath);
1254
+ if (!fs16.existsSync(dir)) {
1255
+ fs16.mkdirSync(dir, { recursive: true });
1256
1256
  }
1257
- this.fileStream = fs15.createWriteStream(filePath, {
1257
+ this.fileStream = fs16.createWriteStream(filePath, {
1258
1258
  flags: "a",
1259
1259
  // append mode
1260
1260
  encoding: "utf8"
@@ -14524,12 +14524,12 @@ var require_dist = __commonJS({
14524
14524
  throw new Error(`Unknown format "${name}"`);
14525
14525
  return f;
14526
14526
  };
14527
- function addFormats(ajv, list, fs18, exportName) {
14527
+ function addFormats(ajv, list, fs17, exportName) {
14528
14528
  var _a;
14529
14529
  var _b;
14530
14530
  (_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
14531
14531
  for (const f of list)
14532
- ajv.addFormat(f, fs18[f]);
14532
+ ajv.addFormat(f, fs17[f]);
14533
14533
  }
14534
14534
  module.exports = exports$1 = formatsPlugin;
14535
14535
  Object.defineProperty(exports$1, "__esModule", { value: true });
@@ -14542,7 +14542,7 @@ var require_windows = __commonJS({
14542
14542
  "node_modules/isexe/windows.js"(exports$1, module) {
14543
14543
  module.exports = isexe;
14544
14544
  isexe.sync = sync;
14545
- var fs18 = __require("fs");
14545
+ var fs17 = __require("fs");
14546
14546
  function checkPathExt(path6, options) {
14547
14547
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
14548
14548
  if (!pathext) {
@@ -14560,19 +14560,19 @@ var require_windows = __commonJS({
14560
14560
  }
14561
14561
  return false;
14562
14562
  }
14563
- function checkStat(stat5, path6, options) {
14564
- if (!stat5.isSymbolicLink() && !stat5.isFile()) {
14563
+ function checkStat(stat6, path6, options) {
14564
+ if (!stat6.isSymbolicLink() && !stat6.isFile()) {
14565
14565
  return false;
14566
14566
  }
14567
14567
  return checkPathExt(path6, options);
14568
14568
  }
14569
14569
  function isexe(path6, options, cb) {
14570
- fs18.stat(path6, function(er, stat5) {
14571
- cb(er, er ? false : checkStat(stat5, path6, options));
14570
+ fs17.stat(path6, function(er, stat6) {
14571
+ cb(er, er ? false : checkStat(stat6, path6, options));
14572
14572
  });
14573
14573
  }
14574
14574
  function sync(path6, options) {
14575
- return checkStat(fs18.statSync(path6), path6, options);
14575
+ return checkStat(fs17.statSync(path6), path6, options);
14576
14576
  }
14577
14577
  }
14578
14578
  });
@@ -14582,22 +14582,22 @@ var require_mode = __commonJS({
14582
14582
  "node_modules/isexe/mode.js"(exports$1, module) {
14583
14583
  module.exports = isexe;
14584
14584
  isexe.sync = sync;
14585
- var fs18 = __require("fs");
14585
+ var fs17 = __require("fs");
14586
14586
  function isexe(path6, options, cb) {
14587
- fs18.stat(path6, function(er, stat5) {
14588
- cb(er, er ? false : checkStat(stat5, options));
14587
+ fs17.stat(path6, function(er, stat6) {
14588
+ cb(er, er ? false : checkStat(stat6, options));
14589
14589
  });
14590
14590
  }
14591
14591
  function sync(path6, options) {
14592
- return checkStat(fs18.statSync(path6), options);
14592
+ return checkStat(fs17.statSync(path6), options);
14593
14593
  }
14594
- function checkStat(stat5, options) {
14595
- return stat5.isFile() && checkMode(stat5, options);
14594
+ function checkStat(stat6, options) {
14595
+ return stat6.isFile() && checkMode(stat6, options);
14596
14596
  }
14597
- function checkMode(stat5, options) {
14598
- var mod = stat5.mode;
14599
- var uid = stat5.uid;
14600
- var gid = stat5.gid;
14597
+ function checkMode(stat6, options) {
14598
+ var mod = stat6.mode;
14599
+ var uid = stat6.uid;
14600
+ var gid = stat6.gid;
14601
14601
  var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
14602
14602
  var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
14603
14603
  var u = parseInt("100", 8);
@@ -14871,16 +14871,16 @@ var require_shebang_command = __commonJS({
14871
14871
  // node_modules/cross-spawn/lib/util/readShebang.js
14872
14872
  var require_readShebang = __commonJS({
14873
14873
  "node_modules/cross-spawn/lib/util/readShebang.js"(exports$1, module) {
14874
- var fs18 = __require("fs");
14874
+ var fs17 = __require("fs");
14875
14875
  var shebangCommand = require_shebang_command();
14876
14876
  function readShebang(command) {
14877
14877
  const size = 150;
14878
14878
  const buffer = Buffer.alloc(size);
14879
14879
  let fd;
14880
14880
  try {
14881
- fd = fs18.openSync(command, "r");
14882
- fs18.readSync(fd, buffer, 0, size, 0);
14883
- fs18.closeSync(fd);
14881
+ fd = fs17.openSync(command, "r");
14882
+ fs17.readSync(fd, buffer, 0, size, 0);
14883
+ fs17.closeSync(fd);
14884
14884
  } catch (e) {
14885
14885
  }
14886
14886
  return shebangCommand(buffer.toString());
@@ -15989,13 +15989,26 @@ var ToolManager = class extends EventEmitter {
15989
15989
  pipeline;
15990
15990
  /** Optional tool context for execution (set by agent before runs) */
15991
15991
  _toolContext;
15992
- constructor() {
15992
+ /** Hard timeout for tool execution (0 = disabled) */
15993
+ _toolExecutionTimeout;
15994
+ constructor(config) {
15993
15995
  super();
15996
+ this._toolExecutionTimeout = config?.toolExecutionTimeout ?? 0;
15994
15997
  this.namespaceIndex.set("default", /* @__PURE__ */ new Set());
15995
15998
  this.toolLogger = logger.child({ component: "ToolManager" });
15996
15999
  this.pipeline = new ToolExecutionPipeline();
15997
16000
  this.pipeline.use(new ResultNormalizerPlugin());
15998
16001
  }
16002
+ /**
16003
+ * Get or set the hard tool execution timeout in milliseconds.
16004
+ * 0 = disabled (relies on tool's own timeout).
16005
+ */
16006
+ get toolExecutionTimeout() {
16007
+ return this._toolExecutionTimeout;
16008
+ }
16009
+ set toolExecutionTimeout(value) {
16010
+ this._toolExecutionTimeout = Math.max(0, value);
16011
+ }
15999
16012
  /**
16000
16013
  * Access the execution pipeline for plugin management.
16001
16014
  *
@@ -16493,7 +16506,7 @@ var ToolManager = class extends EventEmitter {
16493
16506
  const startTime = Date.now();
16494
16507
  metrics.increment("tool.executed", 1, { tool: toolName });
16495
16508
  try {
16496
- const result = await breaker.execute(async () => {
16509
+ const executionPromise = breaker.execute(async () => {
16497
16510
  const toolWithContext = {
16498
16511
  ...registration.tool,
16499
16512
  execute: async (pipelineArgs) => {
@@ -16502,6 +16515,7 @@ var ToolManager = class extends EventEmitter {
16502
16515
  };
16503
16516
  return await this.pipeline.execute(toolWithContext, args);
16504
16517
  });
16518
+ const result = this._toolExecutionTimeout > 0 ? await this.withHardTimeout(executionPromise, toolName, this._toolExecutionTimeout) : await executionPromise;
16505
16519
  const duration = Date.now() - startTime;
16506
16520
  this.recordExecution(toolName, duration, true);
16507
16521
  const resultSummary = this.summarizeResult(result);
@@ -16564,6 +16578,29 @@ var ToolManager = class extends EventEmitter {
16564
16578
  return this.list();
16565
16579
  }
16566
16580
  // ==========================================================================
16581
+ // Hard Timeout
16582
+ // ==========================================================================
16583
+ /**
16584
+ * Wrap a promise with a hard timeout safety net.
16585
+ * If the promise doesn't resolve within the timeout, throws ToolExecutionError.
16586
+ */
16587
+ async withHardTimeout(promise, toolName, timeoutMs) {
16588
+ let timeoutId;
16589
+ const timeoutPromise = new Promise((_, reject) => {
16590
+ timeoutId = setTimeout(() => {
16591
+ reject(new ToolExecutionError(
16592
+ toolName,
16593
+ `Tool execution hard timeout after ${timeoutMs}ms (safety net - tool's own timeout may have failed)`
16594
+ ));
16595
+ }, timeoutMs);
16596
+ });
16597
+ try {
16598
+ return await Promise.race([promise, timeoutPromise]);
16599
+ } finally {
16600
+ clearTimeout(timeoutId);
16601
+ }
16602
+ }
16603
+ // ==========================================================================
16567
16604
  // Circuit Breaker Management
16568
16605
  // ==========================================================================
16569
16606
  /**
@@ -20942,7 +20979,9 @@ var AgentContextNextGen = class _AgentContextNextGen extends EventEmitter {
20942
20979
  this._agentId = this._config.agentId;
20943
20980
  this._storage = config.storage;
20944
20981
  this._compactionStrategy = config.compactionStrategy ?? StrategyRegistry.create(this._config.strategy);
20945
- this._tools = new ToolManager();
20982
+ this._tools = new ToolManager(
20983
+ config.toolExecutionTimeout ? { toolExecutionTimeout: config.toolExecutionTimeout } : void 0
20984
+ );
20946
20985
  if (config.tools) {
20947
20986
  for (const tool of config.tools) {
20948
20987
  this._tools.register(tool);
@@ -22678,7 +22717,7 @@ var OpenAITextProvider = class extends BaseTextProvider {
22678
22717
  streamConverter;
22679
22718
  constructor(config) {
22680
22719
  super(config);
22681
- this.client = new OpenAI2({
22720
+ this.client = new OpenAI3({
22682
22721
  apiKey: this.getApiKey(),
22683
22722
  baseURL: this.getBaseURL(),
22684
22723
  organization: config.organization,
@@ -24408,7 +24447,9 @@ var GoogleTextProvider = class extends BaseTextProvider {
24408
24447
  constructor(config) {
24409
24448
  super(config);
24410
24449
  this.client = new GoogleGenAI({
24411
- apiKey: this.getApiKey()
24450
+ apiKey: this.getApiKey(),
24451
+ // Pass custom baseURL for proxy support (e.g. when routing through EW proxy)
24452
+ ...config.baseURL ? { httpOptions: { baseUrl: config.baseURL } } : {}
24412
24453
  });
24413
24454
  this.converter = new GoogleConverter();
24414
24455
  this.streamConverter = new GoogleStreamConverter();
@@ -24705,6 +24746,30 @@ var GenericOpenAIProvider = class extends OpenAITextProvider {
24705
24746
  };
24706
24747
 
24707
24748
  // src/core/createProvider.ts
24749
+ var VENDOR_DEFAULT_URLS = (() => {
24750
+ const map = /* @__PURE__ */ new Map();
24751
+ try {
24752
+ map.set(Vendor.OpenAI, new OpenAI3({ apiKey: "_" }).baseURL);
24753
+ } catch {
24754
+ }
24755
+ try {
24756
+ map.set(Vendor.Anthropic, new Anthropic({ apiKey: "_" }).baseURL);
24757
+ } catch {
24758
+ }
24759
+ map.set(Vendor.Google, "https://generativelanguage.googleapis.com");
24760
+ map.set(Vendor.GoogleVertex, "https://us-central1-aiplatform.googleapis.com");
24761
+ map.set(Vendor.Groq, "https://api.groq.com/openai/v1");
24762
+ map.set(Vendor.Together, "https://api.together.xyz/v1");
24763
+ map.set(Vendor.Perplexity, "https://api.perplexity.ai");
24764
+ map.set(Vendor.Grok, "https://api.x.ai/v1");
24765
+ map.set(Vendor.DeepSeek, "https://api.deepseek.com/v1");
24766
+ map.set(Vendor.Mistral, "https://api.mistral.ai/v1");
24767
+ map.set(Vendor.Ollama, "http://localhost:11434/v1");
24768
+ return map;
24769
+ })();
24770
+ function getVendorDefaultBaseURL(vendor) {
24771
+ return VENDOR_DEFAULT_URLS.get(vendor);
24772
+ }
24708
24773
  function createProvider(connector) {
24709
24774
  const injectedProvider = connector.getOptions().provider;
24710
24775
  if (injectedProvider && typeof injectedProvider.generate === "function") {
@@ -24739,39 +24804,15 @@ function createProvider(connector) {
24739
24804
  });
24740
24805
  // OpenAI-compatible providers (use connector.name for unique identification)
24741
24806
  case Vendor.Groq:
24742
- return new GenericOpenAIProvider(connector.name, {
24743
- ...config,
24744
- baseURL: config.baseURL || "https://api.groq.com/openai/v1"
24745
- });
24746
24807
  case Vendor.Together:
24747
- return new GenericOpenAIProvider(connector.name, {
24748
- ...config,
24749
- baseURL: config.baseURL || "https://api.together.xyz/v1"
24750
- });
24751
24808
  case Vendor.Perplexity:
24752
- return new GenericOpenAIProvider(connector.name, {
24753
- ...config,
24754
- baseURL: config.baseURL || "https://api.perplexity.ai"
24755
- });
24756
24809
  case Vendor.Grok:
24757
- return new GenericOpenAIProvider(connector.name, {
24758
- ...config,
24759
- baseURL: config.baseURL || "https://api.x.ai/v1"
24760
- });
24761
24810
  case Vendor.DeepSeek:
24762
- return new GenericOpenAIProvider(connector.name, {
24763
- ...config,
24764
- baseURL: config.baseURL || "https://api.deepseek.com/v1"
24765
- });
24766
24811
  case Vendor.Mistral:
24767
- return new GenericOpenAIProvider(connector.name, {
24768
- ...config,
24769
- baseURL: config.baseURL || "https://api.mistral.ai/v1"
24770
- });
24771
24812
  case Vendor.Ollama:
24772
24813
  return new GenericOpenAIProvider(connector.name, {
24773
24814
  ...config,
24774
- baseURL: config.baseURL || "http://localhost:11434/v1"
24815
+ baseURL: config.baseURL || getVendorDefaultBaseURL(vendor)
24775
24816
  });
24776
24817
  case Vendor.Custom:
24777
24818
  if (!config.baseURL) {
@@ -24883,7 +24924,10 @@ var BaseAgent = class extends EventEmitter {
24883
24924
  agentId: config.name,
24884
24925
  // Include storage and sessionId if session config is provided
24885
24926
  storage: config.session?.storage,
24927
+ // Thread tool execution timeout to ToolManager
24928
+ toolExecutionTimeout: config.toolExecutionTimeout,
24886
24929
  // Subclasses can add systemPrompt via their config
24930
+ // Note: context-level toolExecutionTimeout overrides agent-level if both set
24887
24931
  ...typeof config.context === "object" && config.context !== null ? config.context : {}
24888
24932
  };
24889
24933
  return AgentContextNextGen.create(contextConfig);
@@ -27355,8 +27399,8 @@ var Agent = class _Agent extends BaseAgent {
27355
27399
  throw new Error("Configuration file not found. Searched: " + this.DEFAULT_PATHS.join(", "));
27356
27400
  }
27357
27401
  try {
27358
- const fs18 = __require("fs");
27359
- const content = fs18.readFileSync(configPath, "utf-8");
27402
+ const fs17 = __require("fs");
27403
+ const content = fs17.readFileSync(configPath, "utf-8");
27360
27404
  let config = JSON.parse(content);
27361
27405
  config = this.interpolateEnvVars(config);
27362
27406
  this.validate(config);
@@ -27385,10 +27429,10 @@ var Agent = class _Agent extends BaseAgent {
27385
27429
  * Find configuration file synchronously
27386
27430
  */
27387
27431
  static findConfigSync() {
27388
- const fs18 = __require("fs");
27432
+ const fs17 = __require("fs");
27389
27433
  for (const path6 of this.DEFAULT_PATHS) {
27390
27434
  try {
27391
- fs18.accessSync(resolve(path6));
27435
+ fs17.accessSync(resolve(path6));
27392
27436
  return resolve(path6);
27393
27437
  } catch {
27394
27438
  }
@@ -33335,7 +33379,7 @@ var OpenAITTSProvider = class extends BaseMediaProvider {
33335
33379
  client;
33336
33380
  constructor(config) {
33337
33381
  super({ apiKey: config.auth.apiKey, ...config });
33338
- this.client = new OpenAI2({
33382
+ this.client = new OpenAI3({
33339
33383
  apiKey: config.auth.apiKey,
33340
33384
  baseURL: config.baseURL,
33341
33385
  organization: config.organization,
@@ -33418,7 +33462,7 @@ var OpenAITTSProvider = class extends BaseMediaProvider {
33418
33462
  * Handle OpenAI API errors
33419
33463
  */
33420
33464
  handleError(error) {
33421
- if (error instanceof OpenAI2.APIError) {
33465
+ if (error instanceof OpenAI3.APIError) {
33422
33466
  const status = error.status;
33423
33467
  const message = error.message || "Unknown OpenAI API error";
33424
33468
  if (status === 401) {
@@ -33450,7 +33494,7 @@ var OpenAISTTProvider = class extends BaseMediaProvider {
33450
33494
  client;
33451
33495
  constructor(config) {
33452
33496
  super({ apiKey: config.auth.apiKey, ...config });
33453
- this.client = new OpenAI2({
33497
+ this.client = new OpenAI3({
33454
33498
  apiKey: config.auth.apiKey,
33455
33499
  baseURL: config.baseURL,
33456
33500
  organization: config.organization,
@@ -33552,7 +33596,7 @@ var OpenAISTTProvider = class extends BaseMediaProvider {
33552
33596
  if (Buffer.isBuffer(audio)) {
33553
33597
  return new File([new Uint8Array(audio)], "audio.wav", { type: "audio/wav" });
33554
33598
  } else if (typeof audio === "string") {
33555
- return fs15.createReadStream(audio);
33599
+ return fs16.createReadStream(audio);
33556
33600
  } else {
33557
33601
  throw new Error("Invalid audio input: must be Buffer or file path");
33558
33602
  }
@@ -33611,7 +33655,7 @@ var OpenAISTTProvider = class extends BaseMediaProvider {
33611
33655
  * Handle OpenAI API errors
33612
33656
  */
33613
33657
  handleError(error) {
33614
- if (error instanceof OpenAI2.APIError) {
33658
+ if (error instanceof OpenAI3.APIError) {
33615
33659
  const status = error.status;
33616
33660
  const message = error.message || "Unknown OpenAI API error";
33617
33661
  if (status === 401) {
@@ -34105,7 +34149,7 @@ var TextToSpeech = class _TextToSpeech {
34105
34149
  */
34106
34150
  async toFile(text, filePath, options) {
34107
34151
  const response = await this.synthesize(text, options);
34108
- await fs14.writeFile(filePath, response.audio);
34152
+ await fs15.writeFile(filePath, response.audio);
34109
34153
  }
34110
34154
  // ======================== Introspection Methods ========================
34111
34155
  /**
@@ -34453,7 +34497,7 @@ var SpeechToText = class _SpeechToText {
34453
34497
  * @param options - Optional transcription parameters
34454
34498
  */
34455
34499
  async transcribeFile(filePath, options) {
34456
- const audio = await fs14.readFile(filePath);
34500
+ const audio = await fs15.readFile(filePath);
34457
34501
  return this.transcribe(audio, options);
34458
34502
  }
34459
34503
  /**
@@ -34617,7 +34661,7 @@ var OpenAIImageProvider = class extends BaseMediaProvider {
34617
34661
  client;
34618
34662
  constructor(config) {
34619
34663
  super({ apiKey: config.auth.apiKey, ...config });
34620
- this.client = new OpenAI2({
34664
+ this.client = new OpenAI3({
34621
34665
  apiKey: config.auth.apiKey,
34622
34666
  baseURL: config.baseURL,
34623
34667
  organization: config.organization,
@@ -34779,7 +34823,7 @@ var OpenAIImageProvider = class extends BaseMediaProvider {
34779
34823
  if (Buffer.isBuffer(image)) {
34780
34824
  return new File([new Uint8Array(image)], "image.png", { type: "image/png" });
34781
34825
  }
34782
- return fs15.createReadStream(image);
34826
+ return fs16.createReadStream(image);
34783
34827
  }
34784
34828
  /**
34785
34829
  * Handle OpenAI API errors
@@ -34926,8 +34970,8 @@ var GoogleImageProvider = class extends BaseMediaProvider {
34926
34970
  if (Buffer.isBuffer(image)) {
34927
34971
  imageBytes = image.toString("base64");
34928
34972
  } else {
34929
- const fs18 = await import('fs');
34930
- const buffer = fs18.readFileSync(image);
34973
+ const fs17 = await import('fs');
34974
+ const buffer = fs17.readFileSync(image);
34931
34975
  imageBytes = buffer.toString("base64");
34932
34976
  }
34933
34977
  return {
@@ -34977,7 +35021,7 @@ var GrokImageProvider = class extends BaseMediaProvider {
34977
35021
  client;
34978
35022
  constructor(config) {
34979
35023
  super({ apiKey: config.auth.apiKey, ...config });
34980
- this.client = new OpenAI2({
35024
+ this.client = new OpenAI3({
34981
35025
  apiKey: config.auth.apiKey,
34982
35026
  baseURL: config.baseURL || GROK_API_BASE_URL,
34983
35027
  timeout: config.timeout,
@@ -35088,7 +35132,7 @@ var GrokImageProvider = class extends BaseMediaProvider {
35088
35132
  if (Buffer.isBuffer(image)) {
35089
35133
  return new File([new Uint8Array(image)], "image.png", { type: "image/png" });
35090
35134
  }
35091
- return fs15.createReadStream(image);
35135
+ return fs16.createReadStream(image);
35092
35136
  }
35093
35137
  /**
35094
35138
  * Handle API errors
@@ -36290,7 +36334,7 @@ var OpenAISoraProvider = class extends BaseMediaProvider {
36290
36334
  client;
36291
36335
  constructor(config) {
36292
36336
  super({ apiKey: config.auth.apiKey, ...config });
36293
- this.client = new OpenAI2({
36337
+ this.client = new OpenAI3({
36294
36338
  apiKey: config.auth.apiKey,
36295
36339
  baseURL: config.baseURL,
36296
36340
  organization: config.organization,
@@ -36538,8 +36582,8 @@ var OpenAISoraProvider = class extends BaseMediaProvider {
36538
36582
  return new File([new Uint8Array(image)], "input.png", { type: "image/png" });
36539
36583
  }
36540
36584
  if (!image.startsWith("http")) {
36541
- const fs18 = await import('fs');
36542
- const data = fs18.readFileSync(image);
36585
+ const fs17 = await import('fs');
36586
+ const data = fs17.readFileSync(image);
36543
36587
  return new File([new Uint8Array(data)], "input.png", { type: "image/png" });
36544
36588
  }
36545
36589
  const response = await fetch(image);
@@ -36717,7 +36761,7 @@ var GoogleVeoProvider = class extends BaseMediaProvider {
36717
36761
  if (video.videoBytes) {
36718
36762
  buffer = Buffer.from(video.videoBytes, "base64");
36719
36763
  } else if (video.uri) {
36720
- const fs18 = await import('fs/promises');
36764
+ const fs17 = await import('fs/promises');
36721
36765
  const os3 = await import('os');
36722
36766
  const path6 = await import('path');
36723
36767
  const tempDir = os3.tmpdir();
@@ -36728,11 +36772,11 @@ var GoogleVeoProvider = class extends BaseMediaProvider {
36728
36772
  // Pass as GeneratedVideo
36729
36773
  downloadPath: tempFile
36730
36774
  });
36731
- buffer = await fs18.readFile(tempFile);
36732
- await fs18.unlink(tempFile).catch(() => {
36775
+ buffer = await fs17.readFile(tempFile);
36776
+ await fs17.unlink(tempFile).catch(() => {
36733
36777
  });
36734
36778
  } catch (downloadError) {
36735
- await fs18.unlink(tempFile).catch(() => {
36779
+ await fs17.unlink(tempFile).catch(() => {
36736
36780
  });
36737
36781
  throw new ProviderError(
36738
36782
  "google",
@@ -36854,8 +36898,8 @@ var GoogleVeoProvider = class extends BaseMediaProvider {
36854
36898
  if (image.startsWith("http://") || image.startsWith("https://")) {
36855
36899
  return { imageUri: image };
36856
36900
  }
36857
- const fs18 = await import('fs/promises');
36858
- const data = await fs18.readFile(image);
36901
+ const fs17 = await import('fs/promises');
36902
+ const data = await fs17.readFile(image);
36859
36903
  return {
36860
36904
  imageBytes: data.toString("base64")
36861
36905
  };
@@ -37162,8 +37206,8 @@ var GrokImagineProvider = class extends BaseMediaProvider {
37162
37206
  if (image.startsWith("http") || image.startsWith("data:")) {
37163
37207
  return image;
37164
37208
  }
37165
- const fs18 = await import('fs');
37166
- const data = fs18.readFileSync(image);
37209
+ const fs17 = await import('fs');
37210
+ const data = fs17.readFileSync(image);
37167
37211
  const base64 = data.toString("base64");
37168
37212
  const ext = image.split(".").pop()?.toLowerCase() || "png";
37169
37213
  const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext}`;
@@ -40900,6 +40944,126 @@ var FileAgentDefinitionStorage = class {
40900
40944
  function createFileAgentDefinitionStorage(config) {
40901
40945
  return new FileAgentDefinitionStorage(config);
40902
40946
  }
40947
+ var MIME_TYPES = {
40948
+ png: "image/png",
40949
+ jpeg: "image/jpeg",
40950
+ jpg: "image/jpeg",
40951
+ webp: "image/webp",
40952
+ gif: "image/gif",
40953
+ mp4: "video/mp4",
40954
+ webm: "video/webm",
40955
+ mp3: "audio/mpeg",
40956
+ wav: "audio/wav",
40957
+ opus: "audio/opus",
40958
+ ogg: "audio/ogg",
40959
+ aac: "audio/aac",
40960
+ flac: "audio/flac",
40961
+ pcm: "audio/pcm"
40962
+ };
40963
+ var MEDIA_TYPE_PREFIXES = ["image", "video", "audio"];
40964
+ var FileMediaStorage = class {
40965
+ outputDir;
40966
+ initialized = false;
40967
+ constructor(config) {
40968
+ this.outputDir = config?.outputDir ?? path2.join(os2.tmpdir(), "oneringai-media");
40969
+ }
40970
+ async save(data, metadata) {
40971
+ const dir = metadata.userId ? path2.join(this.outputDir, metadata.userId) : this.outputDir;
40972
+ await fs15.mkdir(dir, { recursive: true });
40973
+ const filename = metadata.suggestedFilename ?? this.generateFilename(metadata);
40974
+ const filePath = path2.join(dir, filename);
40975
+ await fs15.writeFile(filePath, data);
40976
+ const format = metadata.format.toLowerCase();
40977
+ const mimeType = MIME_TYPES[format] ?? "application/octet-stream";
40978
+ return {
40979
+ location: filePath,
40980
+ mimeType,
40981
+ size: data.length
40982
+ };
40983
+ }
40984
+ async read(location) {
40985
+ try {
40986
+ return await fs15.readFile(location);
40987
+ } catch (err) {
40988
+ if (err.code === "ENOENT") {
40989
+ return null;
40990
+ }
40991
+ throw err;
40992
+ }
40993
+ }
40994
+ async delete(location) {
40995
+ try {
40996
+ await fs15.unlink(location);
40997
+ } catch (err) {
40998
+ if (err.code === "ENOENT") {
40999
+ return;
41000
+ }
41001
+ throw err;
41002
+ }
41003
+ }
41004
+ async exists(location) {
41005
+ try {
41006
+ await fs15.access(location);
41007
+ return true;
41008
+ } catch {
41009
+ return false;
41010
+ }
41011
+ }
41012
+ async list(options) {
41013
+ await this.ensureDir();
41014
+ let entries = [];
41015
+ const files = await fs15.readdir(this.outputDir);
41016
+ for (const file of files) {
41017
+ const filePath = path2.join(this.outputDir, file);
41018
+ try {
41019
+ const stat6 = await fs15.stat(filePath);
41020
+ if (!stat6.isFile()) continue;
41021
+ const ext = path2.extname(file).slice(1).toLowerCase();
41022
+ const mimeType = MIME_TYPES[ext] ?? "application/octet-stream";
41023
+ let type;
41024
+ for (const prefix of MEDIA_TYPE_PREFIXES) {
41025
+ if (file.startsWith(`${prefix}_`)) {
41026
+ type = prefix;
41027
+ break;
41028
+ }
41029
+ }
41030
+ entries.push({
41031
+ location: filePath,
41032
+ mimeType,
41033
+ size: stat6.size,
41034
+ type,
41035
+ createdAt: stat6.birthtime
41036
+ });
41037
+ } catch {
41038
+ }
41039
+ }
41040
+ if (options?.type) {
41041
+ entries = entries.filter((e) => e.type === options.type);
41042
+ }
41043
+ entries.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
41044
+ const offset = options?.offset ?? 0;
41045
+ const limit = options?.limit ?? entries.length;
41046
+ return entries.slice(offset, offset + limit);
41047
+ }
41048
+ getPath() {
41049
+ return this.outputDir;
41050
+ }
41051
+ generateFilename(metadata) {
41052
+ const timestamp = Date.now();
41053
+ const random2 = crypto2.randomBytes(4).toString("hex");
41054
+ const indexSuffix = metadata.index != null ? `_${metadata.index}` : "";
41055
+ return `${metadata.type}_${timestamp}_${random2}${indexSuffix}.${metadata.format}`;
41056
+ }
41057
+ async ensureDir() {
41058
+ if (!this.initialized) {
41059
+ await fs15.mkdir(this.outputDir, { recursive: true });
41060
+ this.initialized = true;
41061
+ }
41062
+ }
41063
+ };
41064
+ function createFileMediaStorage(config) {
41065
+ return new FileMediaStorage(config);
41066
+ }
40903
41067
 
40904
41068
  // src/capabilities/agents/StreamHelpers.ts
40905
41069
  var StreamHelpers = class {
@@ -41822,7 +41986,7 @@ var ConnectorTools = class {
41822
41986
  static createGenericAPITool(connector, options) {
41823
41987
  const toolName = options?.toolName ?? `${connector.name}_api`;
41824
41988
  const userId = options?.userId;
41825
- const description = options?.description ?? `Make an authenticated API call to ${connector.displayName}.` + (connector.baseURL ? ` Base URL: ${connector.baseURL}` : " Provide full URL in endpoint.");
41989
+ 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.';
41826
41990
  return {
41827
41991
  definition: {
41828
41992
  type: "function",
@@ -41839,15 +42003,15 @@ var ConnectorTools = class {
41839
42003
  },
41840
42004
  endpoint: {
41841
42005
  type: "string",
41842
- description: "API endpoint (relative to base URL) or full URL"
42006
+ 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.'
41843
42007
  },
41844
42008
  body: {
41845
42009
  type: "object",
41846
- description: "Request body (for POST/PUT/PATCH)"
42010
+ 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.'
41847
42011
  },
41848
42012
  queryParams: {
41849
42013
  type: "object",
41850
- description: "URL query parameters"
42014
+ description: 'URL query parameters (for filtering/pagination on GET requests). Do NOT use for POST/PUT/PATCH data \u2014 use "body" instead.'
41851
42015
  },
41852
42016
  headers: {
41853
42017
  type: "object",
@@ -41912,7 +42076,10 @@ var ConnectorTools = class {
41912
42076
  };
41913
42077
  }
41914
42078
  },
41915
- describeCall: (args) => `${args.method} ${args.endpoint}`,
42079
+ describeCall: (args) => {
42080
+ const bodyInfo = args.body ? ` body=${JSON.stringify(args.body).slice(0, 100)}` : "";
42081
+ return `${args.method} ${args.endpoint}${bodyInfo}`;
42082
+ },
41916
42083
  permission: options?.permission ?? {
41917
42084
  scope: "session",
41918
42085
  riskLevel: "medium",
@@ -41947,8 +42114,8 @@ var FileStorage = class {
41947
42114
  }
41948
42115
  async ensureDirectory() {
41949
42116
  try {
41950
- await fs14.mkdir(this.directory, { recursive: true });
41951
- await fs14.chmod(this.directory, 448);
42117
+ await fs15.mkdir(this.directory, { recursive: true });
42118
+ await fs15.chmod(this.directory, 448);
41952
42119
  } catch (error) {
41953
42120
  }
41954
42121
  }
@@ -41957,20 +42124,20 @@ var FileStorage = class {
41957
42124
  */
41958
42125
  getFilePath(key) {
41959
42126
  const hash = crypto2.createHash("sha256").update(key).digest("hex");
41960
- return path3.join(this.directory, `${hash}.token`);
42127
+ return path2.join(this.directory, `${hash}.token`);
41961
42128
  }
41962
42129
  async storeToken(key, token) {
41963
42130
  await this.ensureDirectory();
41964
42131
  const filePath = this.getFilePath(key);
41965
42132
  const plaintext = JSON.stringify(token);
41966
42133
  const encrypted = encrypt(plaintext, this.encryptionKey);
41967
- await fs14.writeFile(filePath, encrypted, "utf8");
41968
- await fs14.chmod(filePath, 384);
42134
+ await fs15.writeFile(filePath, encrypted, "utf8");
42135
+ await fs15.chmod(filePath, 384);
41969
42136
  }
41970
42137
  async getToken(key) {
41971
42138
  const filePath = this.getFilePath(key);
41972
42139
  try {
41973
- const encrypted = await fs14.readFile(filePath, "utf8");
42140
+ const encrypted = await fs15.readFile(filePath, "utf8");
41974
42141
  const decrypted = decrypt(encrypted, this.encryptionKey);
41975
42142
  return JSON.parse(decrypted);
41976
42143
  } catch (error) {
@@ -41979,7 +42146,7 @@ var FileStorage = class {
41979
42146
  }
41980
42147
  console.error("Failed to read/decrypt token file:", error);
41981
42148
  try {
41982
- await fs14.unlink(filePath);
42149
+ await fs15.unlink(filePath);
41983
42150
  } catch {
41984
42151
  }
41985
42152
  return null;
@@ -41988,7 +42155,7 @@ var FileStorage = class {
41988
42155
  async deleteToken(key) {
41989
42156
  const filePath = this.getFilePath(key);
41990
42157
  try {
41991
- await fs14.unlink(filePath);
42158
+ await fs15.unlink(filePath);
41992
42159
  } catch (error) {
41993
42160
  if (error.code !== "ENOENT") {
41994
42161
  throw error;
@@ -41998,7 +42165,7 @@ var FileStorage = class {
41998
42165
  async hasToken(key) {
41999
42166
  const filePath = this.getFilePath(key);
42000
42167
  try {
42001
- await fs14.access(filePath);
42168
+ await fs15.access(filePath);
42002
42169
  return true;
42003
42170
  } catch {
42004
42171
  return false;
@@ -42009,7 +42176,7 @@ var FileStorage = class {
42009
42176
  */
42010
42177
  async listTokens() {
42011
42178
  try {
42012
- const files = await fs14.readdir(this.directory);
42179
+ const files = await fs15.readdir(this.directory);
42013
42180
  return files.filter((f) => f.endsWith(".token")).map((f) => f.replace(".token", ""));
42014
42181
  } catch {
42015
42182
  return [];
@@ -42020,10 +42187,10 @@ var FileStorage = class {
42020
42187
  */
42021
42188
  async clearAll() {
42022
42189
  try {
42023
- const files = await fs14.readdir(this.directory);
42190
+ const files = await fs15.readdir(this.directory);
42024
42191
  const tokenFiles = files.filter((f) => f.endsWith(".token"));
42025
42192
  await Promise.all(
42026
- tokenFiles.map((f) => fs14.unlink(path3.join(this.directory, f)).catch(() => {
42193
+ tokenFiles.map((f) => fs15.unlink(path2.join(this.directory, f)).catch(() => {
42027
42194
  }))
42028
42195
  );
42029
42196
  } catch {
@@ -42291,22 +42458,26 @@ var ConnectorConfigStore = class {
42291
42458
  * Encrypt secrets in ConnectorAuth based on auth type
42292
42459
  */
42293
42460
  encryptAuthSecrets(auth2) {
42461
+ const encryptedExtra = this.encryptExtra(auth2.extra);
42294
42462
  switch (auth2.type) {
42295
42463
  case "api_key":
42296
42464
  return {
42297
42465
  ...auth2,
42298
- apiKey: this.encryptValue(auth2.apiKey)
42466
+ apiKey: this.encryptValue(auth2.apiKey),
42467
+ ...encryptedExtra ? { extra: encryptedExtra } : {}
42299
42468
  };
42300
42469
  case "oauth":
42301
42470
  return {
42302
42471
  ...auth2,
42303
42472
  clientSecret: auth2.clientSecret ? this.encryptValue(auth2.clientSecret) : void 0,
42304
- privateKey: auth2.privateKey ? this.encryptValue(auth2.privateKey) : void 0
42473
+ privateKey: auth2.privateKey ? this.encryptValue(auth2.privateKey) : void 0,
42474
+ ...encryptedExtra ? { extra: encryptedExtra } : {}
42305
42475
  };
42306
42476
  case "jwt":
42307
42477
  return {
42308
42478
  ...auth2,
42309
- privateKey: this.encryptValue(auth2.privateKey)
42479
+ privateKey: this.encryptValue(auth2.privateKey),
42480
+ ...encryptedExtra ? { extra: encryptedExtra } : {}
42310
42481
  };
42311
42482
  default:
42312
42483
  return auth2;
@@ -42316,27 +42487,53 @@ var ConnectorConfigStore = class {
42316
42487
  * Decrypt secrets in ConnectorAuth based on auth type
42317
42488
  */
42318
42489
  decryptAuthSecrets(auth2) {
42490
+ const decryptedExtra = this.decryptExtra(auth2.extra);
42319
42491
  switch (auth2.type) {
42320
42492
  case "api_key":
42321
42493
  return {
42322
42494
  ...auth2,
42323
- apiKey: this.decryptValue(auth2.apiKey)
42495
+ apiKey: this.decryptValue(auth2.apiKey),
42496
+ ...decryptedExtra ? { extra: decryptedExtra } : {}
42324
42497
  };
42325
42498
  case "oauth":
42326
42499
  return {
42327
42500
  ...auth2,
42328
42501
  clientSecret: auth2.clientSecret ? this.decryptValue(auth2.clientSecret) : void 0,
42329
- privateKey: auth2.privateKey ? this.decryptValue(auth2.privateKey) : void 0
42502
+ privateKey: auth2.privateKey ? this.decryptValue(auth2.privateKey) : void 0,
42503
+ ...decryptedExtra ? { extra: decryptedExtra } : {}
42330
42504
  };
42331
42505
  case "jwt":
42332
42506
  return {
42333
42507
  ...auth2,
42334
- privateKey: this.decryptValue(auth2.privateKey)
42508
+ privateKey: this.decryptValue(auth2.privateKey),
42509
+ ...decryptedExtra ? { extra: decryptedExtra } : {}
42335
42510
  };
42336
42511
  default:
42337
42512
  return auth2;
42338
42513
  }
42339
42514
  }
42515
+ /**
42516
+ * Encrypt all values in an extra Record (vendor-specific credentials)
42517
+ */
42518
+ encryptExtra(extra) {
42519
+ if (!extra || Object.keys(extra).length === 0) return void 0;
42520
+ const result = {};
42521
+ for (const [key, value] of Object.entries(extra)) {
42522
+ result[key] = this.encryptValue(value);
42523
+ }
42524
+ return result;
42525
+ }
42526
+ /**
42527
+ * Decrypt all values in an extra Record (vendor-specific credentials)
42528
+ */
42529
+ decryptExtra(extra) {
42530
+ if (!extra || Object.keys(extra).length === 0) return void 0;
42531
+ const result = {};
42532
+ for (const [key, value] of Object.entries(extra)) {
42533
+ result[key] = this.decryptValue(value);
42534
+ }
42535
+ return result;
42536
+ }
42340
42537
  /**
42341
42538
  * Encrypt a single value if not already encrypted
42342
42539
  */
@@ -42414,20 +42611,20 @@ var FileConnectorStorage = class {
42414
42611
  throw new Error("FileConnectorStorage requires a directory path");
42415
42612
  }
42416
42613
  this.directory = config.directory;
42417
- this.indexPath = path3.join(this.directory, "_index.json");
42614
+ this.indexPath = path2.join(this.directory, "_index.json");
42418
42615
  }
42419
42616
  async save(name, stored) {
42420
42617
  await this.ensureDirectory();
42421
42618
  const filePath = this.getFilePath(name);
42422
42619
  const json = JSON.stringify(stored, null, 2);
42423
- await fs14.writeFile(filePath, json, "utf8");
42424
- await fs14.chmod(filePath, 384);
42620
+ await fs15.writeFile(filePath, json, "utf8");
42621
+ await fs15.chmod(filePath, 384);
42425
42622
  await this.updateIndex(name, "add");
42426
42623
  }
42427
42624
  async get(name) {
42428
42625
  const filePath = this.getFilePath(name);
42429
42626
  try {
42430
- const json = await fs14.readFile(filePath, "utf8");
42627
+ const json = await fs15.readFile(filePath, "utf8");
42431
42628
  return JSON.parse(json);
42432
42629
  } catch (error) {
42433
42630
  const err = error;
@@ -42440,7 +42637,7 @@ var FileConnectorStorage = class {
42440
42637
  async delete(name) {
42441
42638
  const filePath = this.getFilePath(name);
42442
42639
  try {
42443
- await fs14.unlink(filePath);
42640
+ await fs15.unlink(filePath);
42444
42641
  await this.updateIndex(name, "remove");
42445
42642
  return true;
42446
42643
  } catch (error) {
@@ -42454,7 +42651,7 @@ var FileConnectorStorage = class {
42454
42651
  async has(name) {
42455
42652
  const filePath = this.getFilePath(name);
42456
42653
  try {
42457
- await fs14.access(filePath);
42654
+ await fs15.access(filePath);
42458
42655
  return true;
42459
42656
  } catch {
42460
42657
  return false;
@@ -42480,13 +42677,13 @@ var FileConnectorStorage = class {
42480
42677
  */
42481
42678
  async clear() {
42482
42679
  try {
42483
- const files = await fs14.readdir(this.directory);
42680
+ const files = await fs15.readdir(this.directory);
42484
42681
  const connectorFiles = files.filter(
42485
42682
  (f) => f.endsWith(".connector.json") || f === "_index.json"
42486
42683
  );
42487
42684
  await Promise.all(
42488
42685
  connectorFiles.map(
42489
- (f) => fs14.unlink(path3.join(this.directory, f)).catch(() => {
42686
+ (f) => fs15.unlink(path2.join(this.directory, f)).catch(() => {
42490
42687
  })
42491
42688
  )
42492
42689
  );
@@ -42499,7 +42696,7 @@ var FileConnectorStorage = class {
42499
42696
  */
42500
42697
  getFilePath(name) {
42501
42698
  const hash = this.hashName(name);
42502
- return path3.join(this.directory, `${hash}.connector.json`);
42699
+ return path2.join(this.directory, `${hash}.connector.json`);
42503
42700
  }
42504
42701
  /**
42505
42702
  * Hash connector name to prevent enumeration
@@ -42513,8 +42710,8 @@ var FileConnectorStorage = class {
42513
42710
  async ensureDirectory() {
42514
42711
  if (this.initialized) return;
42515
42712
  try {
42516
- await fs14.mkdir(this.directory, { recursive: true });
42517
- await fs14.chmod(this.directory, 448);
42713
+ await fs15.mkdir(this.directory, { recursive: true });
42714
+ await fs15.chmod(this.directory, 448);
42518
42715
  this.initialized = true;
42519
42716
  } catch {
42520
42717
  this.initialized = true;
@@ -42525,7 +42722,7 @@ var FileConnectorStorage = class {
42525
42722
  */
42526
42723
  async loadIndex() {
42527
42724
  try {
42528
- const json = await fs14.readFile(this.indexPath, "utf8");
42725
+ const json = await fs15.readFile(this.indexPath, "utf8");
42529
42726
  return JSON.parse(json);
42530
42727
  } catch {
42531
42728
  return { connectors: {} };
@@ -42543,8 +42740,8 @@ var FileConnectorStorage = class {
42543
42740
  delete index.connectors[hash];
42544
42741
  }
42545
42742
  const json = JSON.stringify(index, null, 2);
42546
- await fs14.writeFile(this.indexPath, json, "utf8");
42547
- await fs14.chmod(this.indexPath, 384);
42743
+ await fs15.writeFile(this.indexPath, json, "utf8");
42744
+ await fs15.chmod(this.indexPath, 384);
42548
42745
  }
42549
42746
  };
42550
42747
 
@@ -42589,11 +42786,19 @@ function buildAuthConfig(authTemplate, credentials) {
42589
42786
  if (!credentials.apiKey) {
42590
42787
  throw new Error("API key is required for api_key auth");
42591
42788
  }
42789
+ const standardApiKeyFields = /* @__PURE__ */ new Set(["apiKey", "headerName", "headerPrefix"]);
42790
+ const extra = {};
42791
+ for (const field of authTemplate.optionalFields ?? []) {
42792
+ if (!standardApiKeyFields.has(field) && credentials[field]) {
42793
+ extra[field] = credentials[field];
42794
+ }
42795
+ }
42592
42796
  return {
42593
42797
  type: "api_key",
42594
42798
  apiKey: credentials.apiKey,
42595
42799
  headerName: defaults.headerName ?? "Authorization",
42596
- headerPrefix: defaults.headerPrefix ?? "Bearer"
42800
+ headerPrefix: defaults.headerPrefix ?? "Bearer",
42801
+ ...Object.keys(extra).length > 0 ? { extra } : {}
42597
42802
  };
42598
42803
  }
42599
42804
  if (!authTemplate.flow) {
@@ -42863,8 +43068,9 @@ var slackTemplate = {
42863
43068
  id: "bot-token",
42864
43069
  name: "Bot Token",
42865
43070
  type: "api_key",
42866
- description: "Internal workspace bot - get from OAuth & Permissions page of your Slack app",
43071
+ 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.",
42867
43072
  requiredFields: ["apiKey"],
43073
+ optionalFields: ["appToken", "signingSecret"],
42868
43074
  defaults: {
42869
43075
  type: "api_key",
42870
43076
  headerName: "Authorization",
@@ -44702,14 +44908,14 @@ function createMessageWithImages(text, imageUrls, role = "user" /* USER */) {
44702
44908
  var execAsync = promisify(exec);
44703
44909
  function cleanupTempFile(filePath) {
44704
44910
  try {
44705
- if (fs15.existsSync(filePath)) {
44706
- fs15.unlinkSync(filePath);
44911
+ if (fs16.existsSync(filePath)) {
44912
+ fs16.unlinkSync(filePath);
44707
44913
  }
44708
44914
  } catch {
44709
44915
  }
44710
44916
  }
44711
44917
  async function readClipboardImage() {
44712
- const platform2 = os.platform();
44918
+ const platform2 = os2.platform();
44713
44919
  try {
44714
44920
  switch (platform2) {
44715
44921
  case "darwin":
@@ -44732,7 +44938,7 @@ async function readClipboardImage() {
44732
44938
  }
44733
44939
  }
44734
44940
  async function readClipboardImageMac() {
44735
- const tempFile = path3.join(os.tmpdir(), `clipboard-${Date.now()}.png`);
44941
+ const tempFile = path2.join(os2.tmpdir(), `clipboard-${Date.now()}.png`);
44736
44942
  try {
44737
44943
  try {
44738
44944
  await execAsync(`pngpaste "${tempFile}"`);
@@ -44754,7 +44960,7 @@ async function readClipboardImageMac() {
44754
44960
  end try
44755
44961
  `;
44756
44962
  const { stdout } = await execAsync(`osascript -e '${script}'`);
44757
- if (stdout.includes("success") || fs15.existsSync(tempFile)) {
44963
+ if (stdout.includes("success") || fs16.existsSync(tempFile)) {
44758
44964
  return await convertFileToDataUri(tempFile);
44759
44965
  }
44760
44966
  return {
@@ -44767,18 +44973,18 @@ async function readClipboardImageMac() {
44767
44973
  }
44768
44974
  }
44769
44975
  async function readClipboardImageLinux() {
44770
- const tempFile = path3.join(os.tmpdir(), `clipboard-${Date.now()}.png`);
44976
+ const tempFile = path2.join(os2.tmpdir(), `clipboard-${Date.now()}.png`);
44771
44977
  try {
44772
44978
  try {
44773
44979
  await execAsync(`xclip -selection clipboard -t image/png -o > "${tempFile}"`);
44774
- if (fs15.existsSync(tempFile) && fs15.statSync(tempFile).size > 0) {
44980
+ if (fs16.existsSync(tempFile) && fs16.statSync(tempFile).size > 0) {
44775
44981
  return await convertFileToDataUri(tempFile);
44776
44982
  }
44777
44983
  } catch {
44778
44984
  }
44779
44985
  try {
44780
44986
  await execAsync(`wl-paste -t image/png > "${tempFile}"`);
44781
- if (fs15.existsSync(tempFile) && fs15.statSync(tempFile).size > 0) {
44987
+ if (fs16.existsSync(tempFile) && fs16.statSync(tempFile).size > 0) {
44782
44988
  return await convertFileToDataUri(tempFile);
44783
44989
  }
44784
44990
  } catch {
@@ -44792,7 +44998,7 @@ async function readClipboardImageLinux() {
44792
44998
  }
44793
44999
  }
44794
45000
  async function readClipboardImageWindows() {
44795
- const tempFile = path3.join(os.tmpdir(), `clipboard-${Date.now()}.png`);
45001
+ const tempFile = path2.join(os2.tmpdir(), `clipboard-${Date.now()}.png`);
44796
45002
  try {
44797
45003
  const psScript = `
44798
45004
  Add-Type -AssemblyName System.Windows.Forms;
@@ -44805,7 +45011,7 @@ async function readClipboardImageWindows() {
44805
45011
  }
44806
45012
  `;
44807
45013
  await execAsync(`powershell -Command "${psScript}"`);
44808
- if (fs15.existsSync(tempFile) && fs15.statSync(tempFile).size > 0) {
45014
+ if (fs16.existsSync(tempFile) && fs16.statSync(tempFile).size > 0) {
44809
45015
  return await convertFileToDataUri(tempFile);
44810
45016
  }
44811
45017
  return {
@@ -44818,7 +45024,7 @@ async function readClipboardImageWindows() {
44818
45024
  }
44819
45025
  async function convertFileToDataUri(filePath) {
44820
45026
  try {
44821
- const imageBuffer = fs15.readFileSync(filePath);
45027
+ const imageBuffer = fs16.readFileSync(filePath);
44822
45028
  const base64Image = imageBuffer.toString("base64");
44823
45029
  const magic = imageBuffer.slice(0, 4).toString("hex");
44824
45030
  let mimeType = "image/png";
@@ -44845,7 +45051,7 @@ async function convertFileToDataUri(filePath) {
44845
45051
  }
44846
45052
  }
44847
45053
  async function hasClipboardImage() {
44848
- const platform2 = os.platform();
45054
+ const platform2 = os2.platform();
44849
45055
  try {
44850
45056
  switch (platform2) {
44851
45057
  case "darwin":
@@ -45063,17 +45269,24 @@ __export(tools_exports, {
45063
45269
  ConnectorTools: () => ConnectorTools,
45064
45270
  DEFAULT_FILESYSTEM_CONFIG: () => DEFAULT_FILESYSTEM_CONFIG,
45065
45271
  DEFAULT_SHELL_CONFIG: () => DEFAULT_SHELL_CONFIG,
45066
- FileMediaOutputHandler: () => FileMediaOutputHandler,
45272
+ FileMediaOutputHandler: () => FileMediaStorage,
45067
45273
  ToolRegistry: () => ToolRegistry,
45068
45274
  bash: () => bash,
45069
45275
  createBashTool: () => createBashTool,
45276
+ createCreatePRTool: () => createCreatePRTool,
45070
45277
  createEditFileTool: () => createEditFileTool,
45071
45278
  createExecuteJavaScriptTool: () => createExecuteJavaScriptTool,
45279
+ createGetPRTool: () => createGetPRTool,
45280
+ createGitHubReadFileTool: () => createGitHubReadFileTool,
45072
45281
  createGlobTool: () => createGlobTool,
45073
45282
  createGrepTool: () => createGrepTool,
45074
45283
  createImageGenerationTool: () => createImageGenerationTool,
45075
45284
  createListDirectoryTool: () => createListDirectoryTool,
45285
+ createPRCommentsTool: () => createPRCommentsTool,
45286
+ createPRFilesTool: () => createPRFilesTool,
45076
45287
  createReadFileTool: () => createReadFileTool,
45288
+ createSearchCodeTool: () => createSearchCodeTool,
45289
+ createSearchFilesTool: () => createSearchFilesTool,
45077
45290
  createSpeechToTextTool: () => createSpeechToTextTool,
45078
45291
  createTextToSpeechTool: () => createTextToSpeechTool,
45079
45292
  createVideoTools: () => createVideoTools,
@@ -45085,6 +45298,7 @@ __export(tools_exports, {
45085
45298
  getAllBuiltInTools: () => getAllBuiltInTools,
45086
45299
  getBackgroundOutput: () => getBackgroundOutput,
45087
45300
  getMediaOutputHandler: () => getMediaOutputHandler,
45301
+ getMediaStorage: () => getMediaStorage,
45088
45302
  getToolByName: () => getToolByName,
45089
45303
  getToolCategories: () => getToolCategories,
45090
45304
  getToolRegistry: () => getToolRegistry,
@@ -45097,15 +45311,18 @@ __export(tools_exports, {
45097
45311
  jsonManipulator: () => jsonManipulator,
45098
45312
  killBackgroundProcess: () => killBackgroundProcess,
45099
45313
  listDirectory: () => listDirectory,
45100
- readFile: () => readFile4,
45314
+ parseRepository: () => parseRepository,
45315
+ readFile: () => readFile5,
45316
+ resolveRepository: () => resolveRepository,
45101
45317
  setMediaOutputHandler: () => setMediaOutputHandler,
45318
+ setMediaStorage: () => setMediaStorage,
45102
45319
  toolRegistry: () => toolRegistry,
45103
45320
  validatePath: () => validatePath,
45104
45321
  webFetch: () => webFetch,
45105
45322
  webFetchJS: () => webFetchJS,
45106
45323
  webScrape: () => webScrape,
45107
45324
  webSearch: () => webSearch,
45108
- writeFile: () => writeFile4
45325
+ writeFile: () => writeFile5
45109
45326
  });
45110
45327
  var DEFAULT_FILESYSTEM_CONFIG = {
45111
45328
  workingDirectory: process.cwd(),
@@ -45358,7 +45575,7 @@ EXAMPLES:
45358
45575
  }
45359
45576
  };
45360
45577
  }
45361
- var readFile4 = createReadFileTool();
45578
+ var readFile5 = createReadFileTool();
45362
45579
  function createWriteFileTool(config = {}) {
45363
45580
  const mergedConfig = { ...DEFAULT_FILESYSTEM_CONFIG, ...config };
45364
45581
  return {
@@ -45445,7 +45662,7 @@ EXAMPLES:
45445
45662
  }
45446
45663
  };
45447
45664
  }
45448
- var writeFile4 = createWriteFileTool();
45665
+ var writeFile5 = createWriteFileTool();
45449
45666
  function createEditFileTool(config = {}) {
45450
45667
  const mergedConfig = { ...DEFAULT_FILESYSTEM_CONFIG, ...config };
45451
45668
  return {
@@ -46372,7 +46589,8 @@ EXAMPLES:
46372
46589
  shell: mergedConfig.shell,
46373
46590
  cwd: mergedConfig.workingDirectory,
46374
46591
  env,
46375
- stdio: ["pipe", "pipe", "pipe"]
46592
+ stdio: ["pipe", "pipe", "pipe"],
46593
+ detached: true
46376
46594
  });
46377
46595
  if (run_in_background && mergedConfig.allowBackground) {
46378
46596
  const bgId = generateBackgroundId();
@@ -46399,14 +46617,27 @@ EXAMPLES:
46399
46617
  let stdout = "";
46400
46618
  let stderr = "";
46401
46619
  let killed = false;
46620
+ const killProcessGroup = (signal) => {
46621
+ try {
46622
+ if (childProcess.pid) {
46623
+ process.kill(-childProcess.pid, signal);
46624
+ }
46625
+ } catch {
46626
+ try {
46627
+ childProcess.kill(signal);
46628
+ } catch {
46629
+ }
46630
+ }
46631
+ };
46632
+ const GRACEFUL_KILL_WAIT_MS = 3e3;
46402
46633
  const timeoutId = setTimeout(() => {
46403
46634
  killed = true;
46404
- childProcess.kill("SIGTERM");
46635
+ killProcessGroup("SIGTERM");
46405
46636
  setTimeout(() => {
46406
46637
  if (!childProcess.killed) {
46407
- childProcess.kill("SIGKILL");
46638
+ killProcessGroup("SIGKILL");
46408
46639
  }
46409
- }, 5e3);
46640
+ }, GRACEFUL_KILL_WAIT_MS);
46410
46641
  }, effectiveTimeout);
46411
46642
  childProcess.stdout.on("data", (data) => {
46412
46643
  stdout += data.toString();
@@ -46420,8 +46651,28 @@ EXAMPLES:
46420
46651
  stderr = stderr.slice(-mergedConfig.maxOutputSize);
46421
46652
  }
46422
46653
  });
46423
- childProcess.on("close", (code, signal) => {
46654
+ let resolved = false;
46655
+ const safeResolve = (result) => {
46656
+ if (resolved) return;
46657
+ resolved = true;
46424
46658
  clearTimeout(timeoutId);
46659
+ clearTimeout(hardTimeoutId);
46660
+ resolve4(result);
46661
+ };
46662
+ const HARD_TIMEOUT_GRACE_MS = 5e3;
46663
+ const hardTimeoutId = setTimeout(() => {
46664
+ if (!resolved) {
46665
+ killProcessGroup("SIGKILL");
46666
+ safeResolve({
46667
+ success: false,
46668
+ stdout,
46669
+ stderr,
46670
+ duration: Date.now() - startTime,
46671
+ error: `Command timed out after ${effectiveTimeout}ms (hard timeout: process group did not exit)`
46672
+ });
46673
+ }
46674
+ }, effectiveTimeout + GRACEFUL_KILL_WAIT_MS + HARD_TIMEOUT_GRACE_MS);
46675
+ childProcess.on("close", (code, signal) => {
46425
46676
  const duration = Date.now() - startTime;
46426
46677
  let truncated = false;
46427
46678
  if (stdout.length > mergedConfig.maxOutputSize) {
@@ -46433,7 +46684,7 @@ EXAMPLES:
46433
46684
  truncated = true;
46434
46685
  }
46435
46686
  if (killed) {
46436
- resolve4({
46687
+ safeResolve({
46437
46688
  success: false,
46438
46689
  stdout,
46439
46690
  stderr,
@@ -46444,7 +46695,7 @@ EXAMPLES:
46444
46695
  error: `Command timed out after ${effectiveTimeout}ms`
46445
46696
  });
46446
46697
  } else {
46447
- resolve4({
46698
+ safeResolve({
46448
46699
  success: code === 0,
46449
46700
  stdout,
46450
46701
  stderr,
@@ -46457,8 +46708,7 @@ EXAMPLES:
46457
46708
  }
46458
46709
  });
46459
46710
  childProcess.on("error", (error) => {
46460
- clearTimeout(timeoutId);
46461
- resolve4({
46711
+ safeResolve({
46462
46712
  success: false,
46463
46713
  error: `Failed to execute command: ${error.message}`,
46464
46714
  duration: Date.now() - startTime
@@ -47724,8 +47974,8 @@ async function tryNative(args, startTime, attemptedMethods) {
47724
47974
  method: "native",
47725
47975
  title: result.title,
47726
47976
  content: cleanContent,
47727
- // Note: raw HTML not available with native method (returns markdown instead)
47728
- markdown: args.includeMarkdown ? cleanContent : void 0,
47977
+ // Native method already returns markdown-like content no separate markdown field needed
47978
+ // (would just duplicate content and waste tokens)
47729
47979
  qualityScore: result.qualityScore,
47730
47980
  durationMs: Date.now() - startTime,
47731
47981
  attemptedMethods,
@@ -47761,8 +48011,7 @@ async function tryJS(args, startTime, attemptedMethods) {
47761
48011
  method: "js",
47762
48012
  title: result.title,
47763
48013
  content: cleanContent,
47764
- // Note: raw HTML not available with JS method (returns markdown instead)
47765
- markdown: args.includeMarkdown ? cleanContent : void 0,
48014
+ // JS method already returns markdown-like content no separate markdown field needed
47766
48015
  qualityScore: result.success ? 80 : 0,
47767
48016
  durationMs: Date.now() - startTime,
47768
48017
  attemptedMethods,
@@ -47794,8 +48043,11 @@ async function tryAPI(connectorName, args, startTime, attemptedMethods) {
47794
48043
  includeLinks: args.includeLinks
47795
48044
  };
47796
48045
  const result = await provider.scrape(args.url, options);
47797
- const cleanContent = stripBase64DataUris(result.result?.content || "");
47798
- const cleanMarkdown = result.result?.markdown ? stripBase64DataUris(result.result.markdown) : void 0;
48046
+ const rawContent = result.result?.content || "";
48047
+ const rawMarkdown = result.result?.markdown;
48048
+ const cleanContent = stripBase64DataUris(rawContent);
48049
+ const cleanMarkdown = rawMarkdown ? stripBase64DataUris(rawMarkdown) : void 0;
48050
+ const isDuplicate = !!cleanMarkdown && cleanContent === cleanMarkdown;
47799
48051
  return {
47800
48052
  success: result.success,
47801
48053
  url: args.url,
@@ -47805,7 +48057,7 @@ async function tryAPI(connectorName, args, startTime, attemptedMethods) {
47805
48057
  content: cleanContent,
47806
48058
  html: result.result?.html,
47807
48059
  // Keep raw HTML as-is (only used if explicitly requested)
47808
- markdown: cleanMarkdown,
48060
+ markdown: isDuplicate ? void 0 : cleanMarkdown,
47809
48061
  metadata: result.result?.metadata,
47810
48062
  links: result.result?.links,
47811
48063
  qualityScore: result.success ? 90 : 0,
@@ -48020,68 +48272,25 @@ async function executeInVM(code, input, timeout, logs) {
48020
48272
  const result = await resultPromise;
48021
48273
  return result !== void 0 ? result : sandbox.output;
48022
48274
  }
48023
- var MIME_TYPES = {
48024
- png: "image/png",
48025
- jpeg: "image/jpeg",
48026
- jpg: "image/jpeg",
48027
- webp: "image/webp",
48028
- gif: "image/gif",
48029
- mp4: "video/mp4",
48030
- webm: "video/webm",
48031
- mp3: "audio/mpeg",
48032
- wav: "audio/wav",
48033
- opus: "audio/opus",
48034
- ogg: "audio/ogg",
48035
- aac: "audio/aac",
48036
- flac: "audio/flac",
48037
- pcm: "audio/pcm"
48038
- };
48039
- var FileMediaOutputHandler = class {
48040
- outputDir;
48041
- initialized = false;
48042
- constructor(outputDir) {
48043
- this.outputDir = outputDir ?? path3.join(os.tmpdir(), "oneringai-media");
48044
- }
48045
- async save(data, metadata) {
48046
- if (!this.initialized) {
48047
- await fs14.mkdir(this.outputDir, { recursive: true });
48048
- this.initialized = true;
48049
- }
48050
- const filename = metadata.suggestedFilename ?? this.generateFilename(metadata);
48051
- const filePath = path3.join(this.outputDir, filename);
48052
- await fs14.writeFile(filePath, data);
48053
- const format = metadata.format.toLowerCase();
48054
- const mimeType = MIME_TYPES[format] ?? `application/octet-stream`;
48055
- return {
48056
- location: filePath,
48057
- mimeType,
48058
- size: data.length
48059
- };
48060
- }
48061
- generateFilename(metadata) {
48062
- const timestamp = Date.now();
48063
- const random2 = crypto2.randomBytes(4).toString("hex");
48064
- const indexSuffix = metadata.index != null ? `_${metadata.index}` : "";
48065
- return `${metadata.type}_${timestamp}_${random2}${indexSuffix}.${metadata.format}`;
48066
- }
48067
- };
48068
48275
 
48069
48276
  // src/tools/multimedia/config.ts
48070
- var _outputHandler = null;
48071
- function getMediaOutputHandler() {
48072
- if (!_outputHandler) {
48073
- _outputHandler = new FileMediaOutputHandler();
48277
+ var _storage = null;
48278
+ function getMediaStorage() {
48279
+ if (!_storage) {
48280
+ _storage = new FileMediaStorage();
48074
48281
  }
48075
- return _outputHandler;
48282
+ return _storage;
48076
48283
  }
48077
- function setMediaOutputHandler(handler) {
48078
- _outputHandler = handler;
48284
+ function setMediaStorage(storage) {
48285
+ _storage = storage;
48079
48286
  }
48287
+ var getMediaOutputHandler = getMediaStorage;
48288
+ var setMediaOutputHandler = setMediaStorage;
48080
48289
 
48081
48290
  // src/tools/multimedia/imageGeneration.ts
48082
- function createImageGenerationTool(connector, outputHandler) {
48291
+ function createImageGenerationTool(connector, storage, userId) {
48083
48292
  const vendor = connector.vendor;
48084
- const handler = outputHandler ?? getMediaOutputHandler();
48293
+ const handler = storage ?? getMediaStorage();
48085
48294
  const vendorModels = vendor ? getImageModelsByVendor(vendor) : [];
48086
48295
  const modelNames = vendorModels.map((m) => m.name);
48087
48296
  const properties = {
@@ -48154,8 +48363,9 @@ function createImageGenerationTool(connector, outputHandler) {
48154
48363
  }
48155
48364
  }
48156
48365
  },
48157
- execute: async (args) => {
48366
+ execute: async (args, context) => {
48158
48367
  try {
48368
+ const effectiveUserId = userId ?? context?.userId;
48159
48369
  const imageGen = ImageGeneration.create({ connector });
48160
48370
  const response = await imageGen.generate({
48161
48371
  prompt: args.prompt,
@@ -48186,7 +48396,8 @@ function createImageGenerationTool(connector, outputHandler) {
48186
48396
  format,
48187
48397
  model: modelName,
48188
48398
  vendor: vendor || "unknown",
48189
- index: response.data.length > 1 ? i : void 0
48399
+ index: response.data.length > 1 ? i : void 0,
48400
+ userId: effectiveUserId
48190
48401
  });
48191
48402
  images.push({
48192
48403
  location: result.location,
@@ -48213,9 +48424,9 @@ function createImageGenerationTool(connector, outputHandler) {
48213
48424
 
48214
48425
  // src/tools/multimedia/videoGeneration.ts
48215
48426
  var videoGenInstances = /* @__PURE__ */ new Map();
48216
- function createVideoTools(connector, outputHandler) {
48427
+ function createVideoTools(connector, storage, userId) {
48217
48428
  const vendor = connector.vendor;
48218
- const handler = outputHandler ?? getMediaOutputHandler();
48429
+ const handler = storage ?? getMediaStorage();
48219
48430
  const vendorModels = vendor ? getVideoModelsByVendor(vendor) : [];
48220
48431
  const modelNames = vendorModels.map((m) => m.name);
48221
48432
  const generateProperties = {
@@ -48279,7 +48490,7 @@ function createVideoTools(connector, outputHandler) {
48279
48490
  }
48280
48491
  }
48281
48492
  },
48282
- execute: async (args) => {
48493
+ execute: async (args, _context) => {
48283
48494
  try {
48284
48495
  const videoGen = VideoGeneration.create({ connector });
48285
48496
  const response = await videoGen.generate({
@@ -48328,8 +48539,9 @@ function createVideoTools(connector, outputHandler) {
48328
48539
  }
48329
48540
  }
48330
48541
  },
48331
- execute: async (args) => {
48542
+ execute: async (args, context) => {
48332
48543
  try {
48544
+ const effectiveUserId = userId ?? context?.userId;
48333
48545
  let videoGen = videoGenInstances.get(args.jobId);
48334
48546
  if (!videoGen) {
48335
48547
  videoGen = VideoGeneration.create({ connector });
@@ -48355,7 +48567,8 @@ function createVideoTools(connector, outputHandler) {
48355
48567
  type: "video",
48356
48568
  format,
48357
48569
  model: modelName,
48358
- vendor: vendor || "unknown"
48570
+ vendor: vendor || "unknown",
48571
+ userId: effectiveUserId
48359
48572
  });
48360
48573
  videoGenInstances.delete(args.jobId);
48361
48574
  return {
@@ -48403,9 +48616,9 @@ function createVideoTools(connector, outputHandler) {
48403
48616
  }
48404
48617
 
48405
48618
  // src/tools/multimedia/textToSpeech.ts
48406
- function createTextToSpeechTool(connector, outputHandler) {
48619
+ function createTextToSpeechTool(connector, storage, userId) {
48407
48620
  const vendor = connector.vendor;
48408
- const handler = outputHandler ?? getMediaOutputHandler();
48621
+ const handler = storage ?? getMediaStorage();
48409
48622
  const vendorModels = vendor ? getTTSModelsByVendor(vendor) : [];
48410
48623
  const modelNames = vendorModels.map((m) => m.name);
48411
48624
  const properties = {
@@ -48466,8 +48679,9 @@ function createTextToSpeechTool(connector, outputHandler) {
48466
48679
  }
48467
48680
  }
48468
48681
  },
48469
- execute: async (args) => {
48682
+ execute: async (args, context) => {
48470
48683
  try {
48684
+ const effectiveUserId = userId ?? context?.userId;
48471
48685
  const tts = TextToSpeech.create({
48472
48686
  connector,
48473
48687
  model: args.model,
@@ -48481,7 +48695,8 @@ function createTextToSpeechTool(connector, outputHandler) {
48481
48695
  type: "audio",
48482
48696
  format,
48483
48697
  model: args.model || modelNames[0] || "unknown",
48484
- vendor: vendor || "unknown"
48698
+ vendor: vendor || "unknown",
48699
+ userId: effectiveUserId
48485
48700
  });
48486
48701
  return {
48487
48702
  success: true,
@@ -48504,14 +48719,17 @@ function createTextToSpeechTool(connector, outputHandler) {
48504
48719
  }
48505
48720
  };
48506
48721
  }
48507
- function createSpeechToTextTool(connector) {
48722
+
48723
+ // src/tools/multimedia/speechToText.ts
48724
+ function createSpeechToTextTool(connector, storage, _userId) {
48508
48725
  const vendor = connector.vendor;
48726
+ const handler = storage ?? getMediaStorage();
48509
48727
  const vendorModels = vendor ? getSTTModelsByVendor(vendor) : [];
48510
48728
  const modelNames = vendorModels.map((m) => m.name);
48511
48729
  const properties = {
48512
- audioFilePath: {
48730
+ audioSource: {
48513
48731
  type: "string",
48514
- description: "Path to the audio file to transcribe"
48732
+ description: "Path or location of the audio file to transcribe (file path, storage location, etc.)"
48515
48733
  }
48516
48734
  };
48517
48735
  if (modelNames.length > 0) {
@@ -48539,13 +48757,19 @@ function createSpeechToTextTool(connector) {
48539
48757
  parameters: {
48540
48758
  type: "object",
48541
48759
  properties,
48542
- required: ["audioFilePath"]
48760
+ required: ["audioSource"]
48543
48761
  }
48544
48762
  }
48545
48763
  },
48546
- execute: async (args) => {
48764
+ execute: async (args, _context) => {
48547
48765
  try {
48548
- const audioBuffer = await fs14.readFile(args.audioFilePath);
48766
+ const audioBuffer = await handler.read(args.audioSource);
48767
+ if (!audioBuffer) {
48768
+ return {
48769
+ success: false,
48770
+ error: `Audio not found at: ${args.audioSource}`
48771
+ };
48772
+ }
48549
48773
  const stt = SpeechToText.create({
48550
48774
  connector,
48551
48775
  model: args.model,
@@ -48567,7 +48791,7 @@ function createSpeechToTextTool(connector) {
48567
48791
  };
48568
48792
  }
48569
48793
  },
48570
- describeCall: (args) => args.audioFilePath,
48794
+ describeCall: (args) => args.audioSource,
48571
48795
  permission: {
48572
48796
  scope: "session",
48573
48797
  riskLevel: "low",
@@ -48582,21 +48806,22 @@ var VENDOR_CAPABILITIES = {
48582
48806
  [Vendor.Google]: ["image", "video", "tts"],
48583
48807
  [Vendor.Grok]: ["image", "video"]
48584
48808
  };
48585
- function registerMultimediaTools() {
48809
+ function registerMultimediaTools(storage) {
48586
48810
  for (const [vendor, capabilities] of Object.entries(VENDOR_CAPABILITIES)) {
48587
- ConnectorTools.registerService(vendor, (connector, _userId) => {
48811
+ ConnectorTools.registerService(vendor, (connector, userId) => {
48812
+ const handler = getMediaStorage();
48588
48813
  const tools = [];
48589
48814
  if (capabilities.includes("image")) {
48590
- tools.push(createImageGenerationTool(connector));
48815
+ tools.push(createImageGenerationTool(connector, handler, userId));
48591
48816
  }
48592
48817
  if (capabilities.includes("video")) {
48593
- tools.push(...createVideoTools(connector));
48818
+ tools.push(...createVideoTools(connector, handler, userId));
48594
48819
  }
48595
48820
  if (capabilities.includes("tts")) {
48596
- tools.push(createTextToSpeechTool(connector));
48821
+ tools.push(createTextToSpeechTool(connector, handler, userId));
48597
48822
  }
48598
48823
  if (capabilities.includes("stt")) {
48599
- tools.push(createSpeechToTextTool(connector));
48824
+ tools.push(createSpeechToTextTool(connector, handler));
48600
48825
  }
48601
48826
  return tools;
48602
48827
  });
@@ -48606,6 +48831,851 @@ function registerMultimediaTools() {
48606
48831
  // src/tools/multimedia/index.ts
48607
48832
  registerMultimediaTools();
48608
48833
 
48834
+ // src/tools/github/types.ts
48835
+ function parseRepository(input) {
48836
+ if (!input || input.trim().length === 0) {
48837
+ throw new Error("Repository cannot be empty");
48838
+ }
48839
+ const trimmed = input.trim();
48840
+ try {
48841
+ const url2 = new URL(trimmed);
48842
+ if (url2.hostname === "github.com" || url2.hostname === "www.github.com") {
48843
+ const segments = url2.pathname.split("/").filter(Boolean);
48844
+ if (segments.length >= 2) {
48845
+ return { owner: segments[0], repo: segments[1].replace(/\.git$/, "") };
48846
+ }
48847
+ }
48848
+ } catch {
48849
+ }
48850
+ const parts = trimmed.split("/");
48851
+ if (parts.length === 2 && parts[0].length > 0 && parts[1].length > 0) {
48852
+ return { owner: parts[0], repo: parts[1] };
48853
+ }
48854
+ throw new Error(
48855
+ `Invalid repository format: "${input}". Expected "owner/repo" or "https://github.com/owner/repo"`
48856
+ );
48857
+ }
48858
+ function resolveRepository(repository, connector) {
48859
+ const repoStr = repository ?? connector.getOptions().defaultRepository;
48860
+ if (!repoStr) {
48861
+ return {
48862
+ success: false,
48863
+ error: 'No repository specified. Provide a "repository" parameter (e.g., "owner/repo") or configure defaultRepository on the connector.'
48864
+ };
48865
+ }
48866
+ try {
48867
+ return { success: true, repo: parseRepository(repoStr) };
48868
+ } catch (err) {
48869
+ return { success: false, error: err instanceof Error ? err.message : String(err) };
48870
+ }
48871
+ }
48872
+ var GitHubAPIError = class extends Error {
48873
+ constructor(status, statusText, body) {
48874
+ const msg = typeof body === "object" && body !== null && "message" in body ? body.message : statusText;
48875
+ super(`GitHub API error ${status}: ${msg}`);
48876
+ this.status = status;
48877
+ this.statusText = statusText;
48878
+ this.body = body;
48879
+ this.name = "GitHubAPIError";
48880
+ }
48881
+ };
48882
+ async function githubFetch(connector, endpoint, options) {
48883
+ let url2 = endpoint;
48884
+ if (options?.queryParams && Object.keys(options.queryParams).length > 0) {
48885
+ const params = new URLSearchParams();
48886
+ for (const [key, value] of Object.entries(options.queryParams)) {
48887
+ params.append(key, String(value));
48888
+ }
48889
+ url2 += (url2.includes("?") ? "&" : "?") + params.toString();
48890
+ }
48891
+ const headers = {
48892
+ "Accept": options?.accept ?? "application/vnd.github+json",
48893
+ "X-GitHub-Api-Version": "2022-11-28"
48894
+ };
48895
+ if (options?.body) {
48896
+ headers["Content-Type"] = "application/json";
48897
+ }
48898
+ const response = await connector.fetch(
48899
+ url2,
48900
+ {
48901
+ method: options?.method ?? "GET",
48902
+ headers,
48903
+ body: options?.body ? JSON.stringify(options.body) : void 0
48904
+ },
48905
+ options?.userId
48906
+ );
48907
+ const text = await response.text();
48908
+ let data;
48909
+ try {
48910
+ data = JSON.parse(text);
48911
+ } catch {
48912
+ data = text;
48913
+ }
48914
+ if (!response.ok) {
48915
+ throw new GitHubAPIError(response.status, response.statusText, data);
48916
+ }
48917
+ return data;
48918
+ }
48919
+
48920
+ // src/tools/github/searchFiles.ts
48921
+ function matchGlobPattern2(pattern, filePath) {
48922
+ let regexPattern = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/\?/g, ".").replace(/\{\{GLOBSTAR\}\}/g, ".*");
48923
+ regexPattern = "^" + regexPattern + "$";
48924
+ try {
48925
+ const regex = new RegExp(regexPattern);
48926
+ return regex.test(filePath);
48927
+ } catch {
48928
+ return false;
48929
+ }
48930
+ }
48931
+ function createSearchFilesTool(connector, userId) {
48932
+ return {
48933
+ definition: {
48934
+ type: "function",
48935
+ function: {
48936
+ name: "search_files",
48937
+ description: `Search for files by name/path pattern in a GitHub repository.
48938
+
48939
+ USAGE:
48940
+ - Supports glob patterns like "**/*.ts", "src/**/*.tsx"
48941
+ - Returns matching file paths sorted alphabetically
48942
+ - Uses the repository's file tree for fast matching
48943
+
48944
+ PATTERN SYNTAX:
48945
+ - * matches any characters except /
48946
+ - ** matches any characters including /
48947
+ - ? matches a single character
48948
+
48949
+ EXAMPLES:
48950
+ - Find all TypeScript files: { "pattern": "**/*.ts" }
48951
+ - Find files in src: { "pattern": "src/**/*.{ts,tsx}" }
48952
+ - Find package.json: { "pattern": "**/package.json" }
48953
+ - Search specific branch: { "pattern": "**/*.ts", "ref": "develop" }`,
48954
+ parameters: {
48955
+ type: "object",
48956
+ properties: {
48957
+ repository: {
48958
+ type: "string",
48959
+ description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
48960
+ },
48961
+ pattern: {
48962
+ type: "string",
48963
+ description: 'Glob pattern to match files (e.g., "**/*.ts", "src/**/*.tsx")'
48964
+ },
48965
+ ref: {
48966
+ type: "string",
48967
+ description: "Branch, tag, or commit SHA. Defaults to the repository's default branch."
48968
+ }
48969
+ },
48970
+ required: ["pattern"]
48971
+ }
48972
+ }
48973
+ },
48974
+ describeCall: (args) => {
48975
+ const parts = [args.pattern];
48976
+ if (args.repository) parts.push(`in ${args.repository}`);
48977
+ if (args.ref) parts.push(`@${args.ref}`);
48978
+ return parts.join(" ");
48979
+ },
48980
+ permission: {
48981
+ scope: "session",
48982
+ riskLevel: "low",
48983
+ approvalMessage: `Search files in a GitHub repository via ${connector.displayName}`
48984
+ },
48985
+ execute: async (args) => {
48986
+ const resolved = resolveRepository(args.repository, connector);
48987
+ if (!resolved.success) {
48988
+ return { success: false, error: resolved.error };
48989
+ }
48990
+ const { owner, repo } = resolved.repo;
48991
+ try {
48992
+ let ref = args.ref;
48993
+ if (!ref) {
48994
+ const repoInfo = await githubFetch(
48995
+ connector,
48996
+ `/repos/${owner}/${repo}`,
48997
+ { userId }
48998
+ );
48999
+ ref = repoInfo.default_branch;
49000
+ }
49001
+ const tree = await githubFetch(
49002
+ connector,
49003
+ `/repos/${owner}/${repo}/git/trees/${ref}?recursive=1`,
49004
+ { userId }
49005
+ );
49006
+ const matching = tree.tree.filter(
49007
+ (entry) => entry.type === "blob" && matchGlobPattern2(args.pattern, entry.path)
49008
+ ).map((entry) => ({
49009
+ path: entry.path,
49010
+ size: entry.size ?? 0,
49011
+ type: entry.type
49012
+ })).sort((a, b) => a.path.localeCompare(b.path));
49013
+ return {
49014
+ success: true,
49015
+ files: matching,
49016
+ count: matching.length,
49017
+ truncated: tree.truncated
49018
+ };
49019
+ } catch (error) {
49020
+ return {
49021
+ success: false,
49022
+ error: `Failed to search files: ${error instanceof Error ? error.message : String(error)}`
49023
+ };
49024
+ }
49025
+ }
49026
+ };
49027
+ }
49028
+
49029
+ // src/tools/github/searchCode.ts
49030
+ function createSearchCodeTool(connector, userId) {
49031
+ return {
49032
+ definition: {
49033
+ type: "function",
49034
+ function: {
49035
+ name: "search_code",
49036
+ description: `Search for code content across a GitHub repository.
49037
+
49038
+ USAGE:
49039
+ - Search by keyword, function name, class name, or any text
49040
+ - Filter by language, path, or file extension
49041
+ - Returns matching files with text fragments showing context
49042
+
49043
+ RATE LIMITS:
49044
+ - GitHub's code search API is limited to 30 requests per minute
49045
+ - Results may be incomplete for very large repositories
49046
+
49047
+ EXAMPLES:
49048
+ - Find function: { "query": "function handleAuth", "language": "typescript" }
49049
+ - Find imports: { "query": "import React", "extension": "tsx" }
49050
+ - Search in path: { "query": "TODO", "path": "src/utils" }
49051
+ - Limit results: { "query": "console.log", "limit": 10 }`,
49052
+ parameters: {
49053
+ type: "object",
49054
+ properties: {
49055
+ repository: {
49056
+ type: "string",
49057
+ description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
49058
+ },
49059
+ query: {
49060
+ type: "string",
49061
+ description: "Search query \u2014 keyword, function name, or any text to find in code"
49062
+ },
49063
+ language: {
49064
+ type: "string",
49065
+ description: 'Filter by programming language (e.g., "typescript", "python", "go")'
49066
+ },
49067
+ path: {
49068
+ type: "string",
49069
+ description: 'Filter by file path prefix (e.g., "src/", "lib/utils")'
49070
+ },
49071
+ extension: {
49072
+ type: "string",
49073
+ description: 'Filter by file extension without dot (e.g., "ts", "py", "go")'
49074
+ },
49075
+ limit: {
49076
+ type: "number",
49077
+ description: "Maximum number of results (default: 30, max: 100)"
49078
+ }
49079
+ },
49080
+ required: ["query"]
49081
+ }
49082
+ }
49083
+ },
49084
+ describeCall: (args) => {
49085
+ const parts = [`"${args.query}"`];
49086
+ if (args.language) parts.push(`lang:${args.language}`);
49087
+ if (args.repository) parts.push(`in ${args.repository}`);
49088
+ return parts.join(" ");
49089
+ },
49090
+ permission: {
49091
+ scope: "session",
49092
+ riskLevel: "low",
49093
+ approvalMessage: `Search code in a GitHub repository via ${connector.displayName}`
49094
+ },
49095
+ execute: async (args) => {
49096
+ const resolved = resolveRepository(args.repository, connector);
49097
+ if (!resolved.success) {
49098
+ return { success: false, error: resolved.error };
49099
+ }
49100
+ const { owner, repo } = resolved.repo;
49101
+ try {
49102
+ const qualifiers = [`repo:${owner}/${repo}`];
49103
+ if (args.language) qualifiers.push(`language:${args.language}`);
49104
+ if (args.path) qualifiers.push(`path:${args.path}`);
49105
+ if (args.extension) qualifiers.push(`extension:${args.extension}`);
49106
+ const q = `${args.query} ${qualifiers.join(" ")}`;
49107
+ const perPage = Math.min(args.limit ?? 30, 100);
49108
+ const result = await githubFetch(
49109
+ connector,
49110
+ `/search/code`,
49111
+ {
49112
+ userId,
49113
+ // Request text-match fragments
49114
+ accept: "application/vnd.github.text-match+json",
49115
+ queryParams: { q, per_page: perPage }
49116
+ }
49117
+ );
49118
+ const matches = result.items.map((item) => ({
49119
+ file: item.path,
49120
+ fragment: item.text_matches?.[0]?.fragment
49121
+ }));
49122
+ return {
49123
+ success: true,
49124
+ matches,
49125
+ count: result.total_count,
49126
+ truncated: result.incomplete_results || result.total_count > perPage
49127
+ };
49128
+ } catch (error) {
49129
+ return {
49130
+ success: false,
49131
+ error: `Failed to search code: ${error instanceof Error ? error.message : String(error)}`
49132
+ };
49133
+ }
49134
+ }
49135
+ };
49136
+ }
49137
+
49138
+ // src/tools/github/readFile.ts
49139
+ function createGitHubReadFileTool(connector, userId) {
49140
+ return {
49141
+ definition: {
49142
+ type: "function",
49143
+ function: {
49144
+ name: "read_file",
49145
+ description: `Read file content from a GitHub repository.
49146
+
49147
+ USAGE:
49148
+ - Reads a file and returns content with line numbers
49149
+ - Supports line range selection with offset/limit for large files
49150
+ - By default reads up to 2000 lines from the beginning
49151
+
49152
+ EXAMPLES:
49153
+ - Read entire file: { "path": "src/index.ts" }
49154
+ - Read specific branch: { "path": "README.md", "ref": "develop" }
49155
+ - Read lines 100-200: { "path": "src/app.ts", "offset": 100, "limit": 100 }
49156
+ - Specific repo: { "repository": "owner/repo", "path": "package.json" }
49157
+
49158
+ NOTE: Files larger than 1MB are fetched via the Git Blob API. Very large files (>5MB) may be truncated.`,
49159
+ parameters: {
49160
+ type: "object",
49161
+ properties: {
49162
+ repository: {
49163
+ type: "string",
49164
+ description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
49165
+ },
49166
+ path: {
49167
+ type: "string",
49168
+ description: 'File path within the repository (e.g., "src/index.ts")'
49169
+ },
49170
+ ref: {
49171
+ type: "string",
49172
+ description: "Branch, tag, or commit SHA. Defaults to the repository's default branch."
49173
+ },
49174
+ offset: {
49175
+ type: "number",
49176
+ description: "Line number to start reading from (1-indexed). Only provide if the file is too large."
49177
+ },
49178
+ limit: {
49179
+ type: "number",
49180
+ description: "Number of lines to read (default: 2000). Only provide if the file is too large."
49181
+ }
49182
+ },
49183
+ required: ["path"]
49184
+ }
49185
+ }
49186
+ },
49187
+ describeCall: (args) => {
49188
+ const parts = [args.path];
49189
+ if (args.repository) parts.push(`in ${args.repository}`);
49190
+ if (args.ref) parts.push(`@${args.ref}`);
49191
+ if (args.offset && args.limit) parts.push(`[lines ${args.offset}-${args.offset + args.limit}]`);
49192
+ return parts.join(" ");
49193
+ },
49194
+ permission: {
49195
+ scope: "session",
49196
+ riskLevel: "low",
49197
+ approvalMessage: `Read a file from a GitHub repository via ${connector.displayName}`
49198
+ },
49199
+ execute: async (args) => {
49200
+ const resolved = resolveRepository(args.repository, connector);
49201
+ if (!resolved.success) {
49202
+ return { success: false, error: resolved.error };
49203
+ }
49204
+ const { owner, repo } = resolved.repo;
49205
+ try {
49206
+ let fileContent;
49207
+ let fileSha;
49208
+ let fileSize;
49209
+ const refParam = args.ref ? `?ref=${encodeURIComponent(args.ref)}` : "";
49210
+ const contentResp = await githubFetch(
49211
+ connector,
49212
+ `/repos/${owner}/${repo}/contents/${args.path}${refParam}`,
49213
+ { userId }
49214
+ );
49215
+ if (contentResp.type !== "file") {
49216
+ return {
49217
+ success: false,
49218
+ error: `Path is not a file: ${args.path} (type: ${contentResp.type}). Use search_files to explore the repository.`,
49219
+ path: args.path
49220
+ };
49221
+ }
49222
+ fileSha = contentResp.sha;
49223
+ fileSize = contentResp.size;
49224
+ if (contentResp.content && contentResp.encoding === "base64") {
49225
+ fileContent = Buffer.from(contentResp.content, "base64").toString("utf-8");
49226
+ } else if (contentResp.git_url) {
49227
+ const blob = await githubFetch(
49228
+ connector,
49229
+ contentResp.git_url,
49230
+ { userId }
49231
+ );
49232
+ fileContent = Buffer.from(blob.content, "base64").toString("utf-8");
49233
+ fileSize = blob.size;
49234
+ } else {
49235
+ return {
49236
+ success: false,
49237
+ error: `Cannot read file content: ${args.path} (no content or git_url in response)`,
49238
+ path: args.path
49239
+ };
49240
+ }
49241
+ const offset = args.offset ?? 1;
49242
+ const limit = args.limit ?? 2e3;
49243
+ const allLines = fileContent.split("\n");
49244
+ const totalLines = allLines.length;
49245
+ const startIndex = Math.max(0, offset - 1);
49246
+ const endIndex = Math.min(totalLines, startIndex + limit);
49247
+ const selectedLines = allLines.slice(startIndex, endIndex);
49248
+ const lineNumberWidth = String(endIndex).length;
49249
+ const formattedLines = selectedLines.map((line, i) => {
49250
+ const lineNum = startIndex + i + 1;
49251
+ const paddedNum = String(lineNum).padStart(lineNumberWidth, " ");
49252
+ const truncatedLine = line.length > 2e3 ? line.substring(0, 2e3) + "..." : line;
49253
+ return `${paddedNum} ${truncatedLine}`;
49254
+ });
49255
+ const truncated = endIndex < totalLines;
49256
+ const result = formattedLines.join("\n");
49257
+ return {
49258
+ success: true,
49259
+ content: result,
49260
+ path: args.path,
49261
+ size: fileSize,
49262
+ lines: totalLines,
49263
+ truncated,
49264
+ sha: fileSha
49265
+ };
49266
+ } catch (error) {
49267
+ return {
49268
+ success: false,
49269
+ error: `Failed to read file: ${error instanceof Error ? error.message : String(error)}`,
49270
+ path: args.path
49271
+ };
49272
+ }
49273
+ }
49274
+ };
49275
+ }
49276
+
49277
+ // src/tools/github/getPR.ts
49278
+ function createGetPRTool(connector, userId) {
49279
+ return {
49280
+ definition: {
49281
+ type: "function",
49282
+ function: {
49283
+ name: "get_pr",
49284
+ description: `Get full details of a pull request from a GitHub repository.
49285
+
49286
+ Returns: title, description, state, author, labels, reviewers, merge status, branches, file stats, and more.
49287
+
49288
+ EXAMPLES:
49289
+ - Get PR: { "pull_number": 123 }
49290
+ - Specific repo: { "repository": "owner/repo", "pull_number": 456 }`,
49291
+ parameters: {
49292
+ type: "object",
49293
+ properties: {
49294
+ repository: {
49295
+ type: "string",
49296
+ description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
49297
+ },
49298
+ pull_number: {
49299
+ type: "number",
49300
+ description: "Pull request number"
49301
+ }
49302
+ },
49303
+ required: ["pull_number"]
49304
+ }
49305
+ }
49306
+ },
49307
+ describeCall: (args) => {
49308
+ const parts = [`#${args.pull_number}`];
49309
+ if (args.repository) parts.push(`in ${args.repository}`);
49310
+ return parts.join(" ");
49311
+ },
49312
+ permission: {
49313
+ scope: "session",
49314
+ riskLevel: "low",
49315
+ approvalMessage: `Get pull request details from GitHub via ${connector.displayName}`
49316
+ },
49317
+ execute: async (args) => {
49318
+ const resolved = resolveRepository(args.repository, connector);
49319
+ if (!resolved.success) {
49320
+ return { success: false, error: resolved.error };
49321
+ }
49322
+ const { owner, repo } = resolved.repo;
49323
+ try {
49324
+ const pr = await githubFetch(
49325
+ connector,
49326
+ `/repos/${owner}/${repo}/pulls/${args.pull_number}`,
49327
+ { userId }
49328
+ );
49329
+ return {
49330
+ success: true,
49331
+ data: {
49332
+ number: pr.number,
49333
+ title: pr.title,
49334
+ body: pr.body,
49335
+ state: pr.state,
49336
+ draft: pr.draft,
49337
+ author: pr.user.login,
49338
+ labels: pr.labels.map((l) => l.name),
49339
+ reviewers: pr.requested_reviewers.map((r) => r.login),
49340
+ mergeable: pr.mergeable,
49341
+ head: pr.head.ref,
49342
+ base: pr.base.ref,
49343
+ url: pr.html_url,
49344
+ created_at: pr.created_at,
49345
+ updated_at: pr.updated_at,
49346
+ additions: pr.additions,
49347
+ deletions: pr.deletions,
49348
+ changed_files: pr.changed_files
49349
+ }
49350
+ };
49351
+ } catch (error) {
49352
+ return {
49353
+ success: false,
49354
+ error: `Failed to get PR: ${error instanceof Error ? error.message : String(error)}`
49355
+ };
49356
+ }
49357
+ }
49358
+ };
49359
+ }
49360
+
49361
+ // src/tools/github/prFiles.ts
49362
+ function createPRFilesTool(connector, userId) {
49363
+ return {
49364
+ definition: {
49365
+ type: "function",
49366
+ function: {
49367
+ name: "pr_files",
49368
+ description: `Get the files changed in a pull request with diffs.
49369
+
49370
+ Returns: filename, status (added/modified/removed/renamed), additions, deletions, and patch (diff) content for each file.
49371
+
49372
+ EXAMPLES:
49373
+ - Get files: { "pull_number": 123 }
49374
+ - Specific repo: { "repository": "owner/repo", "pull_number": 456 }
49375
+
49376
+ NOTE: Very large diffs may be truncated by GitHub. Patch content may be absent for binary files.`,
49377
+ parameters: {
49378
+ type: "object",
49379
+ properties: {
49380
+ repository: {
49381
+ type: "string",
49382
+ description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
49383
+ },
49384
+ pull_number: {
49385
+ type: "number",
49386
+ description: "Pull request number"
49387
+ }
49388
+ },
49389
+ required: ["pull_number"]
49390
+ }
49391
+ }
49392
+ },
49393
+ describeCall: (args) => {
49394
+ const parts = [`files for #${args.pull_number}`];
49395
+ if (args.repository) parts.push(`in ${args.repository}`);
49396
+ return parts.join(" ");
49397
+ },
49398
+ permission: {
49399
+ scope: "session",
49400
+ riskLevel: "low",
49401
+ approvalMessage: `Get PR changed files from GitHub via ${connector.displayName}`
49402
+ },
49403
+ execute: async (args) => {
49404
+ const resolved = resolveRepository(args.repository, connector);
49405
+ if (!resolved.success) {
49406
+ return { success: false, error: resolved.error };
49407
+ }
49408
+ const { owner, repo } = resolved.repo;
49409
+ try {
49410
+ const files = await githubFetch(
49411
+ connector,
49412
+ `/repos/${owner}/${repo}/pulls/${args.pull_number}/files`,
49413
+ {
49414
+ userId,
49415
+ queryParams: { per_page: 100 }
49416
+ }
49417
+ );
49418
+ return {
49419
+ success: true,
49420
+ files: files.map((f) => ({
49421
+ filename: f.filename,
49422
+ status: f.status,
49423
+ additions: f.additions,
49424
+ deletions: f.deletions,
49425
+ changes: f.changes,
49426
+ patch: f.patch
49427
+ })),
49428
+ count: files.length
49429
+ };
49430
+ } catch (error) {
49431
+ return {
49432
+ success: false,
49433
+ error: `Failed to get PR files: ${error instanceof Error ? error.message : String(error)}`
49434
+ };
49435
+ }
49436
+ }
49437
+ };
49438
+ }
49439
+
49440
+ // src/tools/github/prComments.ts
49441
+ function createPRCommentsTool(connector, userId) {
49442
+ return {
49443
+ definition: {
49444
+ type: "function",
49445
+ function: {
49446
+ name: "pr_comments",
49447
+ description: `Get all comments and reviews on a pull request.
49448
+
49449
+ Returns a unified list of:
49450
+ - **review_comment**: Line-level comments on specific code (includes file path and line number)
49451
+ - **review**: Full reviews (approve/request changes/comment)
49452
+ - **comment**: General comments on the PR (issue-level)
49453
+
49454
+ All entries are sorted by creation date (oldest first).
49455
+
49456
+ EXAMPLES:
49457
+ - Get comments: { "pull_number": 123 }
49458
+ - Specific repo: { "repository": "owner/repo", "pull_number": 456 }`,
49459
+ parameters: {
49460
+ type: "object",
49461
+ properties: {
49462
+ repository: {
49463
+ type: "string",
49464
+ description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
49465
+ },
49466
+ pull_number: {
49467
+ type: "number",
49468
+ description: "Pull request number"
49469
+ }
49470
+ },
49471
+ required: ["pull_number"]
49472
+ }
49473
+ }
49474
+ },
49475
+ describeCall: (args) => {
49476
+ const parts = [`comments for #${args.pull_number}`];
49477
+ if (args.repository) parts.push(`in ${args.repository}`);
49478
+ return parts.join(" ");
49479
+ },
49480
+ permission: {
49481
+ scope: "session",
49482
+ riskLevel: "low",
49483
+ approvalMessage: `Get PR comments and reviews from GitHub via ${connector.displayName}`
49484
+ },
49485
+ execute: async (args) => {
49486
+ const resolved = resolveRepository(args.repository, connector);
49487
+ if (!resolved.success) {
49488
+ return { success: false, error: resolved.error };
49489
+ }
49490
+ const { owner, repo } = resolved.repo;
49491
+ try {
49492
+ const basePath = `/repos/${owner}/${repo}`;
49493
+ const queryOpts = { userId, queryParams: { per_page: 100 } };
49494
+ const [reviewComments, reviews, issueComments] = await Promise.all([
49495
+ githubFetch(
49496
+ connector,
49497
+ `${basePath}/pulls/${args.pull_number}/comments`,
49498
+ queryOpts
49499
+ ),
49500
+ githubFetch(
49501
+ connector,
49502
+ `${basePath}/pulls/${args.pull_number}/reviews`,
49503
+ queryOpts
49504
+ ),
49505
+ githubFetch(
49506
+ connector,
49507
+ `${basePath}/issues/${args.pull_number}/comments`,
49508
+ queryOpts
49509
+ )
49510
+ ]);
49511
+ const allComments = [];
49512
+ for (const rc of reviewComments) {
49513
+ allComments.push({
49514
+ id: rc.id,
49515
+ type: "review_comment",
49516
+ author: rc.user.login,
49517
+ body: rc.body,
49518
+ created_at: rc.created_at,
49519
+ path: rc.path,
49520
+ line: rc.line ?? rc.original_line ?? void 0
49521
+ });
49522
+ }
49523
+ for (const r of reviews) {
49524
+ if (!r.body && r.state === "APPROVED") continue;
49525
+ allComments.push({
49526
+ id: r.id,
49527
+ type: "review",
49528
+ author: r.user.login,
49529
+ body: r.body || `[${r.state}]`,
49530
+ created_at: r.submitted_at,
49531
+ state: r.state
49532
+ });
49533
+ }
49534
+ for (const ic of issueComments) {
49535
+ allComments.push({
49536
+ id: ic.id,
49537
+ type: "comment",
49538
+ author: ic.user.login,
49539
+ body: ic.body,
49540
+ created_at: ic.created_at
49541
+ });
49542
+ }
49543
+ allComments.sort(
49544
+ (a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
49545
+ );
49546
+ return {
49547
+ success: true,
49548
+ comments: allComments,
49549
+ count: allComments.length
49550
+ };
49551
+ } catch (error) {
49552
+ return {
49553
+ success: false,
49554
+ error: `Failed to get PR comments: ${error instanceof Error ? error.message : String(error)}`
49555
+ };
49556
+ }
49557
+ }
49558
+ };
49559
+ }
49560
+
49561
+ // src/tools/github/createPR.ts
49562
+ function createCreatePRTool(connector, userId) {
49563
+ return {
49564
+ definition: {
49565
+ type: "function",
49566
+ function: {
49567
+ name: "create_pr",
49568
+ description: `Create a pull request on a GitHub repository.
49569
+
49570
+ USAGE:
49571
+ - Specify source branch (head) and target branch (base)
49572
+ - Optionally create as draft
49573
+
49574
+ EXAMPLES:
49575
+ - Create PR: { "title": "Add feature", "head": "feature-branch", "base": "main" }
49576
+ - Draft PR: { "title": "WIP: Refactor", "head": "refactor", "base": "develop", "draft": true }
49577
+ - With body: { "title": "Fix bug #42", "body": "Fixes the login issue\\n\\n## Changes\\n- Fixed auth flow", "head": "fix/42", "base": "main" }`,
49578
+ parameters: {
49579
+ type: "object",
49580
+ properties: {
49581
+ repository: {
49582
+ type: "string",
49583
+ description: 'Repository in "owner/repo" format or full GitHub URL. Optional if connector has a default repository.'
49584
+ },
49585
+ title: {
49586
+ type: "string",
49587
+ description: "Pull request title"
49588
+ },
49589
+ body: {
49590
+ type: "string",
49591
+ description: "Pull request description/body (Markdown supported)"
49592
+ },
49593
+ head: {
49594
+ type: "string",
49595
+ description: "Source branch name (the branch with your changes)"
49596
+ },
49597
+ base: {
49598
+ type: "string",
49599
+ description: 'Target branch name (the branch you want to merge into, e.g., "main")'
49600
+ },
49601
+ draft: {
49602
+ type: "boolean",
49603
+ description: "Create as a draft pull request (default: false)"
49604
+ }
49605
+ },
49606
+ required: ["title", "head", "base"]
49607
+ }
49608
+ }
49609
+ },
49610
+ describeCall: (args) => {
49611
+ const parts = [args.title];
49612
+ if (args.repository) parts.push(`in ${args.repository}`);
49613
+ return parts.join(" ");
49614
+ },
49615
+ permission: {
49616
+ scope: "session",
49617
+ riskLevel: "medium",
49618
+ approvalMessage: `Create a pull request on GitHub via ${connector.displayName}`
49619
+ },
49620
+ execute: async (args) => {
49621
+ const resolved = resolveRepository(args.repository, connector);
49622
+ if (!resolved.success) {
49623
+ return { success: false, error: resolved.error };
49624
+ }
49625
+ const { owner, repo } = resolved.repo;
49626
+ try {
49627
+ const pr = await githubFetch(
49628
+ connector,
49629
+ `/repos/${owner}/${repo}/pulls`,
49630
+ {
49631
+ method: "POST",
49632
+ userId,
49633
+ body: {
49634
+ title: args.title,
49635
+ body: args.body,
49636
+ head: args.head,
49637
+ base: args.base,
49638
+ draft: args.draft ?? false
49639
+ }
49640
+ }
49641
+ );
49642
+ return {
49643
+ success: true,
49644
+ data: {
49645
+ number: pr.number,
49646
+ url: pr.html_url,
49647
+ state: pr.state,
49648
+ title: pr.title
49649
+ }
49650
+ };
49651
+ } catch (error) {
49652
+ return {
49653
+ success: false,
49654
+ error: `Failed to create PR: ${error instanceof Error ? error.message : String(error)}`
49655
+ };
49656
+ }
49657
+ }
49658
+ };
49659
+ }
49660
+
49661
+ // src/tools/github/register.ts
49662
+ function registerGitHubTools() {
49663
+ ConnectorTools.registerService("github", (connector, userId) => {
49664
+ return [
49665
+ createSearchFilesTool(connector, userId),
49666
+ createSearchCodeTool(connector, userId),
49667
+ createGitHubReadFileTool(connector, userId),
49668
+ createGetPRTool(connector, userId),
49669
+ createPRFilesTool(connector, userId),
49670
+ createPRCommentsTool(connector, userId),
49671
+ createCreatePRTool(connector, userId)
49672
+ ];
49673
+ });
49674
+ }
49675
+
49676
+ // src/tools/github/index.ts
49677
+ registerGitHubTools();
49678
+
48609
49679
  // src/tools/registry.generated.ts
48610
49680
  var toolRegistry = [
48611
49681
  {
@@ -48659,7 +49729,7 @@ var toolRegistry = [
48659
49729
  displayName: "Read File",
48660
49730
  category: "filesystem",
48661
49731
  description: "Read content from a file on the local filesystem.",
48662
- tool: readFile4,
49732
+ tool: readFile5,
48663
49733
  safeByDefault: true
48664
49734
  },
48665
49735
  {
@@ -48668,7 +49738,7 @@ var toolRegistry = [
48668
49738
  displayName: "Write File",
48669
49739
  category: "filesystem",
48670
49740
  description: "Write content to a file on the local filesystem.",
48671
- tool: writeFile4,
49741
+ tool: writeFile5,
48672
49742
  safeByDefault: false
48673
49743
  },
48674
49744
  {
@@ -48897,8 +49967,8 @@ var ToolRegistry = class {
48897
49967
 
48898
49968
  // src/tools/index.ts
48899
49969
  var developerTools = [
48900
- readFile4,
48901
- writeFile4,
49970
+ readFile5,
49971
+ writeFile5,
48902
49972
  editFile,
48903
49973
  glob,
48904
49974
  grep,
@@ -49085,6 +50155,6 @@ REMEMBER: Keep it conversational, ask one question at a time, and only output th
49085
50155
  }
49086
50156
  };
49087
50157
 
49088
- export { AGENT_DEFINITION_FORMAT_VERSION, AIError, APPROVAL_STATE_VERSION, Agent, AgentContextNextGen, ApproximateTokenEstimator, BaseMediaProvider, BasePluginNextGen, BaseProvider, BaseTextProvider, BraveProvider, CONNECTOR_CONFIG_VERSION, CONTEXT_SESSION_FORMAT_VERSION, CheckpointManager, CircuitBreaker, CircuitOpenError, Connector, ConnectorConfigStore, ConnectorTools, ConsoleMetrics, ContentType, ContextOverflowError, DEFAULT_ALLOWLIST, DEFAULT_BACKOFF_CONFIG, DEFAULT_BASE_DELAY_MS, DEFAULT_CHECKPOINT_STRATEGY, DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_CONFIG2 as DEFAULT_CONFIG, DEFAULT_CONNECTOR_TIMEOUT, DEFAULT_CONTEXT_CONFIG, DEFAULT_FEATURES, DEFAULT_FILESYSTEM_CONFIG, DEFAULT_HISTORY_MANAGER_CONFIG, DEFAULT_MAX_DELAY_MS, DEFAULT_MAX_RETRIES, DEFAULT_MEMORY_CONFIG, DEFAULT_PERMISSION_CONFIG, DEFAULT_RATE_LIMITER_CONFIG, DEFAULT_RETRYABLE_STATUSES, DEFAULT_SHELL_CONFIG, DefaultCompactionStrategy, DependencyCycleError, ErrorHandler, ExecutionContext, ExternalDependencyHandler, FileAgentDefinitionStorage, FileConnectorStorage, FileContextStorage, FileMediaOutputHandler, FilePersistentInstructionsStorage, FileStorage, FrameworkLogger, HookManager, IMAGE_MODELS, IMAGE_MODEL_REGISTRY, ImageGeneration, InContextMemoryPluginNextGen, InMemoryAgentStateStorage, InMemoryHistoryStorage, InMemoryMetrics, InMemoryPlanStorage, InMemoryStorage, InvalidConfigError, InvalidToolArgumentsError, LLM_MODELS, LoggingPlugin, MCPClient, MCPConnectionError, MCPError, MCPProtocolError, MCPRegistry, MCPResourceError, MCPTimeoutError, MCPToolError, MEMORY_PRIORITY_VALUES, MODEL_REGISTRY, MemoryConnectorStorage, MemoryEvictionCompactor, MemoryStorage, MessageBuilder, MessageRole, ModelNotSupportedError, NoOpMetrics, OAuthManager, ParallelTasksError, PersistentInstructionsPluginNextGen, PlanningAgent, ProviderAuthError, ProviderConfigAgent, ProviderContextLengthError, ProviderError, ProviderErrorMapper, ProviderNotFoundError, ProviderRateLimitError, RapidAPIProvider, RateLimitError, SERVICE_DEFINITIONS, SERVICE_INFO, SERVICE_URL_PATTERNS, SIMPLE_ICONS_CDN, STT_MODELS, STT_MODEL_REGISTRY, ScopedConnectorRegistry, ScrapeProvider, SearchProvider, SerperProvider, Services, SpeechToText, StrategyRegistry, StreamEventType, StreamHelpers, StreamState, SummarizeCompactor, TERMINAL_TASK_STATUSES, TTS_MODELS, TTS_MODEL_REGISTRY, TaskTimeoutError, TaskValidationError, TavilyProvider, TextToSpeech, TokenBucketRateLimiter, ToolCallState, ToolExecutionError, ToolExecutionPipeline, ToolManager, ToolNotFoundError, ToolPermissionManager, ToolRegistry, ToolTimeoutError, TruncateCompactor, VENDORS, VENDOR_ICON_MAP, VIDEO_MODELS, VIDEO_MODEL_REGISTRY, Vendor, VideoGeneration, WorkingMemory, WorkingMemoryPluginNextGen, addJitter, allVendorTemplates, assertNotDestroyed, authenticatedFetch, backoffSequence, backoffWait, bash, buildAuthConfig, buildEndpointWithQuery, buildQueryString, calculateBackoff, calculateCost, calculateEntrySize, calculateImageCost, calculateSTTCost, calculateTTSCost, calculateVideoCost, canTaskExecute, createAgentStorage, createAuthenticatedFetch, createBashTool, createConnectorFromTemplate, createEditFileTool, createEstimator, createExecuteJavaScriptTool, createFileAgentDefinitionStorage, createFileContextStorage, createGlobTool, createGrepTool, createImageGenerationTool, createImageProvider, createListDirectoryTool, createMessageWithImages, createMetricsCollector, createPlan, createProvider, createReadFileTool, createSpeechToTextTool, createTask, createTextMessage, createTextToSpeechTool, createVideoProvider, createVideoTools, createWriteFileTool, defaultDescribeCall, detectDependencyCycle, detectServiceFromURL, developerTools, editFile, evaluateCondition, extractJSON, extractJSONField, extractNumber, findConnectorByServiceTypes, forPlan, forTasks, generateEncryptionKey, generateSimplePlan, generateWebAPITool, getActiveImageModels, getActiveModels, getActiveSTTModels, getActiveTTSModels, getActiveVideoModels, getAllBuiltInTools, getAllServiceIds, getAllVendorLogos, getAllVendorTemplates, getBackgroundOutput, getConnectorTools, getCredentialsSetupURL, getDocsURL, getImageModelInfo, getImageModelsByVendor, getImageModelsWithFeature, getMediaOutputHandler, getModelInfo, getModelsByVendor, getNextExecutableTasks, getRegisteredScrapeProviders, getSTTModelInfo, getSTTModelsByVendor, getSTTModelsWithFeature, getServiceDefinition, getServiceInfo, getServicesByCategory, getTTSModelInfo, getTTSModelsByVendor, getTTSModelsWithFeature, getTaskDependencies, getToolByName, getToolCallDescription, getToolCategories, getToolRegistry, getToolsByCategory, getToolsRequiringConnector, getVendorAuthTemplate, getVendorColor, getVendorInfo, getVendorLogo, getVendorLogoCdnUrl, getVendorLogoSvg, getVendorTemplate, getVideoModelInfo, getVideoModelsByVendor, getVideoModelsWithAudio, getVideoModelsWithFeature, glob, globalErrorHandler, grep, hasClipboardImage, hasVendorLogo, isBlockedCommand, isErrorEvent, isExcludedExtension, isKnownService, isOutputTextDelta, isResponseComplete, isSimpleScope, isStreamEvent, isTaskAwareScope, isTaskBlocked, isTerminalMemoryStatus, isTerminalStatus, isToolCallArgumentsDelta, isToolCallArgumentsDone, isToolCallStart, isVendor, killBackgroundProcess, listConnectorsByServiceTypes, listDirectory, listVendorIds, listVendors, listVendorsByAuthType, listVendorsByCategory, listVendorsWithLogos, logger, metrics, readClipboardImage, readFile4 as readFile, registerScrapeProvider, resolveConnector, resolveDependencies, retryWithBackoff, scopeEquals, scopeMatches, setMediaOutputHandler, setMetricsCollector, simpleTokenEstimator, toConnectorOptions, toolRegistry, tools_exports as tools, updateTaskStatus, validatePath, writeFile4 as writeFile };
50158
+ export { AGENT_DEFINITION_FORMAT_VERSION, AIError, APPROVAL_STATE_VERSION, Agent, AgentContextNextGen, ApproximateTokenEstimator, BaseMediaProvider, BasePluginNextGen, BaseProvider, BaseTextProvider, BraveProvider, CONNECTOR_CONFIG_VERSION, CONTEXT_SESSION_FORMAT_VERSION, CheckpointManager, CircuitBreaker, CircuitOpenError, Connector, ConnectorConfigStore, ConnectorTools, ConsoleMetrics, ContentType, ContextOverflowError, DEFAULT_ALLOWLIST, DEFAULT_BACKOFF_CONFIG, DEFAULT_BASE_DELAY_MS, DEFAULT_CHECKPOINT_STRATEGY, DEFAULT_CIRCUIT_BREAKER_CONFIG, DEFAULT_CONFIG2 as DEFAULT_CONFIG, DEFAULT_CONNECTOR_TIMEOUT, DEFAULT_CONTEXT_CONFIG, DEFAULT_FEATURES, DEFAULT_FILESYSTEM_CONFIG, DEFAULT_HISTORY_MANAGER_CONFIG, DEFAULT_MAX_DELAY_MS, DEFAULT_MAX_RETRIES, DEFAULT_MEMORY_CONFIG, DEFAULT_PERMISSION_CONFIG, DEFAULT_RATE_LIMITER_CONFIG, DEFAULT_RETRYABLE_STATUSES, DEFAULT_SHELL_CONFIG, DefaultCompactionStrategy, DependencyCycleError, ErrorHandler, ExecutionContext, ExternalDependencyHandler, FileAgentDefinitionStorage, FileConnectorStorage, FileContextStorage, FileMediaStorage as FileMediaOutputHandler, FileMediaStorage, FilePersistentInstructionsStorage, FileStorage, FrameworkLogger, HookManager, IMAGE_MODELS, IMAGE_MODEL_REGISTRY, ImageGeneration, InContextMemoryPluginNextGen, InMemoryAgentStateStorage, InMemoryHistoryStorage, InMemoryMetrics, InMemoryPlanStorage, InMemoryStorage, InvalidConfigError, InvalidToolArgumentsError, LLM_MODELS, LoggingPlugin, MCPClient, MCPConnectionError, MCPError, MCPProtocolError, MCPRegistry, MCPResourceError, MCPTimeoutError, MCPToolError, MEMORY_PRIORITY_VALUES, MODEL_REGISTRY, MemoryConnectorStorage, MemoryEvictionCompactor, MemoryStorage, MessageBuilder, MessageRole, ModelNotSupportedError, NoOpMetrics, OAuthManager, ParallelTasksError, PersistentInstructionsPluginNextGen, PlanningAgent, ProviderAuthError, ProviderConfigAgent, ProviderContextLengthError, ProviderError, ProviderErrorMapper, ProviderNotFoundError, ProviderRateLimitError, RapidAPIProvider, RateLimitError, SERVICE_DEFINITIONS, SERVICE_INFO, SERVICE_URL_PATTERNS, SIMPLE_ICONS_CDN, STT_MODELS, STT_MODEL_REGISTRY, ScopedConnectorRegistry, ScrapeProvider, SearchProvider, SerperProvider, Services, SpeechToText, StrategyRegistry, StreamEventType, StreamHelpers, StreamState, SummarizeCompactor, TERMINAL_TASK_STATUSES, TTS_MODELS, TTS_MODEL_REGISTRY, TaskTimeoutError, TaskValidationError, TavilyProvider, TextToSpeech, TokenBucketRateLimiter, ToolCallState, ToolExecutionError, ToolExecutionPipeline, ToolManager, ToolNotFoundError, ToolPermissionManager, ToolRegistry, ToolTimeoutError, TruncateCompactor, VENDORS, VENDOR_ICON_MAP, VIDEO_MODELS, VIDEO_MODEL_REGISTRY, Vendor, VideoGeneration, WorkingMemory, WorkingMemoryPluginNextGen, addJitter, allVendorTemplates, assertNotDestroyed, authenticatedFetch, backoffSequence, backoffWait, bash, buildAuthConfig, buildEndpointWithQuery, buildQueryString, calculateBackoff, calculateCost, calculateEntrySize, calculateImageCost, calculateSTTCost, calculateTTSCost, calculateVideoCost, canTaskExecute, createAgentStorage, createAuthenticatedFetch, createBashTool, createConnectorFromTemplate, createCreatePRTool, createEditFileTool, createEstimator, createExecuteJavaScriptTool, createFileAgentDefinitionStorage, createFileContextStorage, createFileMediaStorage, createGetPRTool, createGitHubReadFileTool, createGlobTool, createGrepTool, createImageGenerationTool, createImageProvider, createListDirectoryTool, createMessageWithImages, createMetricsCollector, createPRCommentsTool, createPRFilesTool, createPlan, createProvider, createReadFileTool, createSearchCodeTool, createSearchFilesTool, createSpeechToTextTool, createTask, createTextMessage, createTextToSpeechTool, createVideoProvider, createVideoTools, createWriteFileTool, defaultDescribeCall, detectDependencyCycle, detectServiceFromURL, developerTools, editFile, evaluateCondition, extractJSON, extractJSONField, extractNumber, findConnectorByServiceTypes, forPlan, forTasks, generateEncryptionKey, generateSimplePlan, generateWebAPITool, getActiveImageModels, getActiveModels, getActiveSTTModels, getActiveTTSModels, getActiveVideoModels, getAllBuiltInTools, getAllServiceIds, getAllVendorLogos, getAllVendorTemplates, getBackgroundOutput, getConnectorTools, getCredentialsSetupURL, getDocsURL, getImageModelInfo, getImageModelsByVendor, getImageModelsWithFeature, getMediaOutputHandler, getMediaStorage, getModelInfo, getModelsByVendor, getNextExecutableTasks, getRegisteredScrapeProviders, getSTTModelInfo, getSTTModelsByVendor, getSTTModelsWithFeature, getServiceDefinition, getServiceInfo, getServicesByCategory, getTTSModelInfo, getTTSModelsByVendor, getTTSModelsWithFeature, getTaskDependencies, getToolByName, getToolCallDescription, getToolCategories, getToolRegistry, getToolsByCategory, getToolsRequiringConnector, getVendorAuthTemplate, getVendorColor, getVendorDefaultBaseURL, getVendorInfo, getVendorLogo, getVendorLogoCdnUrl, getVendorLogoSvg, getVendorTemplate, getVideoModelInfo, getVideoModelsByVendor, getVideoModelsWithAudio, getVideoModelsWithFeature, glob, globalErrorHandler, grep, hasClipboardImage, hasVendorLogo, isBlockedCommand, isErrorEvent, isExcludedExtension, isKnownService, isOutputTextDelta, isResponseComplete, isSimpleScope, isStreamEvent, isTaskAwareScope, isTaskBlocked, isTerminalMemoryStatus, isTerminalStatus, isToolCallArgumentsDelta, isToolCallArgumentsDone, isToolCallStart, isVendor, killBackgroundProcess, listConnectorsByServiceTypes, listDirectory, listVendorIds, listVendors, listVendorsByAuthType, listVendorsByCategory, listVendorsWithLogos, logger, metrics, parseRepository, readClipboardImage, readFile5 as readFile, registerScrapeProvider, resolveConnector, resolveDependencies, resolveRepository, retryWithBackoff, scopeEquals, scopeMatches, setMediaOutputHandler, setMediaStorage, setMetricsCollector, simpleTokenEstimator, toConnectorOptions, toolRegistry, tools_exports as tools, updateTaskStatus, validatePath, writeFile5 as writeFile };
49089
50159
  //# sourceMappingURL=index.js.map
49090
50160
  //# sourceMappingURL=index.js.map