teleton 0.1.17 → 0.1.18

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.
@@ -1,6 +1,7 @@
1
1
  import {
2
- VOYAGE_API_URL
3
- } from "./chunk-ST5CO7TV.js";
2
+ VOYAGE_API_URL,
3
+ fetchWithTimeout
4
+ } from "./chunk-WMIN6AGX.js";
4
5
  import {
5
6
  KNOWLEDGE_CHUNK_OVERLAP,
6
7
  KNOWLEDGE_CHUNK_SIZE,
@@ -8,9 +9,6 @@ import {
8
9
  SQLITE_MMAP_SIZE,
9
10
  VOYAGE_BATCH_SIZE
10
11
  } from "./chunk-QMN6ZOA5.js";
11
- import {
12
- DEFAULT_FETCH_TIMEOUT_MS
13
- } from "./chunk-LJXYESJJ.js";
14
12
 
15
13
  // src/memory/database.ts
16
14
  import Database from "better-sqlite3";
@@ -884,19 +882,6 @@ var NoopEmbeddingProvider = class {
884
882
  }
885
883
  };
886
884
 
887
- // src/utils/fetch.ts
888
- var DEFAULT_TIMEOUT_MS = DEFAULT_FETCH_TIMEOUT_MS;
889
- function fetchWithTimeout(url, init) {
890
- const { timeoutMs = DEFAULT_TIMEOUT_MS, ...fetchInit } = init ?? {};
891
- if (fetchInit.signal) {
892
- return fetch(url, fetchInit);
893
- }
894
- return fetch(url, {
895
- ...fetchInit,
896
- signal: AbortSignal.timeout(timeoutMs)
897
- });
898
- }
899
-
900
885
  // src/memory/embeddings/anthropic.ts
