teleton 0.1.19 → 0.1.21

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,3 +1,19 @@
1
+ import {
2
+ Mi,
3
+ Mn,
4
+ br,
5
+ dt,
6
+ le,
7
+ qn,
8
+ ut,
9
+ ye
10
+ } from "./chunk-U7FQYCBQ.js";
11
+ import {
12
+ appendToTranscript,
13
+ archiveTranscript,
14
+ readTranscript,
15
+ transcriptExists
16
+ } from "./chunk-OQGNS2FV.js";
1
17
  import {
2
18
  ChatStore,
3
19
  ContextBuilder,
@@ -5,7 +21,7 @@ import {
5
21
  UserStore,
6
22
  getDatabase,
7
23
  initializeMemory
8
- } from "./chunk-JDPS46IZ.js";
24
+ } from "./chunk-Y5X6KZX5.js";
9
25
  import {
10
26
  ALLOWED_EXTENSIONS,
11
27
  MAX_FILE_SIZES,
@@ -62,16 +78,6 @@ import {
62
78
  telegramGetMyGiftsExecutor,
63
79
  telegramGetMyGiftsTool
64
80
  } from "./chunk-B2PRMXOH.js";
65
- import {
66
- Mi,
67
- Mn,
68
- br,
69
- dt,
70
- le,
71
- qn,
72
- ut,
73
- ye
74
- } from "./chunk-U7FQYCBQ.js";
75
81
  import {
76
82
  __commonJS,
77
83
  __toESM
@@ -1398,9 +1404,6 @@ var CasinoConfigSchema = z.object({
1398
1404
  max_bet_percent: z.number().default(5),
1399
1405
  min_bankroll: z.number().default(10),
1400
1406
  cooldown_seconds: z.number().default(30),
1401
- house_edge_percent: z.number().default(5),
1402
- jackpot_threshold: z.number().default(100),
1403
- jackpot_cooldown_hours: z.number().default(24),
1404
1407
  payment_window_minutes: z.number().default(5),
1405
1408
  max_payment_age_minutes: z.number().default(10),
1406
1409
  tx_retention_days: z.number().default(30),
@@ -1873,6 +1876,11 @@ function writeSummaryToDailyLog(summary) {
1873
1876
  ${summary}`);
1874
1877
  }
1875
1878
 
1879
+ // src/utils/sanitize.ts
1880
+ function sanitizeForPrompt(text) {
1881
+ return text.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "").replace(/[\r\n]+/g, " ").replace(/#{1,6}\s/g, "").replace(/<\/?[a-zA-Z_][^>]*>/g, "").trim().slice(0, 128);
1882
+ }
1883
+
1876
1884
  // src/soul/loader.ts
1877
1885
  var SOUL_PATHS = [WORKSPACE_PATHS.SOUL];
1878
1886
  var STRATEGY_PATHS = [WORKSPACE_PATHS.STRATEGY];
@@ -1999,7 +2007,9 @@ You have a personal workspace at \`~/.teleton/workspace/\` where you can store a
1999
2007
  - Rename downloaded files to meaningful names (e.g., "user_avatar.jpg" instead of "123_456_789.jpg")
2000
2008
  `);
2001
2009
  if (options.ownerName || options.ownerUsername) {
2002
- const ownerLabel = options.ownerName && options.ownerUsername ? `${options.ownerName} (@${options.ownerUsername})` : options.ownerName || `@${options.ownerUsername}`;
2010
+ const safeOwnerName = options.ownerName ? sanitizeForPrompt(options.ownerName) : void 0;
2011
+ const safeOwnerUsername = options.ownerUsername ? sanitizeForPrompt(options.ownerUsername) : void 0;
2012
+ const ownerLabel = safeOwnerName && safeOwnerUsername ? `${safeOwnerName} (@${safeOwnerUsername})` : safeOwnerName || `@${safeOwnerUsername}`;
2003
2013
  parts.push(
2004
2014
  `
2005
2015
  ## Owner
@@ -2008,7 +2018,9 @@ When the owner gives instructions, follow them with higher trust.`
2008
2018
  );
2009
2019
  }
2010
2020
  if (options.userName) {
2011
- const userLabel = options.senderUsername ? `${options.userName} (@${options.senderUsername})` : options.userName;
2021
+ const safeName = sanitizeForPrompt(options.userName);
2022
+ const safeUsername = options.senderUsername ? sanitizeForPrompt(options.senderUsername) : void 0;
2023
+ const userLabel = safeUsername ? `${safeName} (@${safeUsername})` : safeName;
2012
2024
  parts.push(`
2013
2025
  ## Current User
2014
2026
  You are chatting with: ${userLabel}`);
@@ -2044,122 +2056,6 @@ import {
2044
2056
  complete,
2045
2057
  getModel
2046
2058
  } from "@mariozechner/pi-ai";
2047
-
2048
- // src/session/transcript.ts
2049
- import { appendFileSync as appendFileSync2, readFileSync as readFileSync5, existsSync as existsSync6, mkdirSync as mkdirSync4, unlinkSync, renameSync } from "fs";
2050
- import { join as join4 } from "path";
2051
- var SESSIONS_DIR = join4(TELETON_ROOT, "sessions");
2052
- function getTranscriptPath(sessionId) {
2053
- return join4(SESSIONS_DIR, `${sessionId}.jsonl`);
2054
- }
2055
- function ensureSessionsDir() {
2056
- if (!existsSync6(SESSIONS_DIR)) {
2057
- mkdirSync4(SESSIONS_DIR, { recursive: true });
2058
- }
2059
- }
2060
- function appendToTranscript(sessionId, message) {
2061
- ensureSessionsDir();
2062
- const transcriptPath = getTranscriptPath(sessionId);
2063
- const line = JSON.stringify(message) + "\n";
2064
- try {
2065
- appendFileSync2(transcriptPath, line, "utf-8");
2066
- } catch (error) {
2067
- console.error(`Failed to append to transcript ${sessionId}:`, error);
2068
- }
2069
- }
2070
- function extractToolCallIds(msg) {
2071
- const ids = /* @__PURE__ */ new Set();
2072
- if (msg.role === "assistant" && Array.isArray(msg.content)) {
2073
- for (const block of msg.content) {
2074
- const blockType = block.type;
2075
- if (blockType === "toolCall" || blockType === "tool_use") {
2076
- const id = block.id || block.toolCallId || block.tool_use_id;
2077
- if (id) ids.add(id);
2078
- }
2079
- }
2080
- }
2081
- return ids;
2082
- }
2083
- function sanitizeMessages(messages) {
2084
- const sanitized = [];
2085
- let pendingToolCallIds = /* @__PURE__ */ new Set();
2086
- let removedCount = 0;
2087
- for (let i = 0; i < messages.length; i++) {
2088
- const msg = messages[i];
2089
- if (msg.role === "assistant") {
2090
- const newToolIds = extractToolCallIds(msg);
2091
- if (pendingToolCallIds.size > 0 && newToolIds.size > 0) {
2092
- console.warn(
2093
- `\u26A0\uFE0F Found ${pendingToolCallIds.size} pending tool results that were never received`
2094
- );
2095
- }
2096
- pendingToolCallIds = newToolIds;
2097
- sanitized.push(msg);
2098
- } else if (msg.role === "toolResult" || msg.role === "tool_result") {
2099
- const toolCallId = msg.toolCallId || msg.tool_use_id || msg.tool_call_id;
2100
- if (toolCallId && pendingToolCallIds.has(toolCallId)) {
2101
- pendingToolCallIds.delete(toolCallId);
2102
- sanitized.push(msg);
2103
- } else {
2104
- removedCount++;
2105
- console.warn(
2106
- `\u{1F9F9} Removing out-of-order/orphaned toolResult: ${toolCallId?.slice(0, 20)}...`
2107
- );
2108
- continue;
2109
- }
2110
- } else if (msg.role === "user") {
2111
- if (pendingToolCallIds.size > 0) {
2112
- console.warn(
2113
- `\u26A0\uFE0F User message arrived while ${pendingToolCallIds.size} tool results pending - marking them as orphaned`
2114
- );
2115
- pendingToolCallIds.clear();
2116
- }
2117
- sanitized.push(msg);
2118
- } else {
2119
- sanitized.push(msg);
2120
- }
2121
- }
2122
- if (removedCount > 0) {
2123
- console.log(`\u{1F9F9} Sanitized ${removedCount} orphaned/out-of-order toolResult(s) from transcript`);
2124
- }
2125
- return sanitized;
2126
- }
2127
- function readTranscript(sessionId) {
2128
- const transcriptPath = getTranscriptPath(sessionId);
2129
- if (!existsSync6(transcriptPath)) {
2130
- return [];
2131
- }
2132
- try {
2133
- const content = readFileSync5(transcriptPath, "utf-8");
2134
- const lines = content.trim().split("\n").filter(Boolean);
2135
- const messages = lines.map((line) => JSON.parse(line));
2136
- return sanitizeMessages(messages);
2137
- } catch (error) {
2138
- console.error(`Failed to read transcript ${sessionId}:`, error);
2139
- return [];
2140
- }
2141
- }
2142
- function transcriptExists(sessionId) {
2143
- return existsSync6(getTranscriptPath(sessionId));
2144
- }
2145
- function archiveTranscript(sessionId) {
2146
- const transcriptPath = getTranscriptPath(sessionId);
2147
- const timestamp = Date.now();
2148
- const archivePath = `${transcriptPath}.${timestamp}.archived`;
2149
- if (!existsSync6(transcriptPath)) {
2150
- return false;
2151
- }
2152
- try {
2153
- renameSync(transcriptPath, archivePath);
2154
- console.log(`\u{1F4E6} Archived transcript: ${sessionId} \u2192 ${timestamp}.archived`);
2155
- return true;
2156
- } catch (error) {
2157
- console.error(`Failed to archive transcript ${sessionId}:`, error);
2158
- return false;
2159
- }
2160
- }
2161
-
2162
- // src/agent/client.ts
2163
2059
  var modelCache = /* @__PURE__ */ new Map();
2164
2060
  function getProviderModel(provider, modelId) {
2165
2061
  const cacheKey = `${provider}:${modelId}`;
@@ -2266,10 +2162,10 @@ function formatTimestamp(timestamp) {
2266
2162
  function buildSenderLabel(params) {
2267
2163
  const parts = [];
2268
2164
  if (params.senderName) {
2269
- parts.push(params.senderName);
2165
+ parts.push(sanitizeForPrompt(params.senderName));
2270
2166
  }
2271
2167
  if (params.senderUsername) {
2272
- parts.push(`@${params.senderUsername}`);
2168
+ parts.push(`@${sanitizeForPrompt(params.senderUsername)}`);
2273
2169
  }
2274
2170
  if (parts.length > 0) {
2275
2171
  return parts.length === 2 ? `${parts[0]} (${parts[1]})` : parts[0];
@@ -2295,7 +2191,8 @@ function formatMessageEnvelope(params) {
2295
2191
  const ts = formatTimestamp(params.timestamp);
2296
2192
  parts.push(ts);
2297
2193
  const header = `[${parts.join(" ")}]`;
2298
- let body = params.isGroup ? `${senderLabel}: ${params.body}` : params.body;
2194
+ const safeBody = params.body.replace(/<\/?user_message>/gi, "");
2195
+ let body = params.isGroup ? `${senderLabel}: <user_message>${safeBody}</user_message>` : `<user_message>${safeBody}</user_message>`;
2299
2196
  if (params.hasMedia && params.mediaType) {
2300
2197
  const mediaEmoji = {
2301
2198
  photo: "\u{1F4F7}",
@@ -2789,7 +2686,7 @@ ${oversizedNotes.join("\n")}` : "";
2789
2686
 
2790
2687
  // src/session/memory-hook.ts
2791
2688
  import { writeFile, mkdir } from "fs/promises";
2792
- import { join as join5 } from "path";
2689
+ import { join as join4 } from "path";
2793
2690
  import { complete as complete3 } from "@mariozechner/pi-ai";
2794
2691
  async function generateSlugViaClaude(params) {
2795
2692
  const provider = params.provider || "anthropic";
@@ -2830,7 +2727,7 @@ Slug:`,
2830
2727
  async function saveSessionMemory(params) {
2831
2728
  try {
2832
2729
  const { TELETON_ROOT: TELETON_ROOT2 } = await import("./paths-TMNTEDDD.js");
2833
- const memoryDir = join5(TELETON_ROOT2, "memory");
2730
+ const memoryDir = join4(TELETON_ROOT2, "memory");
2834
2731
  await mkdir(memoryDir, { recursive: true });
2835
2732
  const now = /* @__PURE__ */ new Date();
2836
2733
  const dateStr = now.toISOString().split("T")[0];
@@ -2842,7 +2739,7 @@ async function saveSessionMemory(params) {
2842
2739
  utilityModel: params.utilityModel
2843
2740
  });
2844
2741
  const filename = `${dateStr}-${slug}.md`;
2845
- const filepath = join5(memoryDir, filename);
2742
+ const filepath = join4(memoryDir, filename);
2846
2743
  const timeStr = now.toISOString().split("T")[1].split(".")[0];
2847
2744
  console.log("\u{1F4DD} Generating session summary...");
2848
2745
  let summary;
@@ -3430,7 +3327,7 @@ ${statsContext}`;
3430
3327
  const providerMeta = getProviderMetadata(
3431
3328
  this.config.agent.provider || "anthropic"
3432
3329
  );
3433
- const tools = this.toolRegistry?.getForProvider(providerMeta.toolLimit);
3330
+ const tools = this.toolRegistry?.getForContext(isGroup ?? false, providerMeta.toolLimit);
3434
3331
  const maxIterations = this.config.agent.max_agentic_iterations || 5;
3435
3332
  let iteration = 0;
3436
3333
  let overflowResets = 0;
@@ -3645,23 +3542,23 @@ ${statsContext}`;
3645
3542
  */
3646
3543
  clearHistory(chatId) {
3647
3544
  const db = getDatabase().getDb();
3648
- db.prepare(`DELETE FROM tg_messages WHERE chat_id = ?`).run(chatId);
3649
3545
  db.prepare(
3650
3546
  `
3651
- DELETE FROM tg_messages_vec
3652
- WHERE id IN (
3653
- SELECT id FROM tg_messages WHERE chat_id = ?
3547
+ DELETE FROM tg_messages_fts
3548
+ WHERE rowid IN (
3549
+ SELECT rowid FROM tg_messages WHERE chat_id = ?
3654
3550
  )
3655
3551
  `
3656
3552
  ).run(chatId);
3657
3553
  db.prepare(
3658
3554
  `
3659
- DELETE FROM tg_messages_fts
3660
- WHERE rowid IN (
3661
- SELECT rowid FROM tg_messages WHERE chat_id = ?
3555
+ DELETE FROM tg_messages_vec
3556
+ WHERE id IN (
3557
+ SELECT id FROM tg_messages WHERE chat_id = ?
3662
3558
  )
3663
3559
  `
3664
3560
  ).run(chatId);
3561
+ db.prepare(`DELETE FROM tg_messages WHERE chat_id = ?`).run(chatId);
3665
3562
  resetSession(chatId);
3666
3563
  console.log(`\u{1F5D1}\uFE0F Cleared history for chat ${chatId}`);
3667
3564
  }
@@ -3722,8 +3619,8 @@ import { TelegramClient, Api } from "telegram";
3722
3619
  import { Logger, LogLevel } from "telegram/extensions/Logger.js";
3723
3620
  import { StringSession } from "telegram/sessions/index.js";
3724
3621
  import { NewMessage } from "telegram/events/index.js";
3725
- import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync3, mkdirSync as mkdirSync5, chmodSync } from "fs";
3726
- import { dirname as dirname4 } from "path";
3622
+ import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, chmodSync } from "fs";
3623
+ import { dirname as dirname3 } from "path";
3727
3624
  import { createInterface } from "readline";
3728
3625
 
3729
3626
  // src/telegram/formatting.ts
@@ -3755,7 +3652,7 @@ function markdownToTelegramHtml(markdown) {
3755
3652
  html = html.replace(listPattern, (match) => {
3756
3653
  const index = blockquotes.length;
3757
3654
  const lineCount = match.split("\n").length;
3758
- const content = match.replace(/\|\|([^|]+)\|\|/g, "<tg-spoiler>$1</tg-spoiler>").replace(/\*\*([^*]+)\*\*/g, "<b>$1</b>").replace(/__([^_]+)__/g, "<b>$1</b>").replace(/~~([^~]+)~~/g, "<s>$1</s>").replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, "<i>$1</i>").replace(/(?<!_)_([^_]+)_(?!_)/g, "<i>$1</i>").replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
3655
+ const content = escapeHtml(match).replace(/\|\|([^|]+)\|\|/g, "<tg-spoiler>$1</tg-spoiler>").replace(/\*\*([^*]+)\*\*/g, "<b>$1</b>").replace(/__([^_]+)__/g, "<b>$1</b>").replace(/~~([^~]+)~~/g, "<s>$1</s>").replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, "<i>$1</i>").replace(/(?<!_)_([^_]+)_(?!_)/g, "<i>$1</i>").replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
3759
3656
  const tag = lineCount >= 15 ? "<blockquote expandable>" : "<blockquote>";
3760
3657
  blockquotes.push(`${tag}${content}</blockquote>`);
3761
3658
  return `\0BLOCKQUOTE${index}\0`;
@@ -3763,12 +3660,15 @@ function markdownToTelegramHtml(markdown) {
3763
3660
  html = html.replace(/^(>.*(?:\n>.*)*)/gm, (match) => {
3764
3661
  const index = blockquotes.length;
3765
3662
  const lineCount = match.split("\n").length;
3766
- let content = match.split("\n").map((line) => line.replace(/^>\s?/, "")).join("\n");
3663
+ let content = escapeHtml(
3664
+ match.split("\n").map((line) => line.replace(/^>\s?/, "")).join("\n")
3665
+ );
3767
3666
  content = content.replace(/\|\|([^|]+)\|\|/g, "<tg-spoiler>$1</tg-spoiler>").replace(/\*\*([^*]+)\*\*/g, "<b>$1</b>").replace(/__([^_]+)__/g, "<b>$1</b>").replace(/~~([^~]+)~~/g, "<s>$1</s>").replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, "<i>$1</i>").replace(/(?<!_)_([^_]+)_(?!_)/g, "<i>$1</i>").replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
3768
3667
  const tag = lineCount >= 15 ? "<blockquote expandable>" : "<blockquote>";
3769
3668
  blockquotes.push(`${tag}${content}</blockquote>`);
3770
3669
  return `\0BLOCKQUOTE${index}\0`;
3771
3670
  });
3671
+ html = escapeHtml(html);
3772
3672
  html = html.replace(/\|\|([^|]+)\|\|/g, "<tg-spoiler>$1</tg-spoiler>");
3773
3673
  html = html.replace(/\*\*([^*]+)\*\*/g, "<b>$1</b>");
3774
3674
  html = html.replace(/__([^_]+)__/g, "<b>$1</b>");
@@ -3821,8 +3721,8 @@ var TelegramUserClient = class {
3821
3721
  */
3822
3722
  loadSession() {
3823
3723
  try {
3824
- if (existsSync7(this.config.sessionPath)) {
3825
- return readFileSync6(this.config.sessionPath, "utf-8").trim();
3724
+ if (existsSync6(this.config.sessionPath)) {
3725
+ return readFileSync5(this.config.sessionPath, "utf-8").trim();
3826
3726
  }
3827
3727
  } catch (error) {
3828
3728
  console.warn("Failed to load session:", error);
@@ -3839,9 +3739,9 @@ var TelegramUserClient = class {
3839
3739
  console.warn("No session string to save");
3840
3740
  return;
3841
3741
  }
3842
- const dir = dirname4(this.config.sessionPath);
3843
- if (!existsSync7(dir)) {
3844
- mkdirSync5(dir, { recursive: true });
3742
+ const dir = dirname3(this.config.sessionPath);
3743
+ if (!existsSync6(dir)) {
3744
+ mkdirSync4(dir, { recursive: true });
3845
3745
  }
3846
3746
  writeFileSync3(this.config.sessionPath, sessionString, { encoding: "utf-8" });
3847
3747
  chmodSync(this.config.sessionPath, 384);
@@ -3859,7 +3759,7 @@ var TelegramUserClient = class {
3859
3759
  return;
3860
3760
  }
3861
3761
  try {
3862
- const hasSession = existsSync7(this.config.sessionPath);
3762
+ const hasSession = existsSync6(this.config.sessionPath);
3863
3763
  if (hasSession) {
3864
3764
  await this.client.connect();
3865
3765
  } else {
@@ -4352,20 +4252,20 @@ var TelegramBridge = class {
4352
4252
  };
4353
4253
 
4354
4254
  // src/telegram/offset-store.ts
4355
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync4, existsSync as existsSync8, mkdirSync as mkdirSync6 } from "fs";
4356
- import { dirname as dirname5 } from "path";
4357
- import { join as join6 } from "path";
4358
- var OFFSET_FILE = join6(TELETON_ROOT, "telegram-offset.json");
4255
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync7, mkdirSync as mkdirSync5 } from "fs";
4256
+ import { dirname as dirname4 } from "path";
4257
+ import { join as join5 } from "path";
4258
+ var OFFSET_FILE = join5(TELETON_ROOT, "telegram-offset.json");
4359
4259
  var STORE_VERSION = 2;
4360
4260
  var offsetCache = null;
4361
4261
  function loadState() {
4362
4262
  if (offsetCache) return offsetCache;
4363
4263
  try {
4364
- if (!existsSync8(OFFSET_FILE)) {
4264
+ if (!existsSync7(OFFSET_FILE)) {
4365
4265
  offsetCache = { version: STORE_VERSION, perChat: {} };
4366
4266
  return offsetCache;
4367
4267
  }
4368
- const raw = readFileSync7(OFFSET_FILE, "utf-8");
4268
+ const raw = readFileSync6(OFFSET_FILE, "utf-8");
4369
4269
  const state = JSON.parse(raw);
4370
4270
  if (state.version === 1 || !state.perChat) {
4371
4271
  offsetCache = { version: STORE_VERSION, perChat: {} };
@@ -4381,9 +4281,9 @@ function loadState() {
4381
4281
  }
4382
4282
  function saveState(state) {
4383
4283
  try {
4384
- const dir = dirname5(OFFSET_FILE);
4385
- if (!existsSync8(dir)) {
4386
- mkdirSync6(dir, { recursive: true });
4284
+ const dir = dirname4(OFFSET_FILE);
4285
+ if (!existsSync7(dir)) {
4286
+ mkdirSync5(dir, { recursive: true });
4387
4287
  }
4388
4288
  writeFileSync4(OFFSET_FILE, JSON.stringify(state, null, 2), "utf-8");
4389
4289
  offsetCache = state;
@@ -4446,15 +4346,16 @@ var PendingHistory = class _PendingHistory {
4446
4346
  const lines = pending.map((msg) => {
4447
4347
  let senderLabel;
4448
4348
  if (msg.senderName && msg.senderUsername) {
4449
- senderLabel = `${msg.senderName} (@${msg.senderUsername})`;
4349
+ senderLabel = `${sanitizeForPrompt(msg.senderName)} (@${sanitizeForPrompt(msg.senderUsername)})`;
4450
4350
  } else if (msg.senderName) {
4451
- senderLabel = msg.senderName;
4351
+ senderLabel = sanitizeForPrompt(msg.senderName);
4452
4352
  } else if (msg.senderUsername) {
4453
- senderLabel = `@${msg.senderUsername}`;
4353
+ senderLabel = `@${sanitizeForPrompt(msg.senderUsername)}`;
4454
4354
  } else {
4455
4355
  senderLabel = `User:${msg.senderId}`;
4456
4356
  }
4457
- return `${senderLabel}: ${msg.text}`;
4357
+ const safeText = msg.text.replace(/<\/?user_message>/gi, "");
4358
+ return `${senderLabel}: <user_message>${safeText}</user_message>`;
4458
4359
  });
4459
4360
  this.pendingMessages.delete(chatId);
4460
4361
  return `[Chat messages since your last reply]
@@ -4838,10 +4739,10 @@ var MessageHandler = class {
4838
4739
  // src/ton/wallet-service.ts
4839
4740
  import { mnemonicNew, mnemonicToPrivateKey, mnemonicValidate } from "@ton/crypto";
4840
4741
  import { WalletContractV5R1, TonClient, fromNano } from "@ton/ton";
4841
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, existsSync as existsSync9, mkdirSync as mkdirSync7, chmodSync as chmodSync2 } from "fs";
4842
- import { join as join7, dirname as dirname6 } from "path";
4742
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync8, mkdirSync as mkdirSync6, chmodSync as chmodSync2 } from "fs";
4743
+ import { join as join6, dirname as dirname5 } from "path";
4843
4744
  import { getHttpEndpoint } from "@orbs-network/ton-access";
4844
- var WALLET_FILE = join7(TELETON_ROOT, "wallet.json");
4745
+ var WALLET_FILE = join6(TELETON_ROOT, "wallet.json");
4845
4746
  async function generateWallet() {
4846
4747
  const mnemonic = await mnemonicNew(24);
4847
4748
  const keyPair = await mnemonicToPrivateKey(mnemonic);
@@ -4859,19 +4760,19 @@ async function generateWallet() {
4859
4760
  };
4860
4761
  }
4861
4762
  function saveWallet(wallet) {
4862
- const dir = dirname6(WALLET_FILE);
4863
- if (!existsSync9(dir)) {
4864
- mkdirSync7(dir, { recursive: true });
4763
+ const dir = dirname5(WALLET_FILE);
4764
+ if (!existsSync8(dir)) {
4765
+ mkdirSync6(dir, { recursive: true });
4865
4766
  }
4866
4767
  writeFileSync5(WALLET_FILE, JSON.stringify(wallet, null, 2), "utf-8");
4867
4768
  chmodSync2(WALLET_FILE, 384);
4868
4769
  }
4869
4770
  function loadWallet() {
4870
- if (!existsSync9(WALLET_FILE)) {
4771
+ if (!existsSync8(WALLET_FILE)) {
4871
4772
  return null;
4872
4773
  }
4873
4774
  try {
4874
- const content = readFileSync8(WALLET_FILE, "utf-8");
4775
+ const content = readFileSync7(WALLET_FILE, "utf-8");
4875
4776
  return JSON.parse(content);
4876
4777
  } catch (error) {
4877
4778
  console.error("Failed to load wallet:", error);
@@ -4879,7 +4780,7 @@ function loadWallet() {
4879
4780
  }
4880
4781
  }
4881
4782
  function walletExists() {
4882
- return existsSync9(WALLET_FILE);
4783
+ return existsSync8(WALLET_FILE);
4883
4784
  }
4884
4785
  async function importWallet(mnemonic) {
4885
4786
  const valid = await mnemonicValidate(mnemonic);
@@ -4908,8 +4809,8 @@ async function getWalletBalance(address4) {
4908
4809
  try {
4909
4810
  const endpoint = await getHttpEndpoint({ network: "mainnet" });
4910
4811
  const client = new TonClient({ endpoint });
4911
- const { Address: Address20 } = await import("@ton/core");
4912
- const addressObj = Address20.parse(address4);
4812
+ const { Address: Address19 } = await import("@ton/core");
4813
+ const addressObj = Address19.parse(address4);
4913
4814
  const balance = await client.getBalance(addressObj);
4914
4815
  const balanceFormatted = fromNano(balance);
4915
4816
  return {
@@ -4921,14 +4822,20 @@ async function getWalletBalance(address4) {
4921
4822
  return null;
4922
4823
  }
4923
4824
  }
4825
+ var TON_PRICE_CACHE_TTL_MS = 3e4;
4826
+ var _tonPriceCache = null;
4924
4827
  async function getTonPrice() {
4828
+ if (_tonPriceCache && Date.now() - _tonPriceCache.timestamp < TON_PRICE_CACHE_TTL_MS) {
4829
+ return { ..._tonPriceCache };
4830
+ }
4925
4831
  try {
4926
4832
  const response = await tonapiFetch(`/rates?tokens=ton&currencies=usd`);
4927
4833
  if (response.ok) {
4928
4834
  const data = await response.json();
4929
4835
  const price = data?.rates?.TON?.prices?.USD;
4930
4836
  if (typeof price === "number" && price > 0) {
4931
- return { usd: price, source: "TonAPI", timestamp: Date.now() };
4837
+ _tonPriceCache = { usd: price, source: "TonAPI", timestamp: Date.now() };
4838
+ return _tonPriceCache;
4932
4839
  }
4933
4840
  }
4934
4841
  } catch {
@@ -4943,7 +4850,8 @@ async function getTonPrice() {
4943
4850
  const data = await response.json();
4944
4851
  const price = data["the-open-network"]?.usd;
4945
4852
  if (typeof price === "number" && price > 0) {
4946
- return { usd: price, source: "CoinGecko", timestamp: Date.now() };
4853
+ _tonPriceCache = { usd: price, source: "CoinGecko", timestamp: Date.now() };
4854
+ return _tonPriceCache;
4947
4855
  }
4948
4856
  } catch (error) {
4949
4857
  console.error("Failed to get TON price:", error);
@@ -5445,8 +5353,8 @@ var MessageDebouncer = class {
5445
5353
 
5446
5354
  // src/market/db.ts
5447
5355
  import Database from "better-sqlite3";
5448
- import { join as join8 } from "path";
5449
- var DB_PATH = join8(TELETON_ROOT, "gifts.db");
5356
+ import { join as join7 } from "path";
5357
+ var DB_PATH = join7(TELETON_ROOT, "gifts.db");
5450
5358
  function getDb2() {
5451
5359
  const db = new Database(DB_PATH);
5452
5360
  db.pragma("journal_mode = WAL");
@@ -5765,20 +5673,24 @@ var MarketPriceService = class {
5765
5673
  };
5766
5674
 
5767
5675
  // src/index.ts
5768
- import { join as join15 } from "path";
5676
+ import { join as join14 } from "path";
5769
5677
 
5770
5678
  // src/agent/tools/registry.ts
5771
5679
  import { validateToolCall } from "@mariozechner/pi-ai";
5772
5680
  var ToolRegistry = class {
5773
5681
  tools = /* @__PURE__ */ new Map();
5682
+ scopes = /* @__PURE__ */ new Map();
5774
5683
  /**
5775
- * Register a new tool
5684
+ * Register a new tool with optional scope
5776
5685
  */
5777
- register(tool, executor) {
5686
+ register(tool, executor, scope) {
5778
5687
  if (this.tools.has(tool.name)) {
5779
5688
  throw new Error(`Tool "${tool.name}" is already registered`);
5780
5689
  }
5781
5690
  this.tools.set(tool.name, { tool, executor });
5691
+ if (scope && scope !== "always") {
5692
+ this.scopes.set(tool.name, scope);
5693
+ }
5782
5694
  }
5783
5695
  /**
5784
5696
  * Get all registered tools for pi-ai
@@ -5797,6 +5709,19 @@ var ToolRegistry = class {
5797
5709
  error: `Unknown tool: ${toolCall.name}`
5798
5710
  };
5799
5711
  }
5712
+ const scope = this.scopes.get(toolCall.name);
5713
+ if (scope === "dm-only" && context.isGroup) {
5714
+ return {
5715
+ success: false,
5716
+ error: `Tool "${toolCall.name}" is not available in group chats`
5717
+ };
5718
+ }
5719
+ if (scope === "group-only" && !context.isGroup) {
5720
+ return {
5721
+ success: false,
5722
+ error: `Tool "${toolCall.name}" is only available in group chats`
5723
+ };
5724
+ }
5800
5725
  try {
5801
5726
  const validatedArgs = validateToolCall(this.getAll(), toolCall);
5802
5727
  const result = await registered.executor(validatedArgs, context);
@@ -5822,6 +5747,22 @@ var ToolRegistry = class {
5822
5747
  );
5823
5748
  return all.slice(0, toolLimit);
5824
5749
  }
5750
+ /**
5751
+ * Get tools filtered by chat context (DM vs group) and provider limit.
5752
+ * - In groups: excludes "dm-only" tools (financial, private)
5753
+ * - In DMs: excludes "group-only" tools (moderation)
5754
+ */
5755
+ getForContext(isGroup, toolLimit) {
5756
+ const excluded = isGroup ? "dm-only" : "group-only";
5757
+ const filtered = Array.from(this.tools.values()).filter((rt) => this.scopes.get(rt.tool.name) !== excluded).map((rt) => rt.tool);
5758
+ if (toolLimit !== null && filtered.length > toolLimit) {
5759
+ console.warn(
5760
+ `\u26A0\uFE0F Provider tool limit: ${toolLimit}, after scope filter: ${filtered.length}. Truncating to ${toolLimit} tools.`
5761
+ );
5762
+ return filtered.slice(0, toolLimit);
5763
+ }
5764
+ return filtered;
5765
+ }
5825
5766
  /**
5826
5767
  * Check if a tool is registered
5827
5768
  */
@@ -6554,16 +6495,16 @@ var telegramSendPhotoExecutor = async (params, context) => {
6554
6495
  // src/agent/tools/telegram/media/send-voice.ts
6555
6496
  import { Type as Type11 } from "@sinclair/typebox";
6556
6497
  import { Api as Api10 } from "telegram";
6557
- import { unlinkSync as unlinkSync3 } from "fs";
6498
+ import { unlinkSync as unlinkSync2 } from "fs";
6558
6499
 
6559
6500
  // src/services/tts.ts
6560
6501
  import { spawn } from "child_process";
6561
- import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync8, existsSync as existsSync10, unlinkSync as unlinkSync2 } from "fs";
6562
- import { join as join9 } from "path";
6502
+ import { writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, existsSync as existsSync9, unlinkSync } from "fs";
6503
+ import { join as join8 } from "path";
6563
6504
  import { tmpdir } from "os";
6564
6505
  import { randomUUID as randomUUID3 } from "crypto";
6565
- var PIPER_VOICES_DIR = join9(TELETON_ROOT, "piper-voices");
6566
- var PIPER_VENV = join9(TELETON_ROOT, "rvc-env");
6506
+ var PIPER_VOICES_DIR = join8(TELETON_ROOT, "piper-voices");
6507
+ var PIPER_VENV = join8(TELETON_ROOT, "rvc-env");
6567
6508
  var PIPER_VOICES = {
6568
6509
  trump: "en_US-trump-high.onnx",
6569
6510
  // Trump voice (default) ⭐
@@ -6657,21 +6598,21 @@ async function generateSpeech(options) {
6657
6598
  }
6658
6599
  }
6659
6600
  async function generatePiperTTS(text, voice) {
6660
- const tempDir = join9(tmpdir(), "tonnet-tts");
6661
- if (!existsSync10(tempDir)) {
6662
- mkdirSync8(tempDir, { recursive: true });
6601
+ const tempDir = join8(tmpdir(), "tonnet-tts");
6602
+ if (!existsSync9(tempDir)) {
6603
+ mkdirSync7(tempDir, { recursive: true });
6663
6604
  }
6664
6605
  const id = randomUUID3();
6665
- const wavPath = join9(tempDir, `${id}.wav`);
6666
- const oggPath = join9(tempDir, `${id}.ogg`);
6606
+ const wavPath = join8(tempDir, `${id}.wav`);
6607
+ const oggPath = join8(tempDir, `${id}.ogg`);
6667
6608
  const modelFile = PIPER_VOICES[voice.toLowerCase()] ?? voice;
6668
- const modelPath = modelFile.includes("/") ? modelFile : join9(PIPER_VOICES_DIR, modelFile);
6669
- if (!existsSync10(modelPath)) {
6609
+ const modelPath = modelFile.includes("/") ? modelFile : join8(PIPER_VOICES_DIR, modelFile);
6610
+ if (!existsSync9(modelPath)) {
6670
6611
  throw new Error(
6671
6612
  `Piper voice not found: ${modelPath}. Available: ${Object.keys(PIPER_VOICES).join(", ")}`
6672
6613
  );
6673
6614
  }
6674
- const piperBin = join9(PIPER_VENV, "bin", "piper");
6615
+ const piperBin = join8(PIPER_VENV, "bin", "piper");
6675
6616
  await new Promise((resolve2, reject) => {
6676
6617
  const proc = spawn(
6677
6618
  piperBin,
@@ -6695,7 +6636,7 @@ async function generatePiperTTS(text, voice) {
6695
6636
  stderr += data.toString();
6696
6637
  });
6697
6638
  proc.on("close", (code) => {
6698
- if (code === 0 && existsSync10(wavPath)) {
6639
+ if (code === 0 && existsSync9(wavPath)) {
6699
6640
  resolve2();
6700
6641
  } else {
6701
6642
  reject(new Error(`Piper TTS failed (code ${code}): ${stderr}`));
@@ -6734,7 +6675,7 @@ async function generatePiperTTS(text, voice) {
6734
6675
  reject(new Error(`ffmpeg spawn error: ${err.message}`));
6735
6676
  });
6736
6677
  });
6737
- unlinkSync2(wavPath);
6678
+ unlinkSync(wavPath);
6738
6679
  } catch (err) {
6739
6680
  return {
6740
6681
  filePath: wavPath,
@@ -6749,11 +6690,11 @@ async function generatePiperTTS(text, voice) {
6749
6690
  };
6750
6691
  }
6751
6692
  async function generateEdgeTTS(text, voice, rate, pitch) {
6752
- const tempDir = join9(tmpdir(), "tonnet-tts");
6753
- if (!existsSync10(tempDir)) {
6754
- mkdirSync8(tempDir, { recursive: true });
6693
+ const tempDir = join8(tmpdir(), "tonnet-tts");
6694
+ if (!existsSync9(tempDir)) {
6695
+ mkdirSync7(tempDir, { recursive: true });
6755
6696
  }
6756
- const outputPath = join9(tempDir, `${randomUUID3()}.mp3`);
6697
+ const outputPath = join8(tempDir, `${randomUUID3()}.mp3`);
6757
6698
  const args = ["--text", text, "--voice", voice, "--write-media", outputPath];
6758
6699
  if (rate) {
6759
6700
  args.push("--rate", rate);
@@ -6790,11 +6731,11 @@ async function generateOpenAITTS(text, voice) {
6790
6731
  if (!apiKey) {
6791
6732
  throw new Error("OPENAI_API_KEY not set. Use Edge TTS (free) or set API key.");
6792
6733
  }
6793
- const tempDir = join9(tmpdir(), "tonnet-tts");
6794
- if (!existsSync10(tempDir)) {
6795
- mkdirSync8(tempDir, { recursive: true });
6734
+ const tempDir = join8(tmpdir(), "tonnet-tts");
6735
+ if (!existsSync9(tempDir)) {
6736
+ mkdirSync7(tempDir, { recursive: true });
6796
6737
  }
6797
- const outputPath = join9(tempDir, `${randomUUID3()}.mp3`);
6738
+ const outputPath = join8(tempDir, `${randomUUID3()}.mp3`);
6798
6739
  const response = await fetchWithTimeout(OPENAI_TTS_URL, {
6799
6740
  method: "POST",
6800
6741
  headers: {
@@ -6827,11 +6768,11 @@ async function generateElevenLabsTTS(text, voiceId) {
6827
6768
  if (!apiKey) {
6828
6769
  throw new Error("ELEVENLABS_API_KEY not set. Use Edge TTS (free) or set API key.");
6829
6770
  }
6830
- const tempDir = join9(tmpdir(), "tonnet-tts");
6831
- if (!existsSync10(tempDir)) {
6832
- mkdirSync8(tempDir, { recursive: true });
6771
+ const tempDir = join8(tmpdir(), "tonnet-tts");
6772
+ if (!existsSync9(tempDir)) {
6773
+ mkdirSync7(tempDir, { recursive: true });
6833
6774
  }
6834
- const outputPath = join9(tempDir, `${randomUUID3()}.mp3`);
6775
+ const outputPath = join8(tempDir, `${randomUUID3()}.mp3`);
6835
6776
  const response = await fetchWithTimeout(`${ELEVENLABS_TTS_URL}/${voiceId}`, {
6836
6777
  method: "POST",
6837
6778
  headers: {
@@ -7043,7 +6984,7 @@ var telegramSendVoiceExecutor = async (params, context) => {
7043
6984
  } finally {
7044
6985
  if (generatedFile) {
7045
6986
  try {
7046
- unlinkSync3(generatedFile);
6987
+ unlinkSync2(generatedFile);
7047
6988
  } catch (e) {
7048
6989
  }
7049
6990
  }
@@ -7423,7 +7364,7 @@ import { Type as Type15 } from "@sinclair/typebox";
7423
7364
  import {
7424
7365
  completeSimple
7425
7366
  } from "@mariozechner/pi-ai";
7426
- import { readFileSync as readFileSync9, existsSync as existsSync11 } from "fs";
7367
+ import { readFileSync as readFileSync8, existsSync as existsSync10 } from "fs";
7427
7368
  import { extname as extname3 } from "path";
7428
7369
  var visionAnalyzeTool = {
7429
7370
  name: "vision_analyze",
@@ -7495,7 +7436,7 @@ var visionAnalyzeExecutor = async (params, context) => {
7495
7436
  }
7496
7437
  throw error;
7497
7438
  }
7498
- if (!existsSync11(validatedPath.absolutePath)) {
7439
+ if (!existsSync10(validatedPath.absolutePath)) {
7499
7440
  return {
7500
7441
  success: false,
7501
7442
  error: `File not found: ${filePath}`
@@ -7509,7 +7450,7 @@ var visionAnalyzeExecutor = async (params, context) => {
7509
7450
  error: `Unsupported file type: ${ext}. Vision supports: .jpg, .jpeg, .png, .gif, .webp`
7510
7451
  };
7511
7452
  }
7512
- data = readFileSync9(validatedPath.absolutePath);
7453
+ data = readFileSync8(validatedPath.absolutePath);
7513
7454
  source = `file:${filePath}`;
7514
7455
  } else {
7515
7456
  console.log(`\u{1F4F7} Downloading image from message ${messageId}...`);
@@ -8752,7 +8693,7 @@ var telegramCreateGroupExecutor = async (params, context) => {
8752
8693
  // src/agent/tools/telegram/groups/set-chat-photo.ts
8753
8694
  import { Type as Type29 } from "@sinclair/typebox";
8754
8695
  import { Api as Api22 } from "telegram";
8755
- import { readFileSync as readFileSync10 } from "fs";
8696
+ import { readFileSync as readFileSync9 } from "fs";
8756
8697
  var telegramSetChatPhotoTool = {
8757
8698
  name: "telegram_set_chat_photo",
8758
8699
  description: `Set or delete a group/channel profile photo. You need admin rights with change info permission. Provide a local image path to set, or use delete_photo to remove.`,
@@ -8821,7 +8762,7 @@ var telegramSetChatPhotoExecutor = async (params, context) => {
8821
8762
  }
8822
8763
  throw error;
8823
8764
  }
8824
- const fileBuffer = readFileSync10(validatedPath.absolutePath);
8765
+ const fileBuffer = readFileSync9(validatedPath.absolutePath);
8825
8766
  const file = await client.uploadFile({
8826
8767
  file: new CustomFile(
8827
8768
  validatedPath.filename,
@@ -11001,7 +10942,7 @@ var import_big_integer4 = __toESM(require_BigInteger(), 1);
11001
10942
  import { Type as Type59 } from "@sinclair/typebox";
11002
10943
  import { Api as Api51 } from "telegram";
11003
10944
  import { CustomFile as CustomFile2 } from "telegram/client/uploads.js";
11004
- import { readFileSync as readFileSync11, statSync } from "fs";
10945
+ import { readFileSync as readFileSync10, statSync } from "fs";
11005
10946
  import { basename as basename2 } from "path";
11006
10947
  var telegramSendStoryTool = {
11007
10948
  name: "telegram_send_story",
@@ -11050,7 +10991,7 @@ var telegramSendStoryExecutor = async (params, context) => {
11050
10991
  const filePath = validatedPath.absolutePath;
11051
10992
  const fileName = basename2(filePath);
11052
10993
  const fileSize = statSync(filePath).size;
11053
- const fileBuffer = readFileSync11(filePath);
10994
+ const fileBuffer = readFileSync10(filePath);
11054
10995
  const isVideo = filePath.toLowerCase().match(/\.(mp4|mov|avi)$/);
11055
10996
  const customFile = new CustomFile2(fileName, fileSize, filePath, fileBuffer);
11056
10997
  const uploadedFile = await gramJsClient.uploadFile({
@@ -11119,8 +11060,8 @@ var telegramSendStoryExecutor = async (params, context) => {
11119
11060
 
11120
11061
  // src/agent/tools/telegram/memory/memory-write.ts
11121
11062
  import { Type as Type60 } from "@sinclair/typebox";
11122
- import { appendFileSync as appendFileSync3, writeFileSync as writeFileSync8, existsSync as existsSync12, mkdirSync as mkdirSync9 } from "fs";
11123
- import { join as join10 } from "path";
11063
+ import { appendFileSync as appendFileSync2, writeFileSync as writeFileSync8, existsSync as existsSync11, mkdirSync as mkdirSync8 } from "fs";
11064
+ import { join as join9 } from "path";
11124
11065
  var MEMORY_DIR2 = WORKSPACE_PATHS.MEMORY_DIR;
11125
11066
  var MEMORY_FILE = WORKSPACE_PATHS.MEMORY;
11126
11067
  var memoryWriteTool = {
@@ -11142,8 +11083,8 @@ var memoryWriteTool = {
11142
11083
  })
11143
11084
  };
11144
11085
  function ensureMemoryDir2() {
11145
- if (!existsSync12(MEMORY_DIR2)) {
11146
- mkdirSync9(MEMORY_DIR2, { recursive: true });
11086
+ if (!existsSync11(MEMORY_DIR2)) {
11087
+ mkdirSync8(MEMORY_DIR2, { recursive: true });
11147
11088
  }
11148
11089
  }
11149
11090
  function formatDate2(date) {
@@ -11153,7 +11094,7 @@ function formatDate2(date) {
11153
11094
  return `${year}-${month}-${day}`;
11154
11095
  }
11155
11096
  function getDailyLogPath2() {
11156
- return join10(MEMORY_DIR2, `${formatDate2(/* @__PURE__ */ new Date())}.md`);
11097
+ return join9(MEMORY_DIR2, `${formatDate2(/* @__PURE__ */ new Date())}.md`);
11157
11098
  }
11158
11099
  var memoryWriteExecutor = async (params, context) => {
11159
11100
  try {
@@ -11185,10 +11126,10 @@ var memoryWriteExecutor = async (params, context) => {
11185
11126
  entry += `
11186
11127
  _Added: ${now.toISOString()}_
11187
11128
  `;
11188
- if (!existsSync12(MEMORY_FILE)) {
11129
+ if (!existsSync11(MEMORY_FILE)) {
11189
11130
  writeFileSync8(MEMORY_FILE, "# MEMORY.md - Persistent Memory\n\n", "utf-8");
11190
11131
  }
11191
- appendFileSync3(MEMORY_FILE, entry, "utf-8");
11132
+ appendFileSync2(MEMORY_FILE, entry, "utf-8");
11192
11133
  console.log(`\u{1F4DD} Memory written to MEMORY.md${section ? ` (section: ${section})` : ""}`);
11193
11134
  return {
11194
11135
  success: true,
@@ -11201,7 +11142,7 @@ _Added: ${now.toISOString()}_
11201
11142
  };
11202
11143
  } else {
11203
11144
  const logPath = getDailyLogPath2();
11204
- if (!existsSync12(logPath)) {
11145
+ if (!existsSync11(logPath)) {
11205
11146
  const header = `# Daily Log - ${formatDate2(now)}
11206
11147
 
11207
11148
  `;
@@ -11218,7 +11159,7 @@ ${content}
11218
11159
  ---
11219
11160
 
11220
11161
  `;
11221
- appendFileSync3(logPath, entry, "utf-8");
11162
+ appendFileSync2(logPath, entry, "utf-8");
11222
11163
  console.log(`\u{1F4C5} Memory written to daily log${section ? ` (${section})` : ""}`);
11223
11164
  return {
11224
11165
  success: true,
@@ -11241,8 +11182,8 @@ ${content}
11241
11182
 
11242
11183
  // src/agent/tools/telegram/memory/memory-read.ts
11243
11184
  import { Type as Type61 } from "@sinclair/typebox";
11244
- import { readFileSync as readFileSync13, existsSync as existsSync13, readdirSync as readdirSync2 } from "fs";
11245
- import { join as join11 } from "path";
11185
+ import { readFileSync as readFileSync12, existsSync as existsSync12, readdirSync as readdirSync2 } from "fs";
11186
+ import { join as join10 } from "path";
11246
11187
  var MEMORY_DIR3 = WORKSPACE_PATHS.MEMORY_DIR;
11247
11188
  var MEMORY_FILE2 = WORKSPACE_PATHS.MEMORY;
11248
11189
  var memoryReadTool = {
@@ -11271,10 +11212,10 @@ var memoryReadExecutor = async (params, _context) => {
11271
11212
  const { target, date } = params;
11272
11213
  if (target === "list") {
11273
11214
  const files = [];
11274
- if (existsSync13(MEMORY_FILE2)) {
11215
+ if (existsSync12(MEMORY_FILE2)) {
11275
11216
  files.push("MEMORY.md (persistent)");
11276
11217
  }
11277
- if (existsSync13(MEMORY_DIR3)) {
11218
+ if (existsSync12(MEMORY_DIR3)) {
11278
11219
  const dailyLogs = readdirSync2(MEMORY_DIR3).filter((f) => f.endsWith(".md")).sort().reverse();
11279
11220
  files.push(...dailyLogs.map((f) => `memory/${f}`));
11280
11221
  }
@@ -11287,7 +11228,7 @@ var memoryReadExecutor = async (params, _context) => {
11287
11228
  };
11288
11229
  }
11289
11230
  if (target === "persistent") {
11290
- if (!existsSync13(MEMORY_FILE2)) {
11231
+ if (!existsSync12(MEMORY_FILE2)) {
11291
11232
  return {
11292
11233
  success: true,
11293
11234
  data: {
@@ -11296,7 +11237,7 @@ var memoryReadExecutor = async (params, _context) => {
11296
11237
  }
11297
11238
  };
11298
11239
  }
11299
- const content = readFileSync13(MEMORY_FILE2, "utf-8");
11240
+ const content = readFileSync12(MEMORY_FILE2, "utf-8");
11300
11241
  return {
11301
11242
  success: true,
11302
11243
  data: {
@@ -11309,8 +11250,8 @@ var memoryReadExecutor = async (params, _context) => {
11309
11250
  }
11310
11251
  if (target === "daily") {
11311
11252
  const targetDate = date || formatDate3(/* @__PURE__ */ new Date());
11312
- const logPath = join11(MEMORY_DIR3, `${targetDate}.md`);
11313
- if (!existsSync13(logPath)) {
11253
+ const logPath = join10(MEMORY_DIR3, `${targetDate}.md`);
11254
+ if (!existsSync12(logPath)) {
11314
11255
  return {
11315
11256
  success: true,
11316
11257
  data: {
@@ -11320,7 +11261,7 @@ var memoryReadExecutor = async (params, _context) => {
11320
11261
  }
11321
11262
  };
11322
11263
  }
11323
- const content = readFileSync13(logPath, "utf-8");
11264
+ const content = readFileSync12(logPath, "utf-8");
11324
11265
  return {
11325
11266
  success: true,
11326
11267
  data: {
@@ -11339,15 +11280,15 @@ var memoryReadExecutor = async (params, _context) => {
11339
11280
  const todayStr = formatDate3(today);
11340
11281
  const yesterdayStr = formatDate3(yesterday);
11341
11282
  const result = {};
11342
- const yesterdayPath = join11(MEMORY_DIR3, `${yesterdayStr}.md`);
11343
- if (existsSync13(yesterdayPath)) {
11344
- result[yesterdayStr] = readFileSync13(yesterdayPath, "utf-8");
11283
+ const yesterdayPath = join10(MEMORY_DIR3, `${yesterdayStr}.md`);
11284
+ if (existsSync12(yesterdayPath)) {
11285
+ result[yesterdayStr] = readFileSync12(yesterdayPath, "utf-8");
11345
11286
  } else {
11346
11287
  result[yesterdayStr] = null;
11347
11288
  }
11348
- const todayPath = join11(MEMORY_DIR3, `${todayStr}.md`);
11349
- if (existsSync13(todayPath)) {
11350
- result[todayStr] = readFileSync13(todayPath, "utf-8");
11289
+ const todayPath = join10(MEMORY_DIR3, `${todayStr}.md`);
11290
+ if (existsSync12(todayPath)) {
11291
+ result[todayStr] = readFileSync12(todayPath, "utf-8");
11351
11292
  } else {
11352
11293
  result[todayStr] = null;
11353
11294
  }
@@ -19327,7 +19268,7 @@ var journalUpdateExecutor = async (params) => {
19327
19268
  // src/agent/tools/workspace/list.ts
19328
19269
  import { Type as Type99 } from "@sinclair/typebox";
19329
19270
  import { readdirSync as readdirSync3, lstatSync as lstatSync2 } from "fs";
19330
- import { join as join12 } from "path";
19271
+ import { join as join11 } from "path";
19331
19272
  var workspaceListTool = {
19332
19273
  name: "workspace_list",
19333
19274
  description: `List files and directories in your workspace.
@@ -19364,7 +19305,7 @@ function listDir(dirPath, recursive, filter) {
19364
19305
  try {
19365
19306
  const entries = readdirSync3(dirPath);
19366
19307
  for (const entry of entries) {
19367
- const fullPath = join12(dirPath, entry);
19308
+ const fullPath = join11(dirPath, entry);
19368
19309
  const stats = lstatSync2(fullPath);
19369
19310
  const isDir = stats.isDirectory();
19370
19311
  if (filter === "files" && isDir) continue;
@@ -19425,7 +19366,7 @@ var workspaceListExecutor = async (params, _context) => {
19425
19366
 
19426
19367
  // src/agent/tools/workspace/read.ts
19427
19368
  import { Type as Type100 } from "@sinclair/typebox";
19428
- import { readFileSync as readFileSync14, lstatSync as lstatSync3 } from "fs";
19369
+ import { readFileSync as readFileSync13, lstatSync as lstatSync3 } from "fs";
19429
19370
  var workspaceReadTool = {
19430
19371
  name: "workspace_read",
19431
19372
  description: `Read a file from your workspace.
@@ -19497,7 +19438,7 @@ var workspaceReadExecutor = async (params, _context) => {
19497
19438
  }
19498
19439
  };
19499
19440
  }
19500
- const content = readFileSync14(
19441
+ const content = readFileSync13(
19501
19442
  validated.absolutePath,
19502
19443
  encoding === "base64" ? "base64" : "utf-8"
19503
19444
  );
@@ -19527,8 +19468,8 @@ var workspaceReadExecutor = async (params, _context) => {
19527
19468
 
19528
19469
  // src/agent/tools/workspace/write.ts
19529
19470
  import { Type as Type101 } from "@sinclair/typebox";
19530
- import { writeFileSync as writeFileSync9, appendFileSync as appendFileSync4, mkdirSync as mkdirSync10, existsSync as existsSync14 } from "fs";
19531
- import { dirname as dirname7 } from "path";
19471
+ import { writeFileSync as writeFileSync9, appendFileSync as appendFileSync3, mkdirSync as mkdirSync9, existsSync as existsSync13 } from "fs";
19472
+ import { dirname as dirname6 } from "path";
19532
19473
  var workspaceWriteTool = {
19533
19474
  name: "workspace_write",
19534
19475
  description: `Write a file to your workspace.
@@ -19572,9 +19513,9 @@ var workspaceWriteExecutor = async (params, _context) => {
19572
19513
  try {
19573
19514
  const { path, content, encoding = "utf-8", append = false, createDirs = true } = params;
19574
19515
  const validated = validateWritePath(path);
19575
- const parentDir = dirname7(validated.absolutePath);
19576
- if (createDirs && !existsSync14(parentDir)) {
19577
- mkdirSync10(parentDir, { recursive: true });
19516
+ const parentDir = dirname6(validated.absolutePath);
19517
+ if (createDirs && !existsSync13(parentDir)) {
19518
+ mkdirSync9(parentDir, { recursive: true });
19578
19519
  }
19579
19520
  let writeContent;
19580
19521
  if (encoding === "base64") {
@@ -19591,7 +19532,7 @@ var workspaceWriteExecutor = async (params, _context) => {
19591
19532
  };
19592
19533
  }
19593
19534
  if (append && validated.exists) {
19594
- appendFileSync4(validated.absolutePath, writeContent);
19535
+ appendFileSync3(validated.absolutePath, writeContent);
19595
19536
  } else {
19596
19537
  writeFileSync9(validated.absolutePath, writeContent);
19597
19538
  }
@@ -19621,7 +19562,7 @@ var workspaceWriteExecutor = async (params, _context) => {
19621
19562
 
19622
19563
  // src/agent/tools/workspace/delete.ts
19623
19564
  import { Type as Type102 } from "@sinclair/typebox";
19624
- import { unlinkSync as unlinkSync4, rmdirSync, readdirSync as readdirSync4, rmSync } from "fs";
19565
+ import { unlinkSync as unlinkSync3, rmdirSync, readdirSync as readdirSync4, rmSync } from "fs";
19625
19566
  var PROTECTED_WORKSPACE_FILES = [
19626
19567
  "SOUL.md",
19627
19568
  "STRATEGY.md",
@@ -19677,7 +19618,7 @@ var workspaceDeleteExecutor = async (params, _context) => {
19677
19618
  rmdirSync(validated.absolutePath);
19678
19619
  }
19679
19620
  } else {
19680
- unlinkSync4(validated.absolutePath);
19621
+ unlinkSync3(validated.absolutePath);
19681
19622
  }
19682
19623
  return {
19683
19624
  success: true,
@@ -19703,8 +19644,8 @@ var workspaceDeleteExecutor = async (params, _context) => {
19703
19644
 
19704
19645
  // src/agent/tools/workspace/info.ts
19705
19646
  import { Type as Type103 } from "@sinclair/typebox";
19706
- import { lstatSync as lstatSync4, readdirSync as readdirSync5, existsSync as existsSync15 } from "fs";
19707
- import { join as join13 } from "path";
19647
+ import { lstatSync as lstatSync4, readdirSync as readdirSync5, existsSync as existsSync14 } from "fs";
19648
+ import { join as join12 } from "path";
19708
19649
  var MEMES_DIR = WORKSPACE_PATHS.MEMES_DIR;
19709
19650
  var workspaceInfoTool = {
19710
19651
  name: "workspace_info",
@@ -19729,7 +19670,7 @@ function getDirSize(dirPath) {
19729
19670
  try {
19730
19671
  const entries = readdirSync5(dirPath, { withFileTypes: true });
19731
19672
  for (const entry of entries) {
19732
- const fullPath = join13(dirPath, entry.name);
19673
+ const fullPath = join12(dirPath, entry.name);
19733
19674
  if (entry.isDirectory()) {
19734
19675
  const subStats = getDirSize(fullPath);
19735
19676
  count += subStats.count;
@@ -19756,11 +19697,11 @@ function formatBytes(bytes) {
19756
19697
  var workspaceInfoExecutor = async (params, _context) => {
19757
19698
  try {
19758
19699
  const { detailed = false } = params;
19759
- const memoryStats = existsSync15(WORKSPACE_PATHS.MEMORY_DIR) ? getDirSize(WORKSPACE_PATHS.MEMORY_DIR) : { count: 0, size: 0 };
19760
- const downloadsStats = existsSync15(WORKSPACE_PATHS.DOWNLOADS_DIR) ? getDirSize(WORKSPACE_PATHS.DOWNLOADS_DIR) : { count: 0, size: 0 };
19761
- const uploadsStats = existsSync15(WORKSPACE_PATHS.UPLOADS_DIR) ? getDirSize(WORKSPACE_PATHS.UPLOADS_DIR) : { count: 0, size: 0 };
19762
- const tempStats = existsSync15(WORKSPACE_PATHS.TEMP_DIR) ? getDirSize(WORKSPACE_PATHS.TEMP_DIR) : { count: 0, size: 0 };
19763
- const memesStats = existsSync15(MEMES_DIR) ? getDirSize(MEMES_DIR) : { count: 0, size: 0 };
19700
+ const memoryStats = existsSync14(WORKSPACE_PATHS.MEMORY_DIR) ? getDirSize(WORKSPACE_PATHS.MEMORY_DIR) : { count: 0, size: 0 };
19701
+ const downloadsStats = existsSync14(WORKSPACE_PATHS.DOWNLOADS_DIR) ? getDirSize(WORKSPACE_PATHS.DOWNLOADS_DIR) : { count: 0, size: 0 };
19702
+ const uploadsStats = existsSync14(WORKSPACE_PATHS.UPLOADS_DIR) ? getDirSize(WORKSPACE_PATHS.UPLOADS_DIR) : { count: 0, size: 0 };
19703
+ const tempStats = existsSync14(WORKSPACE_PATHS.TEMP_DIR) ? getDirSize(WORKSPACE_PATHS.TEMP_DIR) : { count: 0, size: 0 };
19704
+ const memesStats = existsSync14(MEMES_DIR) ? getDirSize(MEMES_DIR) : { count: 0, size: 0 };
19764
19705
  const totalSize = memoryStats.size + downloadsStats.size + uploadsStats.size + tempStats.size + memesStats.size;
19765
19706
  const info = {
19766
19707
  workspaceRoot: WORKSPACE_ROOT,
@@ -19796,11 +19737,11 @@ var workspaceInfoExecutor = async (params, _context) => {
19796
19737
  };
19797
19738
  if (detailed) {
19798
19739
  info.files = {
19799
- memory: existsSync15(WORKSPACE_PATHS.MEMORY_DIR) ? readdirSync5(WORKSPACE_PATHS.MEMORY_DIR) : [],
19800
- downloads: existsSync15(WORKSPACE_PATHS.DOWNLOADS_DIR) ? readdirSync5(WORKSPACE_PATHS.DOWNLOADS_DIR) : [],
19801
- uploads: existsSync15(WORKSPACE_PATHS.UPLOADS_DIR) ? readdirSync5(WORKSPACE_PATHS.UPLOADS_DIR) : [],
19802
- temp: existsSync15(WORKSPACE_PATHS.TEMP_DIR) ? readdirSync5(WORKSPACE_PATHS.TEMP_DIR) : [],
19803
- memes: existsSync15(MEMES_DIR) ? readdirSync5(MEMES_DIR) : []
19740
+ memory: existsSync14(WORKSPACE_PATHS.MEMORY_DIR) ? readdirSync5(WORKSPACE_PATHS.MEMORY_DIR) : [],
19741
+ downloads: existsSync14(WORKSPACE_PATHS.DOWNLOADS_DIR) ? readdirSync5(WORKSPACE_PATHS.DOWNLOADS_DIR) : [],
19742
+ uploads: existsSync14(WORKSPACE_PATHS.UPLOADS_DIR) ? readdirSync5(WORKSPACE_PATHS.UPLOADS_DIR) : [],
19743
+ temp: existsSync14(WORKSPACE_PATHS.TEMP_DIR) ? readdirSync5(WORKSPACE_PATHS.TEMP_DIR) : [],
19744
+ memes: existsSync14(MEMES_DIR) ? readdirSync5(MEMES_DIR) : []
19804
19745
  };
19805
19746
  }
19806
19747
  return {
@@ -19817,9 +19758,9 @@ var workspaceInfoExecutor = async (params, _context) => {
19817
19758
 
19818
19759
  // src/agent/tools/workspace/rename.ts
19819
19760
  import { Type as Type104 } from "@sinclair/typebox";
19820
- import { renameSync as renameSync2, existsSync as existsSync16 } from "fs";
19821
- import { dirname as dirname8 } from "path";
19822
- import { mkdirSync as mkdirSync11 } from "fs";
19761
+ import { renameSync, existsSync as existsSync15 } from "fs";
19762
+ import { dirname as dirname7 } from "path";
19763
+ import { mkdirSync as mkdirSync10 } from "fs";
19823
19764
  var workspaceRenameTool = {
19824
19765
  name: "workspace_rename",
19825
19766
  description: `Rename or move a file within your workspace.
@@ -19866,11 +19807,11 @@ var workspaceRenameExecutor = async (params, _context) => {
19866
19807
  error: `Destination already exists: '${to}'. Use overwrite=true to replace.`
19867
19808
  };
19868
19809
  }
19869
- const parentDir = dirname8(validatedTo.absolutePath);
19870
- if (!existsSync16(parentDir)) {
19871
- mkdirSync11(parentDir, { recursive: true });
19810
+ const parentDir = dirname7(validatedTo.absolutePath);
19811
+ if (!existsSync15(parentDir)) {
19812
+ mkdirSync10(parentDir, { recursive: true });
19872
19813
  }
19873
- renameSync2(validatedFrom.absolutePath, validatedTo.absolutePath);
19814
+ renameSync(validatedFrom.absolutePath, validatedTo.absolutePath);
19874
19815
  return {
19875
19816
  success: true,
19876
19817
  data: {
@@ -19908,26 +19849,18 @@ var CASINO_CONFIG = {
19908
19849
  // Cooldown
19909
19850
  cooldownSeconds: 30,
19910
19851
  // Seconds between spins per user
19911
- // House edge
19912
- houseEdgePercent: 5,
19913
- // % of each bet goes to jackpot
19914
- // Jackpot
19915
- jackpotThreshold: 100,
19916
- // Minimum TON to award jackpot
19917
- jackpotCooldownHours: 24,
19918
- // Hours between jackpot awards
19919
- // Slot multipliers (40% house edge, 60% payout)
19852
+ // Slot multipliers
19920
19853
  slot: {
19921
- jackpot: { range: [64, 64], multiplier: 5 },
19854
+ topWin: { range: [64, 64], multiplier: 5 },
19922
19855
  // 777
19923
19856
  bigWin: { range: [60, 63], multiplier: 2.5 },
19924
19857
  mediumWin: { range: [55, 59], multiplier: 1.8 },
19925
19858
  smallWin: { range: [43, 54], multiplier: 1.2 }
19926
19859
  // Values 1-42: no win
19927
19860
  },
19928
- // Dice multipliers (6.7% house edge, 93.3% payout)
19861
+ // Dice multipliers
19929
19862
  dice: {
19930
- jackpot: { value: 6, multiplier: 2.5 },
19863
+ topWin: { value: 6, multiplier: 2.5 },
19931
19864
  bigWin: { value: 5, multiplier: 1.8 },
19932
19865
  smallWin: { value: 4, multiplier: 1.3 }
19933
19866
  // Values 1-3: no win
@@ -19955,11 +19888,6 @@ function initCasinoConfig(yaml) {
19955
19888
  if (yaml.max_bet_percent !== void 0) CASINO_CONFIG.maxBetPercent = yaml.max_bet_percent;
19956
19889
  if (yaml.min_bankroll !== void 0) CASINO_CONFIG.minBankroll = yaml.min_bankroll;
19957
19890
  if (yaml.cooldown_seconds !== void 0) CASINO_CONFIG.cooldownSeconds = yaml.cooldown_seconds;
19958
- if (yaml.house_edge_percent !== void 0)
19959
- CASINO_CONFIG.houseEdgePercent = yaml.house_edge_percent;
19960
- if (yaml.jackpot_threshold !== void 0) CASINO_CONFIG.jackpotThreshold = yaml.jackpot_threshold;
19961
- if (yaml.jackpot_cooldown_hours !== void 0)
19962
- CASINO_CONFIG.jackpotCooldownHours = yaml.jackpot_cooldown_hours;
19963
19891
  if (yaml.payment_window_minutes !== void 0)
19964
19892
  CASINO_CONFIG.paymentWindowMinutes = yaml.payment_window_minutes;
19965
19893
  if (yaml.max_payment_age_minutes !== void 0)
@@ -19974,8 +19902,7 @@ function initCasinoConfig(yaml) {
19974
19902
  }
19975
19903
  function getSlotMultiplier(value) {
19976
19904
  const { slot } = CASINO_CONFIG;
19977
- if (value >= slot.jackpot.range[0] && value <= slot.jackpot.range[1])
19978
- return slot.jackpot.multiplier;
19905
+ if (value >= slot.topWin.range[0] && value <= slot.topWin.range[1]) return slot.topWin.multiplier;
19979
19906
  if (value >= slot.bigWin.range[0] && value <= slot.bigWin.range[1]) return slot.bigWin.multiplier;
19980
19907
  if (value >= slot.mediumWin.range[0] && value <= slot.mediumWin.range[1])
19981
19908
  return slot.mediumWin.multiplier;
@@ -19985,14 +19912,14 @@ function getSlotMultiplier(value) {
19985
19912
  }
19986
19913
  function getDiceMultiplier(value) {
19987
19914
  const { dice } = CASINO_CONFIG;
19988
- if (value === dice.jackpot.value) return dice.jackpot.multiplier;
19915
+ if (value === dice.topWin.value) return dice.topWin.multiplier;
19989
19916
  if (value === dice.bigWin.value) return dice.bigWin.multiplier;
19990
19917
  if (value === dice.smallWin.value) return dice.smallWin.multiplier;
19991
19918
  return 0;
19992
19919
  }
19993
19920
  function getSlotInterpretation(value) {
19994
19921
  const { slot } = CASINO_CONFIG;
19995
- if (value >= slot.jackpot.range[0] && value <= slot.jackpot.range[1]) return "\u{1F3B0} JACKPOT 777!";
19922
+ if (value >= slot.topWin.range[0] && value <= slot.topWin.range[1]) return "\u{1F3B0} 777! Top win!";
19996
19923
  if (value >= slot.bigWin.range[0] && value <= slot.bigWin.range[1]) return "\u{1F38A} Big win!";
19997
19924
  if (value >= slot.mediumWin.range[0] && value <= slot.mediumWin.range[1]) return "\u2728 Nice win!";
19998
19925
  if (value >= slot.smallWin.range[0] && value <= slot.smallWin.range[1]) return "\u{1F3AF} Small win!";
@@ -20000,7 +19927,7 @@ function getSlotInterpretation(value) {
20000
19927
  }
20001
19928
  function getDiceInterpretation(value) {
20002
19929
  const { dice } = CASINO_CONFIG;
20003
- if (value === dice.jackpot.value) return "\u{1F3B2} JACKPOT 6!";
19930
+ if (value === dice.topWin.value) return "\u{1F3B2} 6! Top win!";
20004
19931
  if (value === dice.bigWin.value) return "\u{1F38A} Big win (5)!";
20005
19932
  if (value === dice.smallWin.value) return "\u2728 Nice win (4)!";
20006
19933
  return `Dice: ${value}`;
@@ -20058,9 +19985,9 @@ var casinoBalanceExecutor = async (params, context) => {
20058
19985
  message = `\u2705 Casino bankroll is healthy (${balance.toFixed(2)} TON)`;
20059
19986
  canAcceptBets = true;
20060
19987
  }
20061
- const jackpotMultiplier = CASINO_CONFIG.slot.jackpot.multiplier;
19988
+ const maxMultiplier = CASINO_CONFIG.slot.topWin.multiplier;
20062
19989
  const maxBetByPercent = balance * (CASINO_CONFIG.maxBetPercent / 100);
20063
- const maxBetByCoverage = balance / jackpotMultiplier;
19990
+ const maxBetByCoverage = balance / maxMultiplier;
20064
19991
  const maxBet = Math.min(maxBetByPercent, maxBetByCoverage);
20065
19992
  return {
20066
19993
  success: true,
@@ -20074,7 +20001,7 @@ var casinoBalanceExecutor = async (params, context) => {
20074
20001
  maxBet: maxBet.toFixed(2),
20075
20002
  minBankroll: CASINO_CONFIG.minBankroll,
20076
20003
  maxBetPercent: CASINO_CONFIG.maxBetPercent,
20077
- jackpotMultiplier,
20004
+ maxMultiplier,
20078
20005
  memoFormat: "{username}",
20079
20006
  message
20080
20007
  }
@@ -20097,7 +20024,19 @@ import { Api as Api53 } from "telegram";
20097
20024
  // src/casino/payment-verifier.ts
20098
20025
  import { TonClient as TonClient15, fromNano as fromNano8 } from "@ton/ton";
20099
20026
  import { Address as Address16 } from "@ton/core";
20027
+
20028
+ // src/ton/endpoint.ts
20100
20029
  import { getHttpEndpoint as getHttpEndpoint15 } from "@orbs-network/ton-access";
20030
+ var ENDPOINT_CACHE_TTL_MS = 6e4;
20031
+ var _cache = null;
20032
+ async function getCachedHttpEndpoint() {
20033
+ if (_cache && Date.now() - _cache.ts < ENDPOINT_CACHE_TTL_MS) {
20034
+ return _cache.url;
20035
+ }
20036
+ const url = await getHttpEndpoint15({ network: "mainnet" });
20037
+ _cache = { url, ts: Date.now() };
20038
+ return url;
20039
+ }
20101
20040
 
20102
20041
  // src/casino/retry.ts
20103
20042
  var DEFAULT_OPTIONS = {
@@ -20171,7 +20110,7 @@ function verifyMemo(memo, identifier) {
20171
20110
  async function verifyPayment(db, params) {
20172
20111
  try {
20173
20112
  const { botWalletAddress, betAmount, requestTime, gameType, userId } = params;
20174
- const endpoint = await getHttpEndpoint15({ network: "mainnet" });
20113
+ const endpoint = await getCachedHttpEndpoint();
20175
20114
  const client = new TonClient15({ endpoint });
20176
20115
  const botAddress = Address16.parse(botWalletAddress);
20177
20116
  const transactions = await withBlockchainRetry(
@@ -20272,67 +20211,10 @@ function updateCooldown(db, userId) {
20272
20211
  ).run(userId, now);
20273
20212
  }
20274
20213
 
20275
- // src/casino/jackpot-manager.ts
20276
- function getJackpot(db) {
20277
- const row = db.prepare("SELECT * FROM casino_jackpot WHERE id = 1").get();
20278
- return row;
20279
- }
20280
- function addToJackpot(db, amount) {
20281
- const now = Math.floor(Date.now() / 1e3);
20282
- db.prepare(
20283
- `
20284
- UPDATE casino_jackpot
20285
- SET amount = amount + ?,
20286
- updated_at = ?
20287
- WHERE id = 1
20288
- `
20289
- ).run(amount, now);
20290
- const updated = getJackpot(db);
20291
- return updated.amount;
20292
- }
20293
- function awardJackpot(db, winnerId) {
20294
- const jackpot = getJackpot(db);
20295
- const amount = jackpot.amount;
20296
- const now = Math.floor(Date.now() / 1e3);
20297
- db.prepare(
20298
- `
20299
- UPDATE casino_jackpot
20300
- SET amount = 0,
20301
- last_winner_id = ?,
20302
- last_won_at = ?,
20303
- updated_at = ?
20304
- WHERE id = 1
20305
- `
20306
- ).run(winnerId, now, now);
20307
- return { amount, winnerId };
20308
- }
20309
- function calculateHouseEdge(betAmount) {
20310
- return betAmount * (CASINO_CONFIG.houseEdgePercent / 100);
20311
- }
20312
- function processBetForJackpot(db, betAmount) {
20313
- const houseEdge = calculateHouseEdge(betAmount);
20314
- addToJackpot(db, houseEdge);
20315
- return houseEdge;
20316
- }
20317
- function shouldAwardDailyJackpot(db) {
20318
- const jackpot = getJackpot(db);
20319
- const cooldownSeconds = CASINO_CONFIG.jackpotCooldownHours * 60 * 60;
20320
- const now = Math.floor(Date.now() / 1e3);
20321
- if (jackpot.amount < CASINO_CONFIG.jackpotThreshold) {
20322
- return false;
20323
- }
20324
- if (!jackpot.lastWonAt) {
20325
- return true;
20326
- }
20327
- const timeSinceLastWin = now - jackpot.lastWonAt;
20328
- return timeSinceLastWin >= cooldownSeconds;
20329
- }
20330
-
20331
20214
  // src/casino/payout-sender.ts
20332
20215
  import { mnemonicToPrivateKey as mnemonicToPrivateKey11 } from "@ton/crypto";
20333
20216
  import { WalletContractV5R1 as WalletContractV5R111, TonClient as TonClient16, toNano as toNano25, internal as internal9 } from "@ton/ton";
20334
20217
  import { Address as Address17, SendMode as SendMode9 } from "@ton/core";
20335
- import { getHttpEndpoint as getHttpEndpoint16 } from "@orbs-network/ton-access";
20336
20218
  async function sendPayout(playerAddress, amount, message) {
20337
20219
  try {
20338
20220
  try {
@@ -20355,7 +20237,7 @@ async function sendPayout(playerAddress, amount, message) {
20355
20237
  workchain: 0,
20356
20238
  publicKey: keyPair.publicKey
20357
20239
  });
20358
- const endpoint = await getHttpEndpoint16({ network: "mainnet" });
20240
+ const endpoint = await getCachedHttpEndpoint();
20359
20241
  const client = new TonClient16({ endpoint });
20360
20242
  const contract = client.open(wallet);
20361
20243
  const seqno = await withBlockchainRetry(() => contract.getSeqno(), "getSeqno");
@@ -20397,7 +20279,7 @@ async function sendPayout(playerAddress, amount, message) {
20397
20279
  }
20398
20280
  function getWinMessage(multiplier, amount) {
20399
20281
  if (multiplier >= 5) {
20400
- return `\u{1F3B0} JACKPOT! You won ${amount.toFixed(2)} TON (${multiplier}x)`;
20282
+ return `\u{1F3B0} 777! You won ${amount.toFixed(2)} TON (${multiplier}x)`;
20401
20283
  } else if (multiplier >= 2.5) {
20402
20284
  return `\u{1F38A} Big win! You won ${amount.toFixed(2)} TON (${multiplier}x)`;
20403
20285
  } else if (multiplier >= 1.8) {
@@ -20551,11 +20433,9 @@ async function executeGame(config, params, context) {
20551
20433
  error: `Failed to get ${config.gameType} result from Telegram.`
20552
20434
  };
20553
20435
  }
20554
- const houseEdge = processBetForJackpot(context.db, bet_amount);
20555
20436
  const multiplier = config.getMultiplier(gameValue);
20556
20437
  const won = multiplier > 0;
20557
20438
  const payoutAmount = won ? bet_amount * multiplier : 0;
20558
- const jackpot = getJackpot(context.db);
20559
20439
  const recordBet = context.db.transaction(() => {
20560
20440
  context.db.prepare(
20561
20441
  `INSERT INTO casino_users (telegram_id, wallet_address, total_bets, total_wagered, last_bet_at)
@@ -20629,8 +20509,6 @@ async function executeGame(config, params, context) {
20629
20509
  bet_amount: bet_amount.toFixed(2),
20630
20510
  player_username: username,
20631
20511
  player_wallet: playerWallet,
20632
- house_edge: houseEdge.toFixed(2),
20633
- current_jackpot: jackpot.amount.toFixed(2),
20634
20512
  payment_tx_hash: paymentVerification.txHash,
20635
20513
  journal_id: journalId,
20636
20514
  message_id: messageId,
@@ -20651,8 +20529,8 @@ var casinoSpinTool = {
20651
20529
  name: "casino_spin",
20652
20530
  description: `Execute a Teleton Casino slot machine spin with full security checks.
20653
20531
 
20654
- Slot payout table (40% house edge):
20655
- - \u{1F3B0} 64 (777) = JACKPOT (5x bet)
20532
+ Slot payout table:
20533
+ - \u{1F3B0} 64 (777) = 5x bet
20656
20534
  - \u{1F3B0} 60-63 = Big win (2.5x bet)
20657
20535
  - \u{1F3B0} 55-59 = Medium win (1.8x bet)
20658
20536
  - \u{1F3B0} 43-54 = Small win (1.2x bet)
@@ -20664,8 +20542,7 @@ Process:
20664
20542
  3. Verifies TON payment with username as memo
20665
20543
  4. Auto-discovers player wallet from transaction
20666
20544
  5. Sends \u{1F3B0} slot machine animation
20667
- 6. Processes house edge (5%) to daily jackpot
20668
- 7. AUTO-PAYOUT if player wins
20545
+ 6. AUTO-PAYOUT if player wins
20669
20546
 
20670
20547
  Tell the user: "Send X TON to [casino_address] with memo: your_username"`,
20671
20548
  parameters: Type106.Object({
@@ -20693,7 +20570,7 @@ var casinoSpinExecutor = async (params, context) => {
20693
20570
  gameType: "slot",
20694
20571
  toolName: "casino_spin",
20695
20572
  assetLabel: "SPIN",
20696
- maxMultiplier: CASINO_CONFIG.slot.jackpot.multiplier,
20573
+ maxMultiplier: CASINO_CONFIG.slot.topWin.multiplier,
20697
20574
  getMultiplier: getSlotMultiplier,
20698
20575
  getInterpretation: getSlotInterpretation,
20699
20576
  maxValue: 64
@@ -20710,7 +20587,7 @@ var casinoDiceTool = {
20710
20587
  description: `Execute a Teleton Casino dice roll with full security checks.
20711
20588
 
20712
20589
  Dice payout table:
20713
- - \u{1F3B2} 6 = JACKPOT (2.5x bet)
20590
+ - \u{1F3B2} 6 = Best roll (2.5x bet)
20714
20591
  - \u{1F3B2} 5 = Big win (1.8x bet)
20715
20592
  - \u{1F3B2} 4 = Small win (1.3x bet)
20716
20593
  - \u{1F3B2} 1-3 = No win
@@ -20749,7 +20626,7 @@ var casinoDiceExecutor = async (params, context) => {
20749
20626
  gameType: "dice",
20750
20627
  toolName: "casino_dice",
20751
20628
  assetLabel: "DICE",
20752
- maxMultiplier: CASINO_CONFIG.dice.jackpot.multiplier,
20629
+ maxMultiplier: CASINO_CONFIG.dice.topWin.multiplier,
20753
20630
  getMultiplier: getDiceMultiplier,
20754
20631
  getInterpretation: getDiceInterpretation,
20755
20632
  maxValue: 6
@@ -20759,192 +20636,8 @@ var casinoDiceExecutor = async (params, context) => {
20759
20636
  );
20760
20637
  };
20761
20638
 
20762
- // src/agent/tools/casino/payout.ts
20763
- import { Type as Type108 } from "@sinclair/typebox";
20764
- import { mnemonicToPrivateKey as mnemonicToPrivateKey12 } from "@ton/crypto";
20765
- import { WalletContractV5R1 as WalletContractV5R112, TonClient as TonClient17, toNano as toNano26, internal as internal10 } from "@ton/ton";
20766
- import { Address as Address18, SendMode as SendMode10 } from "@ton/core";
20767
- import { getHttpEndpoint as getHttpEndpoint17 } from "@orbs-network/ton-access";
20768
- var casinoPayoutTool = {
20769
- name: "casino_payout",
20770
- description: `Manual payout for Teleton Casino (backup tool - normally not needed).
20771
-
20772
- NOTE: casino_spin and casino_dice already include AUTO-PAYOUT.
20773
- Only use this tool if auto-payout failed and manual intervention is needed.
20774
-
20775
- Slot payout table (40% house edge):
20776
- - Value 64 (\u{1F3B0} 777 Jackpot): 5x bet
20777
- - Values 60-63 (Big win): 2.5x bet
20778
- - Values 55-59 (Medium win): 1.8x bet
20779
- - Values 43-54 (Small win): 1.2x bet
20780
- - Values 1-42: No payout
20781
-
20782
- Sends TON to winner's address and updates journal entry.`,
20783
- parameters: Type108.Object({
20784
- player_address: Type108.String({
20785
- description: "Player's TON wallet address to send winnings"
20786
- }),
20787
- bet_amount: Type108.Number({
20788
- description: "Original bet amount in TON",
20789
- minimum: 1e-3
20790
- }),
20791
- slot_value: Type108.Number({
20792
- description: "Slot machine result (1-64)",
20793
- minimum: 1,
20794
- maximum: 64
20795
- }),
20796
- journal_entry_id: Type108.Optional(
20797
- Type108.Number({
20798
- description: "Journal entry ID to update with payout info"
20799
- })
20800
- )
20801
- })
20802
- };
20803
- var casinoPayoutExecutor = async (params, context) => {
20804
- try {
20805
- const { player_address, bet_amount, slot_value, journal_entry_id } = params;
20806
- if (!journal_entry_id || !context.db) {
20807
- return {
20808
- success: false,
20809
- error: "Security restriction: casino_payout requires a journal_entry_id from a real spin/dice result."
20810
- };
20811
- }
20812
- const journalEntry = context.db.prepare(
20813
- `SELECT id, user_id, amount_from, pnl_ton FROM journal WHERE id = ? AND type IN ('casino_spin', 'casino_dice')`
20814
- ).get(journal_entry_id);
20815
- if (!journalEntry) {
20816
- return {
20817
- success: false,
20818
- error: `No casino spin/dice found with journal entry #${journal_entry_id}. Cannot send payout without a verified game.`
20819
- };
20820
- }
20821
- if (Math.abs(journalEntry.amount_from - bet_amount) > 0.01) {
20822
- return {
20823
- success: false,
20824
- error: `Bet amount mismatch: journal says ${journalEntry.amount_from} TON but requested ${bet_amount} TON.`
20825
- };
20826
- }
20827
- const multiplier = getSlotMultiplier(slot_value);
20828
- if (multiplier === 0) {
20829
- if (journal_entry_id && context.db) {
20830
- context.db.prepare(
20831
- `
20832
- UPDATE journal
20833
- SET outcome = 'profit',
20834
- amount_to = 0,
20835
- pnl_ton = ?,
20836
- closed_at = unixepoch()
20837
- WHERE id = ?
20838
- `
20839
- ).run(bet_amount, journal_entry_id);
20840
- context.db.prepare(
20841
- `
20842
- UPDATE casino_users
20843
- SET total_losses = total_losses + 1
20844
- WHERE telegram_id = (
20845
- SELECT user_id FROM journal WHERE id = ?
20846
- )
20847
- `
20848
- ).run(journal_entry_id);
20849
- }
20850
- return {
20851
- success: true,
20852
- data: {
20853
- win: false,
20854
- multiplier: 0,
20855
- payout: 0,
20856
- slot_value,
20857
- message: `No win this time. Slot value: ${slot_value}`
20858
- }
20859
- };
20860
- }
20861
- const payout = bet_amount * multiplier;
20862
- try {
20863
- Address18.parse(player_address);
20864
- } catch (e) {
20865
- return {
20866
- success: false,
20867
- error: `Invalid player address: ${player_address}`
20868
- };
20869
- }
20870
- const walletData = loadWallet();
20871
- if (!walletData) {
20872
- return {
20873
- success: false,
20874
- error: "Casino wallet not initialized. Contact admin."
20875
- };
20876
- }
20877
- const keyPair = await mnemonicToPrivateKey12(walletData.mnemonic);
20878
- const wallet = WalletContractV5R112.create({
20879
- workchain: 0,
20880
- publicKey: keyPair.publicKey
20881
- });
20882
- const endpoint = await getHttpEndpoint17({ network: "mainnet" });
20883
- const client = new TonClient17({ endpoint });
20884
- const contract = client.open(wallet);
20885
- const seqno = await contract.getSeqno();
20886
- const winType = getSlotInterpretation(slot_value);
20887
- await contract.sendTransfer({
20888
- seqno,
20889
- secretKey: keyPair.secretKey,
20890
- sendMode: SendMode10.PAY_GAS_SEPARATELY + SendMode10.IGNORE_ERRORS,
20891
- messages: [
20892
- internal10({
20893
- to: Address18.parse(player_address),
20894
- value: toNano26(payout),
20895
- body: `${winType} You won ${payout} TON (${multiplier}x)`,
20896
- bounce: false
20897
- })
20898
- ]
20899
- });
20900
- if (journal_entry_id && context.db) {
20901
- const profit = payout - bet_amount;
20902
- context.db.prepare(
20903
- `
20904
- UPDATE journal
20905
- SET outcome = 'loss',
20906
- amount_to = ?,
20907
- pnl_ton = ?,
20908
- pnl_pct = ?,
20909
- closed_at = unixepoch()
20910
- WHERE id = ?
20911
- `
20912
- ).run(payout, -profit, -(profit / bet_amount * 100), journal_entry_id);
20913
- }
20914
- if (context.db) {
20915
- context.db.prepare(
20916
- `
20917
- UPDATE casino_users
20918
- SET total_wins = total_wins + 1,
20919
- total_won = total_won + ?
20920
- WHERE telegram_id = (
20921
- SELECT user_id FROM journal WHERE id = ?
20922
- )
20923
- `
20924
- ).run(payout, journal_entry_id || 0);
20925
- }
20926
- return {
20927
- success: true,
20928
- data: {
20929
- win: true,
20930
- multiplier,
20931
- payout: payout.toFixed(2),
20932
- slot_value,
20933
- player_address,
20934
- message: `${winType} Sent ${payout.toFixed(2)} TON (${multiplier}x) to ${player_address}`
20935
- }
20936
- };
20937
- } catch (error) {
20938
- console.error("Error in casino_payout:", error);
20939
- return {
20940
- success: false,
20941
- error: error instanceof Error ? error.message : String(error)
20942
- };
20943
- }
20944
- };
20945
-
20946
20639
  // src/agent/tools/casino/leaderboard.ts
20947
- import { Type as Type109 } from "@sinclair/typebox";
20640
+ import { Type as Type108 } from "@sinclair/typebox";
20948
20641
  var casinoLeaderboardTool = {
20949
20642
  name: "casino_leaderboard",
20950
20643
  description: `Show Teleton Casino leaderboard with top players.
@@ -20959,16 +20652,16 @@ Shows:
20959
20652
  - Total amount wagered
20960
20653
  - Total wins/losses
20961
20654
  - Win rate percentage`,
20962
- parameters: Type109.Object({
20963
- limit: Type109.Optional(
20964
- Type109.Number({
20655
+ parameters: Type108.Object({
20656
+ limit: Type108.Optional(
20657
+ Type108.Number({
20965
20658
  description: "Number of players to show (default: 10)",
20966
20659
  minimum: 1,
20967
20660
  maximum: 50
20968
20661
  })
20969
20662
  ),
20970
- type: Type109.Optional(
20971
- Type109.String({
20663
+ type: Type108.Optional(
20664
+ Type108.String({
20972
20665
  description: "Leaderboard type: winners, losers, or wagered",
20973
20666
  enum: ["winners", "losers", "wagered"]
20974
20667
  })
@@ -21073,7 +20766,7 @@ ${formattedPlayers}`
21073
20766
  };
21074
20767
 
21075
20768
  // src/agent/tools/casino/my-stats.ts
21076
- import { Type as Type110 } from "@sinclair/typebox";
20769
+ import { Type as Type109 } from "@sinclair/typebox";
21077
20770
  var casinoMyStatsTool = {
21078
20771
  name: "casino_my_stats",
21079
20772
  description: `Show the current player's personal Teleton Casino statistics.
@@ -21086,7 +20779,7 @@ Returns:
21086
20779
  - Net profit/loss
21087
20780
  - Win rate percentage
21088
20781
  - Last bet timestamp`,
21089
- parameters: Type110.Object({})
20782
+ parameters: Type109.Object({})
21090
20783
  };
21091
20784
  var casinoMyStatsExecutor = async (params, context) => {
21092
20785
  try {
@@ -21100,7 +20793,6 @@ var casinoMyStatsExecutor = async (params, context) => {
21100
20793
  total_losses,
21101
20794
  total_wagered,
21102
20795
  total_won,
21103
- created_at,
21104
20796
  last_bet_at
21105
20797
  FROM casino_users
21106
20798
  WHERE telegram_id = ?`
@@ -21116,7 +20808,6 @@ var casinoMyStatsExecutor = async (params, context) => {
21116
20808
  }
21117
20809
  const netPnL = playerStats.total_won - playerStats.total_wagered;
21118
20810
  const winRate = playerStats.total_bets > 0 ? (playerStats.total_wins / playerStats.total_bets * 100).toFixed(1) : "0";
21119
- const firstPlayDate = new Date(playerStats.created_at * 1e3).toLocaleDateString();
21120
20811
  const lastPlayDate = playerStats.last_bet_at ? new Date(playerStats.last_bet_at * 1e3).toLocaleDateString() : "Never";
21121
20812
  let statusEmoji = "\u{1F3AE}";
21122
20813
  if (netPnL > 10) statusEmoji = "\u{1F911}";
@@ -21137,7 +20828,6 @@ var casinoMyStatsExecutor = async (params, context) => {
21137
20828
  net_pnl: netPnL.toFixed(2),
21138
20829
  net_pnl_positive: netPnL >= 0,
21139
20830
  win_rate: winRate,
21140
- first_play: firstPlayDate,
21141
20831
  last_play: lastPlayDate,
21142
20832
  status_emoji: statusEmoji,
21143
20833
  message: `${statusEmoji} Teleton Casino Stats:
@@ -21158,148 +20848,8 @@ ${netPnL >= 0 ? "\u{1F4C8}" : "\u{1F4C9}"} Net P&L: ${netPnL >= 0 ? "+" : ""}${n
21158
20848
  }
21159
20849
  };
21160
20850
 
21161
- // src/agent/tools/casino/jackpot.ts
21162
- import { Type as Type111 } from "@sinclair/typebox";
21163
- var casinoJackpotInfoTool = {
21164
- name: "casino_jackpot_info",
21165
- description: `View the current Teleton Casino daily jackpot status.
21166
-
21167
- Returns:
21168
- - Current jackpot amount (accumulated from 5% house edge)
21169
- - Last winner and award date
21170
- - Whether jackpot is ready to be awarded (100+ TON, 24h+ since last award)
21171
- - Jackpot creation and update timestamps
21172
-
21173
- The jackpot accumulates 5% of every bet. Once it reaches 100 TON and 24 hours have passed since last award, it can be distributed.`,
21174
- parameters: Type111.Object({})
21175
- };
21176
- var casinoJackpotInfoExecutor = async (params, context) => {
21177
- try {
21178
- const jackpot = getJackpot(context.db);
21179
- const shouldAward = shouldAwardDailyJackpot(context.db);
21180
- const lastWinner = jackpot.lastWinnerId ? `User ${jackpot.lastWinnerId} (${new Date(jackpot.lastWonAt * 1e3).toLocaleString()})` : "Never awarded";
21181
- return {
21182
- success: true,
21183
- data: {
21184
- current_amount: jackpot.amount.toFixed(2),
21185
- last_winner: lastWinner,
21186
- ready_to_award: shouldAward,
21187
- min_threshold: "100 TON",
21188
- award_frequency: "24 hours",
21189
- created_at: new Date(jackpot.createdAt * 1e3).toISOString(),
21190
- updated_at: new Date(jackpot.updatedAt * 1e3).toISOString(),
21191
- message: shouldAward ? `\u{1F3B0} Jackpot ready! ${jackpot.amount.toFixed(2)} TON can be awarded now.` : `\u{1F4B0} Current jackpot: ${jackpot.amount.toFixed(2)} TON`
21192
- }
21193
- };
21194
- } catch (error) {
21195
- console.error("Error in casino_jackpot_info:", error);
21196
- return {
21197
- success: false,
21198
- error: error instanceof Error ? error.message : String(error)
21199
- };
21200
- }
21201
- };
21202
- var casinoAwardJackpotTool = {
21203
- name: "casino_award_jackpot",
21204
- description: `Award the Teleton Casino daily jackpot to a winner.
21205
-
21206
- Process:
21207
- 1. Checks if jackpot is ready (100+ TON, 24h+ elapsed)
21208
- 2. Awards entire jackpot amount to winner's wallet
21209
- 3. Resets jackpot to 0
21210
- 4. Records winner in jackpot history
21211
- 5. Logs to journal
21212
-
21213
- Requirements:
21214
- - Jackpot must be >= 100 TON
21215
- - Must be 24+ hours since last award (or never awarded)
21216
-
21217
- Use this to manually award the jackpot or implement automated daily draws.`,
21218
- parameters: Type111.Object({
21219
- winner_telegram_id: Type111.String({
21220
- description: "Winner's Telegram user ID"
21221
- }),
21222
- winner_wallet: Type111.String({
21223
- description: "Winner's TON wallet address for payout"
21224
- })
21225
- })
21226
- };
21227
- var casinoAwardJackpotExecutor = async (params, context) => {
21228
- try {
21229
- const { winner_telegram_id, winner_wallet } = params;
21230
- if (!shouldAwardDailyJackpot(context.db)) {
21231
- const jackpot = getJackpot(context.db);
21232
- return {
21233
- success: false,
21234
- error: `Jackpot not ready yet. Current: ${jackpot.amount.toFixed(2)} TON (minimum: 100 TON, 24h since last award required)`
21235
- };
21236
- }
21237
- const { amount, winnerId } = awardJackpot(context.db, winner_telegram_id);
21238
- if (amount === 0) {
21239
- return {
21240
- success: false,
21241
- error: "Jackpot amount is 0 TON, nothing to award."
21242
- };
21243
- }
21244
- const payoutResult = await sendPayout(
21245
- winner_wallet,
21246
- amount,
21247
- `\u{1F3B0}\u{1F3B0}\u{1F3B0} TELETON CASINO DAILY JACKPOT! You won ${amount.toFixed(2)} TON! \u{1F3B0}\u{1F3B0}\u{1F3B0}`
21248
- );
21249
- if (!payoutResult.success) {
21250
- context.db.prepare(
21251
- "UPDATE casino_jackpot SET amount = ?, last_winner_id = NULL, last_won_at = NULL WHERE id = 1"
21252
- ).run(amount);
21253
- return {
21254
- success: false,
21255
- error: `Failed to send payout: ${payoutResult.error}`
21256
- };
21257
- }
21258
- context.db.prepare(
21259
- `INSERT INTO journal (
21260
- type, action, asset_from, asset_to, amount_from, amount_to,
21261
- platform, reasoning, outcome, pnl_ton, tx_hash, tool_used,
21262
- chat_id, user_id, timestamp
21263
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, unixepoch())`
21264
- ).run(
21265
- "trade",
21266
- "casino_jackpot_award",
21267
- "JACKPOT",
21268
- "TON",
21269
- amount,
21270
- amount,
21271
- "telegram_casino",
21272
- `Daily jackpot awarded to ${winner_telegram_id}`,
21273
- "loss",
21274
- // Casino lost (paid out jackpot)
21275
- -amount,
21276
- payoutResult.txHash,
21277
- "casino_award_jackpot",
21278
- null,
21279
- // No specific chat
21280
- winner_telegram_id
21281
- );
21282
- return {
21283
- success: true,
21284
- data: {
21285
- amount: amount.toFixed(2),
21286
- winner_id: winnerId,
21287
- winner_wallet,
21288
- payout_tx: payoutResult.txHash,
21289
- message: `\u{1F3B0} Jackpot awarded! ${amount.toFixed(2)} TON sent to ${winner_wallet}`
21290
- }
21291
- };
21292
- } catch (error) {
21293
- console.error("Error in casino_award_jackpot:", error);
21294
- return {
21295
- success: false,
21296
- error: error instanceof Error ? error.message : String(error)
21297
- };
21298
- }
21299
- };
21300
-
21301
20851
  // src/agent/tools/deals/propose.ts
21302
- import { Type as Type112 } from "@sinclair/typebox";
20852
+ import { Type as Type110 } from "@sinclair/typebox";
21303
20853
 
21304
20854
  // src/deals/utils.ts
21305
20855
  function generateDealId() {
@@ -21450,36 +21000,36 @@ BEFORE proposing:
21450
21000
  3. This tool will REJECT deals that violate strategy
21451
21001
 
21452
21002
  Deal expires in 2 minutes if not accepted.`,
21453
- parameters: Type112.Object({
21454
- chatId: Type112.String({ description: "Chat ID where to send proposal" }),
21455
- userId: Type112.Number({ description: "Telegram user ID" }),
21456
- userGivesType: Type112.Union([Type112.Literal("ton"), Type112.Literal("gift")]),
21457
- userGivesTonAmount: Type112.Optional(
21458
- Type112.Number({ description: "TON amount user gives (if type=ton)" })
21003
+ parameters: Type110.Object({
21004
+ chatId: Type110.String({ description: "Chat ID where to send proposal" }),
21005
+ userId: Type110.Number({ description: "Telegram user ID" }),
21006
+ userGivesType: Type110.Union([Type110.Literal("ton"), Type110.Literal("gift")]),
21007
+ userGivesTonAmount: Type110.Optional(
21008
+ Type110.Number({ description: "TON amount user gives (if type=ton)" })
21459
21009
  ),
21460
- userGivesGiftId: Type112.Optional(
21461
- Type112.String({ description: "Gift msgId user gives (if type=gift)" })
21010
+ userGivesGiftId: Type110.Optional(
21011
+ Type110.String({ description: "Gift msgId user gives (if type=gift)" })
21462
21012
  ),
21463
- userGivesGiftSlug: Type112.Optional(
21464
- Type112.String({
21013
+ userGivesGiftSlug: Type110.Optional(
21014
+ Type110.String({
21465
21015
  description: "Gift's slug field from telegram_get_my_gifts (e.g. 'LolPop-425402'), NOT the title"
21466
21016
  })
21467
21017
  ),
21468
- userGivesValueTon: Type112.Number({ description: "Estimated TON value of what user gives" }),
21469
- agentGivesType: Type112.Union([Type112.Literal("ton"), Type112.Literal("gift")]),
21470
- agentGivesTonAmount: Type112.Optional(
21471
- Type112.Number({ description: "TON amount you give (if type=ton)" })
21018
+ userGivesValueTon: Type110.Number({ description: "Estimated TON value of what user gives" }),
21019
+ agentGivesType: Type110.Union([Type110.Literal("ton"), Type110.Literal("gift")]),
21020
+ agentGivesTonAmount: Type110.Optional(
21021
+ Type110.Number({ description: "TON amount you give (if type=ton)" })
21472
21022
  ),
21473
- agentGivesGiftId: Type112.Optional(
21474
- Type112.String({ description: "Gift msgId you give (if type=gift)" })
21023
+ agentGivesGiftId: Type110.Optional(
21024
+ Type110.String({ description: "Gift msgId you give (if type=gift)" })
21475
21025
  ),
21476
- agentGivesGiftSlug: Type112.Optional(
21477
- Type112.String({
21026
+ agentGivesGiftSlug: Type110.Optional(
21027
+ Type110.String({
21478
21028
  description: "Gift's slug field from telegram_get_my_gifts (e.g. 'LolPop-425402'), NOT the title"
21479
21029
  })
21480
21030
  ),
21481
- agentGivesValueTon: Type112.Number({ description: "Estimated TON value of what you give" }),
21482
- userUsername: Type112.Optional(Type112.String({ description: "User's @username for display" }))
21031
+ agentGivesValueTon: Type110.Number({ description: "Estimated TON value of what you give" }),
21032
+ userUsername: Type110.Optional(Type110.String({ description: "User's @username for display" }))
21483
21033
  })
21484
21034
  };
21485
21035
  var dealProposeExecutor = async (params, context) => {
@@ -21627,7 +21177,7 @@ async function sendInlineBotResult(bridge, chatId, botUsername, dealId) {
21627
21177
  }
21628
21178
 
21629
21179
  // src/agent/tools/deals/verify-payment.ts
21630
- import { Type as Type113 } from "@sinclair/typebox";
21180
+ import { Type as Type111 } from "@sinclair/typebox";
21631
21181
 
21632
21182
  // src/deals/gift-detector.ts
21633
21183
  var GiftDetector = class {
@@ -21691,16 +21241,16 @@ var GiftDetector = class {
21691
21241
  };
21692
21242
 
21693
21243
  // src/ton/transfer.ts
21694
- import { mnemonicToPrivateKey as mnemonicToPrivateKey13 } from "@ton/crypto";
21695
- import { WalletContractV5R1 as WalletContractV5R113, TonClient as TonClient18, toNano as toNano27, internal as internal11 } from "@ton/ton";
21696
- import { Address as Address19, SendMode as SendMode11 } from "@ton/core";
21697
- import { getHttpEndpoint as getHttpEndpoint18 } from "@orbs-network/ton-access";
21244
+ import { mnemonicToPrivateKey as mnemonicToPrivateKey12 } from "@ton/crypto";
21245
+ import { WalletContractV5R1 as WalletContractV5R112, TonClient as TonClient17, toNano as toNano26, internal as internal10 } from "@ton/ton";
21246
+ import { Address as Address18, SendMode as SendMode10 } from "@ton/core";
21247
+ import { getHttpEndpoint as getHttpEndpoint16 } from "@orbs-network/ton-access";
21698
21248
  async function sendTon(params) {
21699
21249
  try {
21700
21250
  const { toAddress: toAddress2, amount, comment = "", bounce = false } = params;
21701
21251
  let recipientAddress;
21702
21252
  try {
21703
- recipientAddress = Address19.parse(toAddress2);
21253
+ recipientAddress = Address18.parse(toAddress2);
21704
21254
  } catch (e) {
21705
21255
  console.error(`Invalid recipient address: ${toAddress2}`, e);
21706
21256
  return null;
@@ -21710,23 +21260,23 @@ async function sendTon(params) {
21710
21260
  console.error("Wallet not initialized");
21711
21261
  return null;
21712
21262
  }
21713
- const keyPair = await mnemonicToPrivateKey13(walletData.mnemonic);
21714
- const wallet = WalletContractV5R113.create({
21263
+ const keyPair = await mnemonicToPrivateKey12(walletData.mnemonic);
21264
+ const wallet = WalletContractV5R112.create({
21715
21265
  workchain: 0,
21716
21266
  publicKey: keyPair.publicKey
21717
21267
  });
21718
- const endpoint = await getHttpEndpoint18({ network: "mainnet" });
21719
- const client = new TonClient18({ endpoint });
21268
+ const endpoint = await getHttpEndpoint16({ network: "mainnet" });
21269
+ const client = new TonClient17({ endpoint });
21720
21270
  const contract = client.open(wallet);
21721
21271
  const seqno = await contract.getSeqno();
21722
21272
  await contract.sendTransfer({
21723
21273
  seqno,
21724
21274
  secretKey: keyPair.secretKey,
21725
- sendMode: SendMode11.PAY_GAS_SEPARATELY + SendMode11.IGNORE_ERRORS,
21275
+ sendMode: SendMode10.PAY_GAS_SEPARATELY + SendMode10.IGNORE_ERRORS,
21726
21276
  messages: [
21727
- internal11({
21277
+ internal10({
21728
21278
  to: recipientAddress,
21729
- value: toNano27(amount),
21279
+ value: toNano26(amount),
21730
21280
  body: comment,
21731
21281
  bounce
21732
21282
  })
@@ -21805,6 +21355,7 @@ async function executeDeal(dealId, db, bridge) {
21805
21355
  WHERE id = ?`
21806
21356
  ).run(txHash, dealId);
21807
21357
  console.log(`\u2705 [Deal] #${dealId} completed - TON sent - TX: ${txHash.slice(0, 8)}...`);
21358
+ logDealToJournal(deal, db, txHash);
21808
21359
  await bridge.sendMessage({
21809
21360
  chatId: deal.chat_id,
21810
21361
  text: `\u2705 **Deal #${dealId} completed!**
@@ -21875,6 +21426,7 @@ Thank you for trading! \u{1F389}`
21875
21426
  WHERE id = ?`
21876
21427
  ).run(sentMsgId, dealId);
21877
21428
  console.log(`\u2705 [Deal] #${dealId} completed - Gift transferred`);
21429
+ logDealToJournal(deal, db);
21878
21430
  await bridge.sendMessage({
21879
21431
  chatId: deal.chat_id,
21880
21432
  text: `\u2705 **Deal #${dealId} completed!**
@@ -21924,6 +21476,40 @@ Thank you for trading! \u{1F389}`
21924
21476
  };
21925
21477
  }
21926
21478
  }
21479
+ function logDealToJournal(deal, db, txHash) {
21480
+ try {
21481
+ const journal = new JournalStore(db);
21482
+ const agentGave = formatAsset(
21483
+ deal.agent_gives_type,
21484
+ deal.agent_gives_ton_amount,
21485
+ deal.agent_gives_gift_slug
21486
+ );
21487
+ const agentReceived = formatAsset(
21488
+ deal.user_gives_type,
21489
+ deal.user_gives_ton_amount,
21490
+ deal.user_gives_gift_slug
21491
+ );
21492
+ const isGiftTrade = deal.agent_gives_type === "gift" || deal.user_gives_type === "gift";
21493
+ journal.addEntry({
21494
+ type: isGiftTrade ? "gift" : "trade",
21495
+ action: deal.agent_gives_type === "gift" ? "sell_gift" : "buy_gift",
21496
+ asset_from: agentGave,
21497
+ asset_to: agentReceived,
21498
+ amount_from: deal.agent_gives_ton_amount ?? void 0,
21499
+ amount_to: deal.user_gives_ton_amount ?? void 0,
21500
+ counterparty: String(deal.user_telegram_id),
21501
+ platform: "telegram_deals",
21502
+ outcome: "neutral",
21503
+ // P&L computed later when floor prices are known
21504
+ tx_hash: txHash,
21505
+ tool_used: "deal_executor",
21506
+ chat_id: deal.chat_id,
21507
+ user_id: deal.user_telegram_id
21508
+ });
21509
+ } catch (error) {
21510
+ console.error(`\u26A0\uFE0F [Deal] Failed to log deal #${deal.id} to journal:`, error);
21511
+ }
21512
+ }
21927
21513
  async function autoExecuteAfterVerification(dealId, db, bridge) {
21928
21514
  console.log(`\u{1F504} [Deal] Auto-executing deal #${dealId} after verification...`);
21929
21515
  const result = await executeDeal(dealId, db, bridge);
@@ -21957,8 +21543,8 @@ Updates deal status to 'verified' if successful.
21957
21543
  Auto-triggers executor after verification.
21958
21544
 
21959
21545
  IMPORTANT: Only call this for deals with status = 'accepted'.`,
21960
- parameters: Type113.Object({
21961
- dealId: Type113.String({ description: "Deal ID to verify payment for" })
21546
+ parameters: Type111.Object({
21547
+ dealId: Type111.String({ description: "Deal ID to verify payment for" })
21962
21548
  })
21963
21549
  };
21964
21550
  var dealVerifyPaymentExecutor = async (params, context) => {
@@ -21970,6 +21556,13 @@ var dealVerifyPaymentExecutor = async (params, context) => {
21970
21556
  error: `Deal #${params.dealId} not found`
21971
21557
  };
21972
21558
  }
21559
+ const adminIds = context.config?.telegram.admin_ids ?? [];
21560
+ if (context.senderId !== deal.user_telegram_id && !adminIds.includes(context.senderId)) {
21561
+ return {
21562
+ success: false,
21563
+ error: `\u26D4 You can only verify payment for your own deals.`
21564
+ };
21565
+ }
21973
21566
  if (deal.status !== "accepted") {
21974
21567
  return {
21975
21568
  success: false,
@@ -22122,7 +21715,7 @@ var dealVerifyPaymentExecutor = async (params, context) => {
22122
21715
  };
22123
21716
 
22124
21717
  // src/agent/tools/deals/status.ts
22125
- import { Type as Type114 } from "@sinclair/typebox";
21718
+ import { Type as Type112 } from "@sinclair/typebox";
22126
21719
  var dealStatusTool = {
22127
21720
  name: "deal_status",
22128
21721
  description: `Check the status and details of a deal by ID.
@@ -22134,8 +21727,8 @@ Shows:
22134
21727
  - Timestamps (created, expires, verified, completed)
22135
21728
  - Payment/transfer tracking info (TX hashes, msgIds)
22136
21729
  - Profit calculation`,
22137
- parameters: Type114.Object({
22138
- dealId: Type114.String({ description: "Deal ID to check status for" })
21730
+ parameters: Type112.Object({
21731
+ dealId: Type112.String({ description: "Deal ID to check status for" })
22139
21732
  })
22140
21733
  };
22141
21734
  var dealStatusExecutor = async (params, context) => {
@@ -22147,6 +21740,13 @@ var dealStatusExecutor = async (params, context) => {
22147
21740
  error: `Deal #${params.dealId} not found`
22148
21741
  };
22149
21742
  }
21743
+ const adminIds = context.config?.telegram.admin_ids ?? [];
21744
+ if (context.senderId !== deal.user_telegram_id && !adminIds.includes(context.senderId)) {
21745
+ return {
21746
+ success: false,
21747
+ error: `\u26D4 You can only view your own deals.`
21748
+ };
21749
+ }
22150
21750
  const createdAt = new Date(deal.created_at * 1e3).toISOString();
22151
21751
  const expiresAt = new Date(deal.expires_at * 1e3).toISOString();
22152
21752
  const verifiedAt = deal.user_payment_verified_at ? new Date(deal.user_payment_verified_at * 1e3).toISOString() : null;
@@ -22247,7 +21847,7 @@ ${deal.notes ? `
22247
21847
  };
22248
21848
 
22249
21849
  // src/agent/tools/deals/list.ts
22250
- import { Type as Type115 } from "@sinclair/typebox";
21850
+ import { Type as Type113 } from "@sinclair/typebox";
22251
21851
  var dealListTool = {
22252
21852
  name: "deal_list",
22253
21853
  description: `List recent deals with optional filters.
@@ -22258,21 +21858,26 @@ Filters:
22258
21858
  - limit: Max results (default 20)
22259
21859
 
22260
21860
  Returns summary of each deal with ID, status, parties, trade details, timestamps.`,
22261
- parameters: Type115.Object({
22262
- status: Type115.Optional(
22263
- Type115.String({
21861
+ parameters: Type113.Object({
21862
+ status: Type113.Optional(
21863
+ Type113.String({
22264
21864
  description: "Filter by status: proposed, accepted, verified, completed, declined, expired, cancelled, failed"
22265
21865
  })
22266
21866
  ),
22267
- userId: Type115.Optional(Type115.Number({ description: "Filter by user's Telegram ID" })),
22268
- limit: Type115.Optional(
22269
- Type115.Number({ description: "Max results to return (default 20)", minimum: 1, maximum: 100 })
21867
+ userId: Type113.Optional(Type113.Number({ description: "Filter by user's Telegram ID" })),
21868
+ limit: Type113.Optional(
21869
+ Type113.Number({ description: "Max results to return (default 20)", minimum: 1, maximum: 100 })
22270
21870
  )
22271
21871
  })
22272
21872
  };
22273
21873
  var dealListExecutor = async (params, context) => {
22274
21874
  try {
22275
- const { status, userId, limit = 20 } = params;
21875
+ const { status, limit = 20 } = params;
21876
+ let { userId } = params;
21877
+ const adminIds = context.config?.telegram.admin_ids ?? [];
21878
+ if (!adminIds.includes(context.senderId)) {
21879
+ userId = context.senderId;
21880
+ }
22276
21881
  let query = `SELECT * FROM deals WHERE 1=1`;
22277
21882
  const queryParams = [];
22278
21883
  if (status) {
@@ -22364,7 +21969,7 @@ var dealListExecutor = async (params, context) => {
22364
21969
  };
22365
21970
 
22366
21971
  // src/agent/tools/deals/cancel.ts
22367
- import { Type as Type116 } from "@sinclair/typebox";
21972
+ import { Type as Type114 } from "@sinclair/typebox";
22368
21973
  var dealCancelTool = {
22369
21974
  name: "deal_cancel",
22370
21975
  description: `Cancel an active deal (proposed or accepted status only).
@@ -22380,9 +21985,9 @@ Use this when:
22380
21985
  - External circumstances make deal impossible
22381
21986
 
22382
21987
  The deal status will be set to 'cancelled' and cannot be resumed.`,
22383
- parameters: Type116.Object({
22384
- dealId: Type116.String({ description: "Deal ID to cancel" }),
22385
- reason: Type116.Optional(Type116.String({ description: "Reason for cancellation (optional)" }))
21988
+ parameters: Type114.Object({
21989
+ dealId: Type114.String({ description: "Deal ID to cancel" }),
21990
+ reason: Type114.Optional(Type114.String({ description: "Reason for cancellation (optional)" }))
22386
21991
  })
22387
21992
  };
22388
21993
  var dealCancelExecutor = async (params, context) => {
@@ -22395,6 +22000,13 @@ var dealCancelExecutor = async (params, context) => {
22395
22000
  error: `Deal #${dealId} not found`
22396
22001
  };
22397
22002
  }
22003
+ const adminIds = context.config?.telegram.admin_ids ?? [];
22004
+ if (context.senderId !== deal.user_telegram_id && !adminIds.includes(context.senderId)) {
22005
+ return {
22006
+ success: false,
22007
+ error: `\u26D4 You can only cancel your own deals.`
22008
+ };
22009
+ }
22398
22010
  const cancellableStatuses = ["proposed", "accepted"];
22399
22011
  if (!cancellableStatuses.includes(deal.status)) {
22400
22012
  return {
@@ -22468,45 +22080,57 @@ function registerAllTools(registry, config) {
22468
22080
  registry.register(telegramGetDialogsTool, telegramGetDialogsExecutor);
22469
22081
  registry.register(telegramMarkAsReadTool, telegramMarkAsReadExecutor);
22470
22082
  registry.register(telegramGetChatInfoTool, telegramGetChatInfoExecutor);
22471
- registry.register(telegramJoinChannelTool, telegramJoinChannelExecutor);
22472
- registry.register(telegramLeaveChannelTool, telegramLeaveChannelExecutor);
22083
+ registry.register(telegramJoinChannelTool, telegramJoinChannelExecutor, "dm-only");
22084
+ registry.register(telegramLeaveChannelTool, telegramLeaveChannelExecutor, "dm-only");
22473
22085
  registry.register(telegramGetMeTool, telegramGetMeExecutor);
22474
22086
  registry.register(telegramGetParticipantsTool, telegramGetParticipantsExecutor);
22475
- registry.register(telegramKickUserTool, telegramKickUserExecutor);
22476
- registry.register(telegramBanUserTool, telegramBanUserExecutor);
22477
- registry.register(telegramUnbanUserTool, telegramUnbanUserExecutor);
22478
- registry.register(telegramCreateGroupTool, telegramCreateGroupExecutor);
22479
- registry.register(telegramSetChatPhotoTool, telegramSetChatPhotoExecutor);
22480
- registry.register(telegramBlockUserTool, telegramBlockUserExecutor);
22481
- registry.register(telegramGetBlockedTool, telegramGetBlockedExecutor);
22087
+ registry.register(telegramKickUserTool, telegramKickUserExecutor, "group-only");
22088
+ registry.register(telegramBanUserTool, telegramBanUserExecutor, "group-only");
22089
+ registry.register(telegramUnbanUserTool, telegramUnbanUserExecutor, "group-only");
22090
+ registry.register(telegramCreateGroupTool, telegramCreateGroupExecutor, "dm-only");
22091
+ registry.register(telegramSetChatPhotoTool, telegramSetChatPhotoExecutor, "group-only");
22092
+ registry.register(telegramBlockUserTool, telegramBlockUserExecutor, "dm-only");
22093
+ registry.register(telegramGetBlockedTool, telegramGetBlockedExecutor, "dm-only");
22482
22094
  registry.register(telegramGetCommonChatsTool, telegramGetCommonChatsExecutor);
22483
- registry.register(telegramSendStoryTool, telegramSendStoryExecutor);
22095
+ registry.register(telegramSendStoryTool, telegramSendStoryExecutor, "dm-only");
22484
22096
  registry.register(telegramGetFoldersTool, telegramGetFoldersExecutor);
22485
22097
  registry.register(telegramCreateFolderTool, telegramCreateFolderExecutor);
22486
22098
  registry.register(telegramAddChatToFolderTool, telegramAddChatToFolderExecutor);
22487
- registry.register(telegramCreateChannelTool, telegramCreateChannelExecutor);
22488
- registry.register(telegramUpdateProfileTool, telegramUpdateProfileExecutor);
22489
- registry.register(telegramSetBioTool, telegramSetBioExecutor);
22490
- registry.register(telegramSetUsernameTool, telegramSetUsernameExecutor);
22099
+ registry.register(telegramCreateChannelTool, telegramCreateChannelExecutor, "dm-only");
22100
+ registry.register(telegramUpdateProfileTool, telegramUpdateProfileExecutor, "dm-only");
22101
+ registry.register(telegramSetBioTool, telegramSetBioExecutor, "dm-only");
22102
+ registry.register(telegramSetUsernameTool, telegramSetUsernameExecutor, "dm-only");
22491
22103
  registry.register(telegramDeleteMessageTool, telegramDeleteMessageExecutor);
22492
22104
  registry.register(telegramDownloadMediaTool, telegramDownloadMediaExecutor);
22493
22105
  registry.register(visionAnalyzeTool, visionAnalyzeExecutor);
22494
- registry.register(telegramGetStarsBalanceTool, telegramGetStarsBalanceExecutor);
22495
- registry.register(telegramGetStarsTransactionsTool, telegramGetStarsTransactionsExecutor);
22106
+ registry.register(telegramGetStarsBalanceTool, telegramGetStarsBalanceExecutor, "dm-only");
22107
+ registry.register(
22108
+ telegramGetStarsTransactionsTool,
22109
+ telegramGetStarsTransactionsExecutor,
22110
+ "dm-only"
22111
+ );
22496
22112
  registry.register(telegramGetAvailableGiftsTool, telegramGetAvailableGiftsExecutor);
22497
- registry.register(telegramSendGiftTool, telegramSendGiftExecutor);
22113
+ registry.register(telegramSendGiftTool, telegramSendGiftExecutor, "dm-only");
22498
22114
  registry.register(telegramGetMyGiftsTool, telegramGetMyGiftsExecutor);
22499
- registry.register(telegramTransferCollectibleTool, telegramTransferCollectibleExecutor);
22500
- registry.register(telegramSetCollectiblePriceTool, telegramSetCollectiblePriceExecutor);
22115
+ registry.register(
22116
+ telegramTransferCollectibleTool,
22117
+ telegramTransferCollectibleExecutor,
22118
+ "dm-only"
22119
+ );
22120
+ registry.register(
22121
+ telegramSetCollectiblePriceTool,
22122
+ telegramSetCollectiblePriceExecutor,
22123
+ "dm-only"
22124
+ );
22501
22125
  registry.register(telegramGetResaleGiftsTool, telegramGetResaleGiftsExecutor);
22502
- registry.register(telegramBuyResaleGiftTool, telegramBuyResaleGiftExecutor);
22503
- registry.register(telegramSetGiftStatusTool, telegramSetGiftStatusExecutor);
22504
- registry.register(memoryWriteTool, memoryWriteExecutor);
22126
+ registry.register(telegramBuyResaleGiftTool, telegramBuyResaleGiftExecutor, "dm-only");
22127
+ registry.register(telegramSetGiftStatusTool, telegramSetGiftStatusExecutor, "dm-only");
22128
+ registry.register(memoryWriteTool, memoryWriteExecutor, "dm-only");
22505
22129
  registry.register(memoryReadTool, memoryReadExecutor);
22506
22130
  registry.register(telegramGetUserInfoTool, telegramGetUserInfoExecutor);
22507
22131
  registry.register(telegramCheckUsernameTool, telegramCheckUsernameExecutor);
22508
- registry.register(telegramEditChannelInfoTool, telegramEditChannelInfoExecutor);
22509
- registry.register(telegramInviteToChannelTool, telegramInviteToChannelExecutor);
22132
+ registry.register(telegramEditChannelInfoTool, telegramEditChannelInfoExecutor, "dm-only");
22133
+ registry.register(telegramInviteToChannelTool, telegramInviteToChannelExecutor, "dm-only");
22510
22134
  if (config.market.enabled || config.deals.enabled) {
22511
22135
  registry.register(marketGetFloorTool, marketGetFloorExecutor);
22512
22136
  registry.register(marketSearchTool, marketSearchExecutor);
@@ -22516,12 +22140,12 @@ function registerAllTools(registry, config) {
22516
22140
  registry.register(tonGetAddressTool, tonGetAddressExecutor);
22517
22141
  registry.register(tonGetBalanceTool, tonGetBalanceExecutor);
22518
22142
  registry.register(tonPriceTool, tonPriceExecutor);
22519
- registry.register(tonSendTool, tonSendExecutor);
22143
+ registry.register(tonSendTool, tonSendExecutor, "dm-only");
22520
22144
  registry.register(tonGetTransactionsTool, tonGetTransactionsExecutor);
22521
22145
  registry.register(tonMyTransactionsTool, tonMyTransactionsExecutor);
22522
22146
  registry.register(jettonBalancesTool, jettonBalancesExecutor);
22523
- registry.register(jettonSwapTool, jettonSwapExecutor);
22524
- registry.register(jettonSendTool, jettonSendExecutor);
22147
+ registry.register(jettonSwapTool, jettonSwapExecutor, "dm-only");
22148
+ registry.register(jettonSendTool, jettonSendExecutor, "dm-only");
22525
22149
  registry.register(jettonInfoTool, jettonInfoExecutor);
22526
22150
  registry.register(jettonPriceTool, jettonPriceExecutor);
22527
22151
  registry.register(jettonSearchTool, jettonSearchExecutor);
@@ -22533,63 +22157,60 @@ function registerAllTools(registry, config) {
22533
22157
  registry.register(dnsCheckTool, dnsCheckExecutor);
22534
22158
  registry.register(dnsAuctionsTool, dnsAuctionsExecutor);
22535
22159
  registry.register(dnsResolveTool, dnsResolveExecutor);
22536
- registry.register(dnsStartAuctionTool, dnsStartAuctionExecutor);
22537
- registry.register(dnsBidTool, dnsBidExecutor);
22538
- registry.register(dnsLinkTool, dnsLinkExecutor);
22539
- registry.register(dnsUnlinkTool, dnsUnlinkExecutor);
22160
+ registry.register(dnsStartAuctionTool, dnsStartAuctionExecutor, "dm-only");
22161
+ registry.register(dnsBidTool, dnsBidExecutor, "dm-only");
22162
+ registry.register(dnsLinkTool, dnsLinkExecutor, "dm-only");
22163
+ registry.register(dnsUnlinkTool, dnsUnlinkExecutor, "dm-only");
22540
22164
  registry.register(dedustQuoteTool, dedustQuoteExecutor);
22541
- registry.register(dedustSwapTool, dedustSwapExecutor);
22165
+ registry.register(dedustSwapTool, dedustSwapExecutor, "dm-only");
22542
22166
  registry.register(dedustPoolsTool, dedustPoolsExecutor);
22543
22167
  registry.register(dexQuoteTool, dexQuoteExecutor);
22544
- registry.register(dexSwapTool, dexSwapExecutor);
22545
- registry.register(journalLogTool, journalLogExecutor);
22168
+ registry.register(dexSwapTool, dexSwapExecutor, "dm-only");
22169
+ registry.register(journalLogTool, journalLogExecutor, "dm-only");
22546
22170
  registry.register(journalQueryTool, journalQueryExecutor);
22547
- registry.register(journalUpdateTool, journalUpdateExecutor);
22171
+ registry.register(journalUpdateTool, journalUpdateExecutor, "dm-only");
22548
22172
  registry.register(workspaceListTool, workspaceListExecutor);
22549
22173
  registry.register(workspaceReadTool, workspaceReadExecutor);
22550
- registry.register(workspaceWriteTool, workspaceWriteExecutor);
22551
- registry.register(workspaceDeleteTool, workspaceDeleteExecutor);
22174
+ registry.register(workspaceWriteTool, workspaceWriteExecutor, "dm-only");
22175
+ registry.register(workspaceDeleteTool, workspaceDeleteExecutor, "dm-only");
22552
22176
  registry.register(workspaceInfoTool, workspaceInfoExecutor);
22553
- registry.register(workspaceRenameTool, workspaceRenameExecutor);
22177
+ registry.register(workspaceRenameTool, workspaceRenameExecutor, "dm-only");
22554
22178
  if (config.casino.enabled) {
22555
22179
  registry.register(casinoBalanceTool, casinoBalanceExecutor);
22556
22180
  registry.register(casinoSpinTool, casinoSpinExecutor);
22557
22181
  registry.register(casinoDiceTool, casinoDiceExecutor);
22558
- registry.register(casinoPayoutTool, casinoPayoutExecutor);
22559
22182
  registry.register(casinoLeaderboardTool, casinoLeaderboardExecutor);
22560
22183
  registry.register(casinoMyStatsTool, casinoMyStatsExecutor);
22561
- registry.register(casinoJackpotInfoTool, casinoJackpotInfoExecutor);
22562
- registry.register(casinoAwardJackpotTool, casinoAwardJackpotExecutor);
22563
22184
  }
22564
22185
  if (config.deals.enabled) {
22565
- registry.register(dealProposeTool, dealProposeExecutor);
22566
- registry.register(dealVerifyPaymentTool, dealVerifyPaymentExecutor);
22186
+ registry.register(dealProposeTool, dealProposeExecutor, "dm-only");
22187
+ registry.register(dealVerifyPaymentTool, dealVerifyPaymentExecutor, "dm-only");
22567
22188
  registry.register(dealStatusTool, dealStatusExecutor);
22568
22189
  registry.register(dealListTool, dealListExecutor);
22569
- registry.register(dealCancelTool, dealCancelExecutor);
22190
+ registry.register(dealCancelTool, dealCancelExecutor, "dm-only");
22570
22191
  }
22571
22192
  }
22572
22193
 
22573
22194
  // src/agent/tools/plugin-loader.ts
22574
- import { readdirSync as readdirSync6, existsSync as existsSync17, statSync as statSync2 } from "fs";
22575
- import { join as join14 } from "path";
22195
+ import { readdirSync as readdirSync6, existsSync as existsSync16, statSync as statSync2 } from "fs";
22196
+ import { join as join13 } from "path";
22576
22197
  import { pathToFileURL } from "url";
22577
22198
  async function loadPlugins(registry) {
22578
22199
  const pluginsDir = WORKSPACE_PATHS.PLUGINS_DIR;
22579
- if (!existsSync17(pluginsDir)) {
22200
+ if (!existsSync16(pluginsDir)) {
22580
22201
  return 0;
22581
22202
  }
22582
22203
  const entries = readdirSync6(pluginsDir);
22583
22204
  let totalRegistered = 0;
22584
22205
  for (const entry of entries) {
22585
- const entryPath = join14(pluginsDir, entry);
22206
+ const entryPath = join13(pluginsDir, entry);
22586
22207
  let modulePath = null;
22587
22208
  const stat = statSync2(entryPath);
22588
22209
  if (stat.isFile() && entry.endsWith(".js")) {
22589
22210
  modulePath = entryPath;
22590
22211
  } else if (stat.isDirectory()) {
22591
- const indexPath = join14(entryPath, "index.js");
22592
- if (existsSync17(indexPath)) {
22212
+ const indexPath = join13(entryPath, "index.js");
22213
+ if (existsSync16(indexPath)) {
22593
22214
  modulePath = indexPath;
22594
22215
  }
22595
22216
  }
@@ -23874,7 +23495,7 @@ var TonnetApp = class {
23874
23495
  apiId: this.config.telegram.api_id,
23875
23496
  apiHash: this.config.telegram.api_hash,
23876
23497
  phone: this.config.telegram.phone,
23877
- sessionPath: join15(TELETON_ROOT, "telegram_session.txt"),
23498
+ sessionPath: join14(TELETON_ROOT, "telegram_session.txt"),
23878
23499
  connectionRetries: TELEGRAM_CONNECTION_RETRIES,
23879
23500
  autoReconnect: true,
23880
23501
  floodSleepThreshold: TELEGRAM_FLOOD_SLEEP_THRESHOLD
@@ -23882,7 +23503,7 @@ var TonnetApp = class {
23882
23503
  const VECTOR_DIMENSIONS = 512;
23883
23504
  const memory = initializeMemory({
23884
23505
  database: {
23885
- path: join15(TELETON_ROOT, "memory.db"),
23506
+ path: join14(TELETON_ROOT, "memory.db"),
23886
23507
  enableVectorSearch: false,
23887
23508
  vectorDimensions: VECTOR_DIMENSIONS
23888
23509
  },
@@ -23891,7 +23512,7 @@ var TonnetApp = class {
23891
23512
  apiKey: "",
23892
23513
  model: ""
23893
23514
  },
23894
- workspaceDir: join15(TELETON_ROOT)
23515
+ workspaceDir: join14(TELETON_ROOT)
23895
23516
  });
23896
23517
  const db = getDatabase().getDb();
23897
23518
  if (this.config.market.enabled || this.config.deals.enabled) {
@@ -23941,11 +23562,13 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
23941
23562
  `\u26A0\uFE0F Tool count (${this.toolCount}) exceeds ${providerMeta.displayName} limit (${providerMeta.toolLimit})`
23942
23563
  );
23943
23564
  }
23944
- const { migrateSessionsToDb } = await import("./migrate-F256Q7LW.js");
23565
+ const { migrateSessionsToDb } = await import("./migrate-4Z74FLKS.js");
23945
23566
  migrateSessionsToDb();
23567
+ const { cleanupOldTranscripts } = await import("./transcript-DF2Y6CFY.js");
23568
+ cleanupOldTranscripts(30);
23946
23569
  const memory = initializeMemory({
23947
23570
  database: {
23948
- path: join15(TELETON_ROOT, "memory.db"),
23571
+ path: join14(TELETON_ROOT, "memory.db"),
23949
23572
  enableVectorSearch: false,
23950
23573
  vectorDimensions: 512
23951
23574
  },
@@ -23954,7 +23577,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
23954
23577
  apiKey: "",
23955
23578
  model: ""
23956
23579
  },
23957
- workspaceDir: join15(TELETON_ROOT)
23580
+ workspaceDir: join14(TELETON_ROOT)
23958
23581
  });
23959
23582
  const indexResult = await memory.knowledge.indexAll();
23960
23583
  const db = getDatabase();
@@ -24125,7 +23748,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
24125
23748
  const taskId = match[1];
24126
23749
  const { getTaskStore } = await import("./tasks-M3QDPTGY.js");
24127
23750
  const { executeScheduledTask } = await import("./task-executor-MNI4VIZL.js");
24128
- const { getDatabase: getDatabase2 } = await import("./memory-Q755V5UK.js");
23751
+ const { getDatabase: getDatabase2 } = await import("./memory-RBJIBZ5L.js");
24129
23752
  const db = getDatabase2().getDb();
24130
23753
  const taskStore = getTaskStore(db);
24131
23754
  const task = taskStore.getTask(taskId);
@@ -24200,7 +23823,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
24200
23823
  try {
24201
23824
  const { getTaskStore } = await import("./tasks-M3QDPTGY.js");
24202
23825
  const { TaskDependencyResolver } = await import("./task-dependency-resolver-CWG6DTU4.js");
24203
- const { getDatabase: getDatabase2 } = await import("./memory-Q755V5UK.js");
23826
+ const { getDatabase: getDatabase2 } = await import("./memory-RBJIBZ5L.js");
24204
23827
  const db = getDatabase2().getDb();
24205
23828
  const taskStore = getTaskStore(db);
24206
23829
  const match = message.text.match(/^\[TASK:([^\]]+)\]/);