901
886
  var AnthropicEmbeddingProvider = class {
902
887
  id = "anthropic";
@@ -2024,7 +2009,6 @@ export {
2024
2009
  getDatabase,
2025
2010
  closeDatabase,
2026
2011
  NoopEmbeddingProvider,
2027
- fetchWithTimeout,
2028
2012
  AnthropicEmbeddingProvider,
2029
2013
  LocalEmbeddingProvider,
2030
2014
  createEmbeddingProvider,
@@ -3,10 +3,9 @@ import {
3
3
  ContextBuilder,
4
4
  MessageStore,
5
5
  UserStore,
6
- fetchWithTimeout,
7
6
  getDatabase,
8
7
  initializeMemory
9
- } from "./chunk-PMX75DTX.js";
8
+ } from "./chunk-JDPS46IZ.js";
10
9
  import {
11
10
  ALLOWED_EXTENSIONS,
12
11
  MAX_FILE_SIZES,
@@ -20,10 +19,10 @@ import {
20
19
  GECKOTERMINAL_API_URL,
21
20
  OPENAI_TTS_URL,
22
21
  STONFI_API_BASE_URL,
23
- TONAPI_BASE_URL,
22
+ fetchWithTimeout,
24
23
  setTonapiKey,
25
- tonapiHeaders
26
- } from "./chunk-ST5CO7TV.js";
24
+ tonapiFetch
25
+ } from "./chunk-WMIN6AGX.js";
27
26
  import {
28
27
  COMPACTION_KEEP_RECENT,
29
28
  COMPACTION_MAX_MESSAGES,
@@ -3192,6 +3191,18 @@ function maskOldToolResults(messages, config = DEFAULT_MASKING_CONFIG, toolRegis
3192
3191
  return result;
3193
3192
  }
3194
3193
 
3194
+ // src/utils/logger.ts
3195
+ var _verbose = process.env.TELETON_LOG === "verbose";
3196
+ function verbose(...args) {
3197
+ if (_verbose) console.log(...args);
3198
+ }
3199
+ function setVerbose(v) {
3200
+ _verbose = v;
3201
+ }
3202
+ function isVerbose() {
3203
+ return _verbose;
3204
+ }
3205
+
3195
3206
  // src/agent/runtime.ts
3196
3207
  function isContextOverflowError(errorMessage) {
3197
3208
  if (!errorMessage) return false;
@@ -3327,9 +3338,14 @@ var AgentRuntime = class {
3327
3338
  formattedMessage = `${pendingContext}
3328
3339
 
3329
3340
  ${formattedMessage}`;
3330
- console.log(`\u{1F4CB} Including ${pendingContext.split("\n").length - 1} pending messages`);
3331
- }
3332
- console.log(`\u{1F4E8} Formatted message: ${formattedMessage.substring(0, 100)}...`);
3341
+ verbose(`\u{1F4CB} Including ${pendingContext.split("\n").length - 1} pending messages`);
3342
+ }
3343
+ verbose(`\u{1F4E8} Formatted message: ${formattedMessage.substring(0, 100)}...`);
3344
+ const preview = formattedMessage.slice(0, 50).replace(/\n/g, " ");
3345
+ const who = senderUsername ? `@${senderUsername}` : userName;
3346
+ const msgType = isGroup ? `Group ${chatId} ${who}` : `DM ${who}`;
3347
+ console.log(`
3348
+ \u{1F4E8} ${msgType}: "${preview}${formattedMessage.length > 50 ? "..." : ""}"`);
3333
3349
  let relevantContext = "";
3334
3350
  if (this.contextBuilder) {
3335
3351
  try {
@@ -3358,7 +3374,7 @@ ${dbContext.relevantFeed.join("\n")}`
3358
3374
  }
3359
3375
  if (contextParts.length > 0) {
3360
3376
  relevantContext = contextParts.join("\n\n");
3361
- console.log(
3377
+ verbose(
3362
3378
  `\u{1F50D} Found ${dbContext.relevantKnowledge.length} knowledge chunks, ${dbContext.relevantFeed.length} feed messages`
3363
3379
  );
3364
3380
  }
@@ -3424,7 +3440,7 @@ ${statsContext}`;
3424
3440
  const accumulatedTexts = [];
3425
3441
  while (iteration < maxIterations) {
3426
3442
  iteration++;
3427
- console.log(`
3443
+ verbose(`
3428
3444
  \u{1F504} Agentic iteration ${iteration}/${maxIterations}`);
3429
3445
  const maskedMessages = maskOldToolResults(
3430
3446
  context.messages,
@@ -3491,7 +3507,7 @@ ${statsContext}`;
3491
3507
  }
3492
3508
  const toolCalls = response2.message.content.filter((block) => block.type === "toolCall");
3493
3509
  if (toolCalls.length === 0) {
3494
- console.log(`\u2705 Agent finished (no more tool calls)`);
3510
+ console.log(` \u{1F504} ${iteration}/${maxIterations} \u2192 done`);
3495
3511
  finalResponse = response2;
3496
3512
  break;
3497
3513
  }
@@ -3499,8 +3515,9 @@ ${statsContext}`;
3499
3515
  console.error("\u26A0\uFE0F Cannot execute tools: registry or context missing");
3500
3516
  break;
3501
3517
  }
3502
- console.log(`\u{1F527} Executing ${toolCalls.length} tool call(s)`);
3518
+ verbose(`\u{1F527} Executing ${toolCalls.length} tool call(s)`);
3503
3519
  context.messages.push(response2.message);
3520
+ const iterationToolNames = [];
3504
3521
  for (const block of toolCalls) {
3505
3522
  if (block.type !== "toolCall") continue;
3506
3523
  const fullContext = {
@@ -3509,7 +3526,8 @@ ${statsContext}`;
3509
3526
  isGroup: isGroup ?? false
3510
3527
  };
3511
3528
  const result = await this.toolRegistry.execute(block, fullContext);
3512
- console.log(` ${block.name}: ${result.success ? "\u2713" : "\u2717"} ${result.error || ""}`);
3529
+ verbose(` ${block.name}: ${result.success ? "\u2713" : "\u2717"} ${result.error || ""}`);
3530
+ iterationToolNames.push(`${block.name} ${result.success ? "\u2713" : "\u2717"}`);
3513
3531
  totalToolCalls.push({
3514
3532
  name: block.name,
3515
3533
  input: block.arguments
@@ -3552,8 +3570,9 @@ ${statsContext}`;
3552
3570
  context.messages.push(toolResultMsg);
3553
3571
  appendToTranscript(session.sessionId, toolResultMsg);
3554
3572
  }
3573
+ console.log(` \u{1F504} ${iteration}/${maxIterations} \u2192 ${iterationToolNames.join(", ")}`);
3555
3574
  if (iteration === maxIterations) {
3556
- console.log(`\u26A0\uFE0F Max iterations reached (${maxIterations})`);
3575
+ console.log(` \u26A0\uFE0F Max iterations reached (${maxIterations})`);
3557
3576
  finalResponse = response2;
3558
3577
  }
3559
3578
  }
@@ -3584,9 +3603,8 @@ ${statsContext}`;
3584
3603
  }
3585
3604
  const usage = response.message.usage;
3586
3605
  if (usage) {
3587
- console.log(
3588
- `\u{1F4B0} Usage: ${usage.input} in, ${usage.output} out, ${usage.cacheRead} cache read | Cost: $${usage.cost.total.toFixed(4)}`
3589
- );
3606
+ const inK = (usage.input / 1e3).toFixed(1);
3607
+ console.log(` \u{1F4B0} ${inK}K in, ${usage.output} out | $${usage.cost.total.toFixed(3)}`);
3590
3608
  }
3591
3609
  let content = accumulatedTexts.join("\n").trim() || response.text;
3592
3610
  const telegramSendTools = [
@@ -4666,7 +4684,7 @@ var MessageHandler = class {
4666
4684
  */
4667
4685
  async handleMessage(message) {
4668
4686
  const msgType = message.isGroup ? "group" : message.isChannel ? "channel" : "dm";
4669
- console.log(
4687
+ verbose(
4670
4688
  `\u{1F4E8} [Handler] Received ${msgType} message ${message.id} from ${message.senderId} (mentions: ${message.mentionsMe})`
4671
4689
  );
4672
4690
  await this.storeTelegramMessage(message, false);
@@ -4675,15 +4693,20 @@ var MessageHandler = class {
4675
4693
  this.pendingHistory.addMessage(message.chatId, message);
4676
4694
  }
4677
4695
  if (!context.shouldRespond) {
4678
- console.log(`Skipping message ${message.id} from ${message.senderId}: ${context.reason}`);
4696
+ if (message.isGroup && context.reason === "Not mentioned") {
4697
+ const chatShort = message.chatId.length > 10 ? message.chatId.slice(0, 7) + ".." + message.chatId.slice(-2) : message.chatId;
4698
+ console.log(`\u23ED\uFE0F Group ${chatShort} msg:${message.id} (not mentioned)`);
4699
+ } else {
4700
+ verbose(`Skipping message ${message.id} from ${message.senderId}: ${context.reason}`);
4701
+ }
4679
4702
  return;
4680
4703
  }
4681
4704
  if (!this.rateLimiter.canSendMessage()) {
4682
- console.log("Rate limit reached, skipping message");
4705
+ verbose("Rate limit reached, skipping message");
4683
4706
  return;
4684
4707
  }
4685
4708
  if (message.isGroup && !this.rateLimiter.canSendToGroup(message.chatId)) {
4686
- console.log(`Group rate limit reached for ${message.chatId}`);
4709
+ verbose(`Group rate limit reached for ${message.chatId}`);
4687
4710
  return;
4688
4711
  }
4689
4712
  const releaseLock = await this.chatLock.acquire(message.chatId);
@@ -4763,7 +4786,7 @@ var MessageHandler = class {
4763
4786
  this.pendingHistory.clearPending(message.chatId);
4764
4787
  }
4765
4788
  writeOffset(message.id, message.chatId);
4766
- console.log(`Processed message ${message.id} in chat ${message.chatId}`);
4789
+ verbose(`Processed message ${message.id} in chat ${message.chatId}`);
4767
4790
  } catch (error) {
4768
4791
  console.error("Error handling message:", error);
4769
4792
  } finally {
@@ -4900,9 +4923,7 @@ async function getWalletBalance(address4) {
4900
4923
  }
4901
4924
  async function getTonPrice() {
4902
4925
  try {
4903
- const response = await fetchWithTimeout(`${TONAPI_BASE_URL}/rates?tokens=ton&currencies=usd`, {
4904
- headers: tonapiHeaders()
4905
- });
4926
+ const response = await tonapiFetch(`/rates?tokens=ton&currencies=usd`);
4906
4927
  if (response.ok) {
4907
4928
  const data = await response.json();
4908
4929
  const price = data?.rates?.TON?.prices?.USD;
@@ -5044,6 +5065,8 @@ var AdminHandler = class {
5044
5065
  return this.handleStrategyCommand(command);
5045
5066
  case "stop":
5046
5067
  return await this.handleStopCommand();
5068
+ case "verbose":
5069
+ return this.handleVerboseCommand();
5047
5070
  case "help":
5048
5071
  return this.handleHelpCommand();
5049
5072
  case "ping":
@@ -5248,6 +5271,14 @@ Usage:
5248
5271
  return null;
5249
5272
  }
5250
5273
  }
5274
+ /**
5275
+ * /verbose - Toggle verbose logging at runtime
5276
+ */
5277
+ handleVerboseCommand() {
5278
+ const next = !isVerbose();
5279
+ setVerbose(next);
5280
+ return next ? "\u{1F50A} Verbose logging **ON**" : "\u{1F507} Verbose logging **OFF**";
5281
+ }
5251
5282
  /**
5252
5283
  * /help - Show available commands
5253
5284
  */
@@ -5272,6 +5303,9 @@ View or change trading thresholds
5272
5303
  **/wallet**
5273
5304
  Check TON wallet balance
5274
5305
 
5306
+ **/verbose**
5307
+ Toggle verbose debug logging
5308
+
5275
5309
  **/pause** / **/resume**
5276
5310
  Pause or resume the agent
5277
5311
 
@@ -5314,18 +5348,16 @@ var MessageDebouncer = class {
5314
5348
  async enqueue(message) {
5315
5349
  const isGroup = message.isGroup ? "group" : "dm";
5316
5350
  const shouldDebounce = this.config.debounceMs > 0 && this.shouldDebounce(message);
5317
- console.log(
5351
+ verbose(
5318
5352
  `\u{1F4E9} [Debouncer] Received ${isGroup} message from ${message.senderId} in ${message.chatId} (debounce: ${shouldDebounce})`
5319
5353
  );
5320
5354
  if (!shouldDebounce) {
5321
5355
  const key2 = message.chatId;
5322
5356
  if (this.buffers.has(key2)) {
5323
- console.log(
5324
- `\u{1F4E4} [Debouncer] Flushing pending buffer for ${key2} before immediate processing`
5325
- );
5357
+ verbose(`\u{1F4E4} [Debouncer] Flushing pending buffer for ${key2} before immediate processing`);
5326
5358
  await this.flushKey(key2);
5327
5359
  }
5328
- console.log(`\u26A1 [Debouncer] Processing immediately (no debounce)`);
5360
+ verbose(`\u26A1 [Debouncer] Processing immediately (no debounce)`);
5329
5361
  await this.processMessages([message]);
5330
5362
  return;
5331
5363
  }
@@ -5333,7 +5365,7 @@ var MessageDebouncer = class {
5333
5365
  const existing = this.buffers.get(key);
5334
5366
  if (existing) {
5335
5367
  existing.messages.push(message);
5336
- console.log(
5368
+ verbose(
5337
5369
  `\u{1F4E5} [Debouncer] Added to buffer for ${key} (${existing.messages.length} messages waiting)`
5338
5370
  );
5339
5371
  this.resetTimer(key, existing);
@@ -5367,7 +5399,7 @@ var MessageDebouncer = class {
5367
5399
  async flushKey(key) {
5368
5400
  const buffer = this.buffers.get(key);
5369
5401
  if (!buffer) {
5370
- console.log(`\u{1F4ED} [Debouncer] No buffer to flush for ${key}`);
5402
+ verbose(`\u{1F4ED} [Debouncer] No buffer to flush for ${key}`);
5371
5403
  return;
5372
5404
  }
5373
5405
  this.buffers.delete(key);
@@ -5376,10 +5408,10 @@ var MessageDebouncer = class {
5376
5408
  buffer.timer = null;
5377
5409
  }
5378
5410
  if (buffer.messages.length === 0) {
5379
- console.log(`\u{1F4ED} [Debouncer] Empty buffer for ${key}, nothing to flush`);
5411
+ verbose(`\u{1F4ED} [Debouncer] Empty buffer for ${key}, nothing to flush`);
5380
5412
  return;
5381
5413
  }
5382
- console.log(`\u{1F4E4} [Debouncer] Flushing ${buffer.messages.length} message(s) for ${key}`);
5414
+ verbose(`\u{1F4E4} [Debouncer] Flushing ${buffer.messages.length} message(s) for ${key}`);
5383
5415
  await this.processMessages(buffer.messages);
5384
5416
  }
5385
5417
  /**
@@ -5387,7 +5419,7 @@ var MessageDebouncer = class {
5387
5419
  */
5388
5420
  async processMessages(messages) {
5389
5421
  const sorted = messages.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
5390
- console.log(`\u{1F504} [Debouncer] Processing ${sorted.length} message(s)`);
5422
+ verbose(`\u{1F504} [Debouncer] Processing ${sorted.length} message(s)`);
5391
5423
  try {
5392
5424
  await this.onFlush(sorted);
5393
5425
  } catch (error) {
@@ -5447,7 +5479,7 @@ var MarketScraperService = class {
5447
5479
  this.isScrapingInProgress = true;
5448
5480
  console.log("\u{1F504} Starting full market scrape...");
5449
5481
  try {
5450
- const { runScraper } = await import("./scraper-BET6OXRF.js");
5482
+ const { runScraper } = await import("./scraper-I2TFAK4V.js");
5451
5483
  const result = await runScraper({
5452
5484
  workers: 4,
5453
5485
  limit: 0
@@ -5590,7 +5622,7 @@ var MarketPriceService = class {
5590
5622
  const updatedAt = /* @__PURE__ */ new Date(model.updated_at + "Z");
5591
5623
  const cacheAge = Date.now() - updatedAt.getTime();
5592
5624
  if (cacheAge > this.cacheTtlMs) {
5593
- console.log(
5625
+ verbose(
5594
5626
  ` \u23F0 Cache stale for ${collectionName} (${Math.round(cacheAge / 1e3 / 60)} min old)`
5595
5627
  );
5596
5628
  }
@@ -12516,9 +12548,7 @@ var dnsCheckExecutor = async (params, context) => {
12516
12548
  };
12517
12549
  }
12518
12550
  const fullDomain = `${domain}.ton`;
12519
- const dnsInfoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
12520
- headers: tonapiHeaders()
12521
- });
12551
+ const dnsInfoResponse = await tonapiFetch(`/dns/${fullDomain}`);
12522
12552
  if (dnsInfoResponse.status === 404) {
12523
12553
  const minPrice = estimateMinPrice(domain.length);
12524
12554
  return {
@@ -12559,9 +12589,7 @@ var dnsCheckExecutor = async (params, context) => {
12559
12589
  }
12560
12590
  };
12561
12591
  }
12562
- const auctionsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/auctions?tld=ton`, {
12563
- headers: tonapiHeaders()
12564
- });
12592
+ const auctionsResponse = await tonapiFetch(`/dns/auctions?tld=ton`);
12565
12593
  if (auctionsResponse.ok) {
12566
12594
  const auctions = await auctionsResponse.json();
12567
12595
  const auction = auctions.data?.find((a) => a.domain === fullDomain);
@@ -12623,9 +12651,7 @@ var dnsAuctionsTool = {
12623
12651
  var dnsAuctionsExecutor = async (params, context) => {
12624
12652
  try {
12625
12653
  const { limit = 20 } = params;
12626
- const response = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/auctions?tld=ton`, {
12627
- headers: tonapiHeaders()
12628
- });
12654
+ const response = await tonapiFetch(`/dns/auctions?tld=ton`);
12629
12655
  if (!response.ok) {
12630
12656
  return {
12631
12657
  success: false,
@@ -12694,9 +12720,7 @@ var dnsResolveExecutor = async (params, context) => {
12694
12720
  let { domain } = params;
12695
12721
  domain = domain.toLowerCase().replace(/\.ton$/, "");
12696
12722
  const fullDomain = `${domain}.ton`;
12697
- const response = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
12698
- headers: tonapiHeaders()
12699
- });
12723
+ const response = await tonapiFetch(`/dns/${fullDomain}`);
12700
12724
  if (response.status === 404) {
12701
12725
  return {
12702
12726
  success: false,
@@ -12853,9 +12877,7 @@ var dnsBidExecutor = async (params, context) => {
12853
12877
  let { domain, amount } = params;
12854
12878
  domain = domain.toLowerCase().replace(/\.ton$/, "");
12855
12879
  const fullDomain = `${domain}.ton`;
12856
- const dnsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
12857
- headers: tonapiHeaders()
12858
- });
12880
+ const dnsResponse = await tonapiFetch(`/dns/${fullDomain}`);
12859
12881
  if (dnsResponse.status === 404) {
12860
12882
  return {
12861
12883
  success: false,
@@ -12882,9 +12904,7 @@ var dnsBidExecutor = async (params, context) => {
12882
12904
  error: `Could not determine NFT address for ${fullDomain}`
12883
12905
  };
12884
12906
  }
12885
- const auctionsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/auctions?tld=ton`, {
12886
- headers: tonapiHeaders()
12887
- });
12907
+ const auctionsResponse = await tonapiFetch(`/dns/auctions?tld=ton`);
12888
12908
  if (auctionsResponse.ok) {
12889
12909
  const auctions = await auctionsResponse.json();
12890
12910
  const auction = auctions.data?.find((a) => a.domain === fullDomain);
@@ -12997,9 +13017,7 @@ var dnsLinkExecutor = async (params, context) => {
12997
13017
  error: `Invalid wallet address: ${targetAddress}`
12998
13018
  };
12999
13019
  }
13000
- const dnsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
13001
- headers: tonapiHeaders()
13002
- });
13020
+ const dnsResponse = await tonapiFetch(`/dns/${fullDomain}`);
13003
13021
  if (dnsResponse.status === 404) {
13004
13022
  return {
13005
13023
  success: false,
@@ -13112,9 +13130,7 @@ var dnsUnlinkExecutor = async (params, context) => {
13112
13130
  error: "Wallet not initialized. Contact admin to generate wallet."
13113
13131
  };
13114
13132
  }
13115
- const dnsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
13116
- headers: tonapiHeaders()
13117
- });
13133
+ const dnsResponse = await tonapiFetch(`/dns/${fullDomain}`);
13118
13134
  if (dnsResponse.status === 404) {
13119
13135
  return {
13120
13136
  success: false,
@@ -13211,12 +13227,7 @@ var jettonBalancesExecutor = async (params, context) => {
13211
13227
  error: "Wallet not initialized. Contact admin to generate wallet."
13212
13228
  };
13213
13229
  }
13214
- const response = await fetchWithTimeout(
13215
- `${TONAPI_BASE_URL}/accounts/${walletData.address}/jettons`,
13216
- {
13217
- headers: tonapiHeaders()
13218
- }
13219
- );
13230
+ const response = await tonapiFetch(`/accounts/${walletData.address}/jettons`);
13220
13231
  if (!response.ok) {
13221
13232
  return {
13222
13233
  success: false,
@@ -16810,12 +16821,7 @@ var jettonSendExecutor = async (params, context) => {
16810
16821
  error: `Invalid recipient address: ${to}`
16811
16822
  };
16812
16823
  }
16813
- const jettonsResponse = await fetchWithTimeout(
16814
- `${TONAPI_BASE_URL}/accounts/${walletData.address}/jettons`,
16815
- {
16816
- headers: tonapiHeaders()
16817
- }
16818
- );
16824
+ const jettonsResponse = await tonapiFetch(`/accounts/${walletData.address}/jettons`);
16819
16825
  if (!jettonsResponse.ok) {
16820
16826
  return {
16821
16827
  success: false,
@@ -16908,9 +16914,7 @@ var jettonInfoTool = {
16908
16914
  var jettonInfoExecutor = async (params, context) => {
16909
16915
  try {
16910
16916
  const { jetton_address } = params;
16911
- const response = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
16912
- headers: tonapiHeaders()
16913
- });
16917
+ const response = await tonapiFetch(`/jettons/${jetton_address}`);
16914
16918
  if (response.status === 404) {
16915
16919
  return {
16916
16920
  success: false,
@@ -17005,11 +17009,8 @@ var jettonPriceTool = {
17005
17009
  var jettonPriceExecutor = async (params, context) => {
17006
17010
  try {
17007
17011
  const { jetton_address } = params;
17008
- const response = await fetchWithTimeout(
17009
- `${TONAPI_BASE_URL}/rates?tokens=${encodeURIComponent(jetton_address)}&currencies=usd,ton`,
17010
- {
17011
- headers: tonapiHeaders()
17012
- }
17012
+ const response = await tonapiFetch(
17013
+ `/rates?tokens=${encodeURIComponent(jetton_address)}&currencies=usd,ton`
17013
17014
  );
17014
17015
  if (!response.ok) {
17015
17016
  return {
@@ -17020,9 +17021,7 @@ var jettonPriceExecutor = async (params, context) => {
17020
17021
  const data = await response.json();
17021
17022
  const rateData = data.rates?.[jetton_address];
17022
17023
  if (!rateData) {
17023
- const infoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
17024
- headers: tonapiHeaders()
17025
- });
17024
+ const infoResponse = await tonapiFetch(`/jettons/${jetton_address}`);
17026
17025
  if (infoResponse.status === 404) {
17027
17026
  return {
17028
17027
  success: false,
@@ -17041,9 +17040,7 @@ var jettonPriceExecutor = async (params, context) => {
17041
17040
  let symbol = "TOKEN";
17042
17041
  let name = "Unknown Token";
17043
17042
  try {
17044
- const infoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
17045
- headers: tonapiHeaders()
17046
- });
17043
+ const infoResponse = await tonapiFetch(`/jettons/${jetton_address}`);
17047
17044
  if (infoResponse.ok) {
17048
17045
  const infoData = await infoResponse.json();
17049
17046
  symbol = infoData.metadata?.symbol || symbol;
@@ -17340,11 +17337,8 @@ var jettonHoldersTool = {
17340
17337
  var jettonHoldersExecutor = async (params, context) => {
17341
17338
  try {
17342
17339
  const { jetton_address, limit = 10 } = params;
17343
- const response = await fetchWithTimeout(
17344
- `${TONAPI_BASE_URL}/jettons/${jetton_address}/holders?limit=${Math.min(limit, 100)}`,
17345
- {
17346
- headers: tonapiHeaders()
17347
- }
17340
+ const response = await tonapiFetch(
17341
+ `/jettons/${jetton_address}/holders?limit=${Math.min(limit, 100)}`
17348
17342
  );
17349
17343
  if (response.status === 404) {
17350
17344
  return {
@@ -17363,9 +17357,7 @@ var jettonHoldersExecutor = async (params, context) => {
17363
17357
  let decimals = 9;
17364
17358
  let symbol = "TOKEN";
17365
17359
  try {
17366
- const infoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
17367
- headers: tonapiHeaders()
17368
- });
17360
+ const infoResponse = await tonapiFetch(`/jettons/${jetton_address}`);
17369
17361
  if (infoResponse.ok) {
17370
17362
  const infoData = await infoResponse.json();
17371
17363
  decimals = parseInt(infoData.metadata?.decimals || "9");
@@ -17432,17 +17424,14 @@ var jettonHistoryTool = {
17432
17424
  var jettonHistoryExecutor = async (params, context) => {
17433
17425
  try {
17434
17426
  const { jetton_address } = params;
17435
- const ratesResponse = await fetchWithTimeout(
17436
- `${TONAPI_BASE_URL}/rates?tokens=${encodeURIComponent(jetton_address)}&currencies=usd,ton`,
17437
- { headers: tonapiHeaders() }
17427
+ const ratesResponse = await tonapiFetch(
17428
+ `/rates?tokens=${encodeURIComponent(jetton_address)}&currencies=usd,ton`
17438
17429
  );
17439
17430
  const geckoResponse = await fetchWithTimeout(
17440
17431
  `${GECKOTERMINAL_API_URL}/networks/ton/tokens/${jetton_address}`,
17441
17432
  { headers: { Accept: "application/json" } }
17442
17433
  );
17443
- const infoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
17444
- headers: tonapiHeaders()
17445
- });
17434
+ const infoResponse = await tonapiFetch(`/jettons/${jetton_address}`);
17446
17435
  let symbol = "TOKEN";
17447
17436
  let name = "Unknown Token";
17448
17437
  let holdersCount = 0;
@@ -23866,7 +23855,6 @@ var TonnetApp = class {
23866
23855
  initDealsConfig(this.config.deals);
23867
23856
  if (this.config.tonapi_key) {
23868
23857
  setTonapiKey(this.config.tonapi_key);
23869
- console.log("\u{1F511} TonAPI key configured");
23870
23858
  }
23871
23859
  const soul = loadSoul();
23872
23860
  this.toolRegistry = new ToolRegistry();
@@ -23944,7 +23932,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
23944
23932
  `\u26A0\uFE0F Tool count (${this.toolCount}) exceeds ${providerMeta.displayName} limit (${providerMeta.toolLimit})`
23945
23933
  );
23946
23934
  }
23947
- const { migrateSessionsToDb } = await import("./migrate-FGNIC4XZ.js");
23935
+ const { migrateSessionsToDb } = await import("./migrate-F256Q7LW.js");
23948
23936
  migrateSessionsToDb();
23949
23937
  const memory = initializeMemory({
23950
23938
  database: {
@@ -24009,7 +23997,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
24009
23997
  const r3 = db.getDb().prepare(
24010
23998
  `UPDATE deals SET status = 'expired' WHERE status IN ('proposed', 'accepted') AND expires_at < ?`
24011
23999
  ).run(now);
24012
- if (r3.changes > 0) console.log(`\u23F0 Expired ${r3.changes} stale deal(s)`);
24000
+ if (r3.changes > 0) verbose(`\u23F0 Expired ${r3.changes} stale deal(s)`);
24013
24001
  }, DEALS_CONFIG.expiryCheckIntervalMs);
24014
24002
  }
24015
24003
  console.log(`\u2705 SOUL.md loaded`);
@@ -24026,6 +24014,9 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
24026
24014
  }
24027
24015
  console.log(`\u2705 Telegram: @${username} connected`);
24028
24016
  console.log(`\u2705 TON Blockchain: connected`);
24017
+ if (this.config.tonapi_key) {
24018
+ console.log(`\u{1F511} TonAPI key configured`);
24019
+ }
24029
24020
  console.log(`\u2705 DEXs: STON.fi, DeDust connected`);
24030
24021
  console.log(`\u2705 Wallet: ${walletAddress || "not configured"}`);
24031
24022
  console.log(`\u2705 Model: ${provider}/${this.config.agent.model}`);
@@ -24125,7 +24116,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
24125
24116
  const taskId = match[1];
24126
24117
  const { getTaskStore } = await import("./tasks-M3QDPTGY.js");
24127
24118
  const { executeScheduledTask } = await import("./task-executor-MNI4VIZL.js");
24128
- const { getDatabase: getDatabase2 } = await import("./memory-I4QLDRLK.js");
24119
+ const { getDatabase: getDatabase2 } = await import("./memory-Q755V5UK.js");
24129
24120
  const db = getDatabase2().getDb();
24130
24121
  const taskStore = getTaskStore(db);
24131
24122
  const task = taskStore.getTask(taskId);
@@ -24200,7 +24191,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
24200
24191
  try {
24201
24192
  const { getTaskStore } = await import("./tasks-M3QDPTGY.js");
24202
24193
  const { TaskDependencyResolver } = await import("./task-dependency-resolver-CWG6DTU4.js");
24203
- const { getDatabase: getDatabase2 } = await import("./memory-I4QLDRLK.js");
24194
+ const { getDatabase: getDatabase2 } = await import("./memory-Q755V5UK.js");
24204
24195
  const db = getDatabase2().getDb();
24205
24196
  const taskStore = getTaskStore(db);
24206
24197
  const match = message.text.match(/^\[TASK:([^\]]+)\]/);
@@ -0,0 +1,74 @@
1
+ import {
2
+ DEFAULT_FETCH_TIMEOUT_MS
3
+ } from "./chunk-LJXYESJJ.js";
4
+
5
+ // src/utils/fetch.ts
6
+ var DEFAULT_TIMEOUT_MS = DEFAULT_FETCH_TIMEOUT_MS;
7
+ function fetchWithTimeout(url, init) {
8
+ const { timeoutMs = DEFAULT_TIMEOUT_MS, ...fetchInit } = init ?? {};
9
+ if (fetchInit.signal) {
10
+ return fetch(url, fetchInit);
11
+ }
12
+ return fetch(url, {
13
+ ...fetchInit,
14
+ signal: AbortSignal.timeout(timeoutMs)
15
+ });
16
+ }
17
+
18
+ // src/constants/api-endpoints.ts
19
+ var TONAPI_BASE_URL = "https://tonapi.io/v2";
20
+ var _tonapiKey;
21
+ function setTonapiKey(key) {
22
+ _tonapiKey = key;
23
+ }
24
+ function tonapiHeaders() {
25
+ const headers = { Accept: "application/json" };
26
+ if (_tonapiKey) {
27
+ headers["Authorization"] = `Bearer ${_tonapiKey}`;
28
+ }
29
+ return headers;
30
+ }
31
+ var TONAPI_MAX_RPS = 5;
32
+ var _tonapiTimestamps = [];
33
+ async function waitForTonapiSlot() {
34
+ const clean = () => {
35
+ const cutoff = Date.now() - 1e3;
36
+ while (_tonapiTimestamps.length > 0 && _tonapiTimestamps[0] <= cutoff) {
37
+ _tonapiTimestamps.shift();
38
+ }
39
+ };
40
+ clean();
41
+ if (_tonapiTimestamps.length >= TONAPI_MAX_RPS) {
42
+ const waitMs = _tonapiTimestamps[0] + 1e3 - Date.now() + 50;
43
+ if (waitMs > 0) await new Promise((r) => setTimeout(r, waitMs));
44
+ clean();
45
+ }
46
+ _tonapiTimestamps.push(Date.now());
47
+ }
48
+ async function tonapiFetch(path, init) {
49
+ await waitForTonapiSlot();
50
+ return fetchWithTimeout(`${TONAPI_BASE_URL}${path}`, {
51
+ ...init,
52
+ headers: { ...tonapiHeaders(), ...init?.headers }
53
+ });
54
+ }
55
+ var STONFI_API_BASE_URL = "https://api.ston.fi/v1";
56
+ var GECKOTERMINAL_API_URL = "https://api.geckoterminal.com/api/v2";
57
+ var COINGECKO_API_URL = "https://api.coingecko.com/api/v3";
58
+ var MARKETAPP_BASE_URL = "https://marketapp.ws";
59
+ var OPENAI_TTS_URL = "https://api.openai.com/v1/audio/speech";
60
+ var ELEVENLABS_TTS_URL = "https://api.elevenlabs.io/v1/text-to-speech";
61
+ var VOYAGE_API_URL = "https://api.voyageai.com/v1";
62
+
63
+ export {
64
+ fetchWithTimeout,
65
+ setTonapiKey,
66
+ tonapiFetch,
67
+ STONFI_API_BASE_URL,
68
+ GECKOTERMINAL_API_URL,
69
+ COINGECKO_API_URL,
70
+ MARKETAPP_BASE_URL,
71
+ OPENAI_TTS_URL,
72
+ ELEVENLABS_TTS_URL,
73
+ VOYAGE_API_URL
74
+ };
package/dist/cli/index.js CHANGED
@@ -17,15 +17,15 @@ import {
17
17
  saveWallet,
18
18
  validateApiKeyFormat,
19
19
  walletExists
20
- } from "../chunk-UQ54EXWQ.js";
21
- import {
22
- fetchWithTimeout
23
- } from "../chunk-PMX75DTX.js";
20
+ } from "../chunk-Q4N5NJ2B.js";
21
+ import "../chunk-JDPS46IZ.js";
24
22
  import "../chunk-E2NXSWOS.js";
25
23
  import {
26
24
  TELETON_ROOT
27
25
  } from "../chunk-EYWNOHMJ.js";
28
- import "../chunk-ST5CO7TV.js";
26
+ import {
27
+ fetchWithTimeout
28
+ } from "../chunk-WMIN6AGX.js";
29
29
  import {
30
30
  TELEGRAM_MAX_MESSAGE_LENGTH
31
31
  } from "../chunk-QMN6ZOA5.js";
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  TonnetApp,
3
3
  main
4
- } from "./chunk-UQ54EXWQ.js";
5
- import "./chunk-PMX75DTX.js";
4
+ } from "./chunk-Q4N5NJ2B.js";
5
+ import "./chunk-JDPS46IZ.js";
6
6
  import "./chunk-E2NXSWOS.js";
7
7
  import "./chunk-EYWNOHMJ.js";
8
- import "./chunk-ST5CO7TV.js";
8
+ import "./chunk-WMIN6AGX.js";
9
9
  import "./chunk-QMN6ZOA5.js";
10
10
  import "./chunk-LJXYESJJ.js";
11
11
  import "./chunk-B2PRMXOH.js";
@@ -24,12 +24,12 @@ import {
24
24
  runMigrations,
25
25
  serializeEmbedding,
26
26
  setSchemaVersion
27
- } from "./chunk-PMX75DTX.js";
27
+ } from "./chunk-JDPS46IZ.js";
28
28
  import {
29
29
  TaskStore,
30
30
  getTaskStore
31
31
  } from "./chunk-E2NXSWOS.js";
32
- import "./chunk-ST5CO7TV.js";
32
+ import "./chunk-WMIN6AGX.js";
33
33
  import "./chunk-QMN6ZOA5.js";
34
34
  import "./chunk-LJXYESJJ.js";
35
35
  import "./chunk-QGM4M3NI.js";
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  getDatabase
3
- } from "./chunk-PMX75DTX.js";
3
+ } from "./chunk-JDPS46IZ.js";
4
4
  import "./chunk-E2NXSWOS.js";
5
5
  import {
6
6
  TELETON_ROOT
7
7
  } from "./chunk-EYWNOHMJ.js";
8
- import "./chunk-ST5CO7TV.js";
8
+ import "./chunk-WMIN6AGX.js";
9
9
  import "./chunk-QMN6ZOA5.js";
10
10
  import "./chunk-LJXYESJJ.js";
11
11
  import "./chunk-QGM4M3NI.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-EYWNOHMJ.js";
4
4
  import {
5
5
  MARKETAPP_BASE_URL
6
- } from "./chunk-ST5CO7TV.js";
6
+ } from "./chunk-WMIN6AGX.js";
7
7
  import {
8
8
  SCRAPER_PARALLEL_WORKERS
9
9
  } from "./chunk-QMN6ZOA5.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teleton",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "description": "Personal AI Agent for Telegram",
5
5
  "author": "ZKProof (https://t.me/zkproof)",
6
6
  "license": "MIT",
@@ -1,33 +0,0 @@
1
- // src/constants/api-endpoints.ts
2
- var TONAPI_BASE_URL = "https://tonapi.io/v2";
3
- var _tonapiKey;
4
- function setTonapiKey(key) {
5
- _tonapiKey = key;
6
- }
7
- function tonapiHeaders() {
8
- const headers = { Accept: "application/json" };
9
- if (_tonapiKey) {
10
- headers["Authorization"] = `Bearer ${_tonapiKey}`;
11
- }
12
- return headers;
13
- }
14
- var STONFI_API_BASE_URL = "https://api.ston.fi/v1";
15
- var GECKOTERMINAL_API_URL = "https://api.geckoterminal.com/api/v2";
16
- var COINGECKO_API_URL = "https://api.coingecko.com/api/v3";
17
- var MARKETAPP_BASE_URL = "https://marketapp.ws";
18
- var OPENAI_TTS_URL = "https://api.openai.com/v1/audio/speech";
19
- var ELEVENLABS_TTS_URL = "https://api.elevenlabs.io/v1/text-to-speech";
20
- var VOYAGE_API_URL = "https://api.voyageai.com/v1";
21
-
22
- export {
23
- TONAPI_BASE_URL,
24
- setTonapiKey,
25
- tonapiHeaders,
26
- STONFI_API_BASE_URL,
27
- GECKOTERMINAL_API_URL,
28
- COINGECKO_API_URL,
29
- MARKETAPP_BASE_URL,
30
- OPENAI_TTS_URL,
31
- ELEVENLABS_TTS_URL,
32
- VOYAGE_API_URL
33
- };