teleton 0.8.1 → 0.8.3

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.
Files changed (43) hide show
  1. package/dist/bootstrap-DDFVEMYI.js +128 -0
  2. package/dist/{server-3FHI2SEB.js → chunk-2ERTYRHA.js} +26 -372
  3. package/dist/{chunk-5FNWBZ5K.js → chunk-33Z47EXI.js} +264 -274
  4. package/dist/{chunk-3S4GGLLR.js → chunk-35MX4ZUI.js} +23 -104
  5. package/dist/chunk-3UFPFWYP.js +12 -0
  6. package/dist/chunk-5SEMA47R.js +75 -0
  7. package/dist/{chunk-PHSAHTK4.js → chunk-6OOHHJ4N.js} +3 -108
  8. package/dist/{chunk-CGOXE4WP.js → chunk-7MWKT67G.js} +467 -914
  9. package/dist/chunk-AEHTQI3H.js +142 -0
  10. package/dist/{chunk-S6PHGKOC.js → chunk-AERHOXGC.js} +88 -322
  11. package/dist/chunk-ALKAAG4O.js +487 -0
  12. package/dist/{chunk-UP55PXFH.js → chunk-C4NKJT2Z.js} +8 -0
  13. package/dist/chunk-CUE4UZXR.js +129 -0
  14. package/dist/chunk-FUNF6H4W.js +251 -0
  15. package/dist/{chunk-7U7BOHCL.js → chunk-GHMXWAXI.js} +147 -63
  16. package/dist/{chunk-QBHRXLZS.js → chunk-H7MFXJZK.js} +2 -2
  17. package/dist/{chunk-QV2GLOTK.js → chunk-LC4TV3KL.js} +1 -1
  18. package/dist/{chunk-AYWEJCDB.js → chunk-LVTKJQ7O.js} +12 -10
  19. package/dist/{chunk-RCMD3U65.js → chunk-NQ6FZKCE.js} +13 -0
  20. package/dist/chunk-NVKBBTI6.js +128 -0
  21. package/dist/{setup-server-32XGDPE6.js → chunk-OIMAE24Q.js} +55 -216
  22. package/dist/{chunk-OJCLKU5Z.js → chunk-WFTC3JJW.js} +16 -0
  23. package/dist/chunk-WTDAICGT.js +175 -0
  24. package/dist/{chunk-KVXV7EF7.js → chunk-XDZDOKIF.js} +2 -2
  25. package/dist/cli/index.js +91 -27
  26. package/dist/{client-MPHPIZB6.js → client-5KD25NOP.js} +5 -4
  27. package/dist/{get-my-gifts-CC6HAVWB.js → get-my-gifts-Y7EN7RK4.js} +3 -3
  28. package/dist/index.js +19 -13
  29. package/dist/local-IHKJFQJS.js +9 -0
  30. package/dist/{memory-UBHM7ILG.js → memory-QMJRM3XJ.js} +9 -5
  31. package/dist/memory-hook-VUNWZ3NY.js +19 -0
  32. package/dist/{migrate-UBBEJ5BL.js → migrate-5VBAP52B.js} +5 -4
  33. package/dist/server-JF6FX772.js +813 -0
  34. package/dist/server-N4T7E25M.js +396 -0
  35. package/dist/setup-server-IX3BFPPH.js +217 -0
  36. package/dist/{store-M5IMUQCL.js → store-BY7S6IFN.js} +6 -5
  37. package/dist/{task-dependency-resolver-RR2O5S7B.js → task-dependency-resolver-L6UUMTHK.js} +2 -2
  38. package/dist/{task-executor-6W5HRX5C.js → task-executor-XBNJLUCS.js} +2 -2
  39. package/dist/{tool-adapter-IH5VGBOO.js → tool-adapter-IVX2XQJE.js} +1 -1
  40. package/dist/{tool-index-PMAOXWUA.js → tool-index-FTERJSZK.js} +4 -3
  41. package/dist/{transcript-NGDPSNIH.js → transcript-IM7G25OS.js} +2 -2
  42. package/package.json +4 -2
  43. package/dist/chunk-XBE4JB7C.js +0 -8
@@ -1,5 +1,4 @@
1
1
  import {
2
- ConfigSchema,
3
2
  getCachedTonClient,
4
3
  getKeyPair,
5
4
  getTonPrice,
@@ -7,7 +6,13 @@ import {
7
6
  getWalletBalance,
8
7
  invalidateTonClientCache,
9
8
  loadWallet
10
- } from "./chunk-S6PHGKOC.js";
9
+ } from "./chunk-FUNF6H4W.js";
10
+ import {
11
+ expandPath
12
+ } from "./chunk-AEHTQI3H.js";
13
+ import {
14
+ ConfigSchema
15
+ } from "./chunk-AERHOXGC.js";
11
16
  import {
12
17
  getOrCreateSession,
13
18
  getSession,
@@ -15,7 +20,22 @@ import {
15
20
  resetSessionWithPolicy,
16
21
  shouldResetSession,
17
22
  updateSession
18
- } from "./chunk-KVXV7EF7.js";
23
+ } from "./chunk-XDZDOKIF.js";
24
+ import {
25
+ ContextBuilder,
26
+ createDbWrapper,
27
+ getDatabase,
28
+ migrateFromMainDb,
29
+ openModuleDb
30
+ } from "./chunk-GHMXWAXI.js";
31
+ import {
32
+ saveSessionMemory,
33
+ summarizeWithFallback
34
+ } from "./chunk-ALKAAG4O.js";
35
+ import {
36
+ getErrorMessage,
37
+ isHttpError
38
+ } from "./chunk-3UFPFWYP.js";
19
39
  import {
20
40
  Mi,
21
41
  Mn,
@@ -26,41 +46,11 @@ import {
26
46
  ut,
27
47
  ye
28
48
  } from "./chunk-7TECSLJ4.js";
29
- import {
30
- getErrorMessage
31
- } from "./chunk-XBE4JB7C.js";
32
- import {
33
- chatWithContext,
34
- getEffectiveApiKey,
35
- getProviderModel,
36
- getUtilityModel,
37
- loadContextFromTranscript
38
- } from "./chunk-AYWEJCDB.js";
39
- import {
40
- getProviderMetadata,
41
- getSupportedProviders
42
- } from "./chunk-PHSAHTK4.js";
43
- import {
44
- appendToTranscript,
45
- archiveTranscript,
46
- transcriptExists
47
- } from "./chunk-QV2GLOTK.js";
48
- import {
49
- ContextBuilder,
50
- createDbWrapper,
51
- getDatabase,
52
- migrateFromMainDb,
53
- openModuleDb
54
- } from "./chunk-7U7BOHCL.js";
55
49
  import {
56
50
  GECKOTERMINAL_API_URL,
57
51
  tonapiFetch
58
52
  } from "./chunk-VFA7QMCZ.js";
59
53
  import {
60
- ADAPTIVE_CHUNK_RATIO_BASE,
61
- ADAPTIVE_CHUNK_RATIO_MIN,
62
- ADAPTIVE_CHUNK_RATIO_TRIGGER,
63
- CHARS_PER_TOKEN_ESTIMATE,
64
54
  COMPACTION_KEEP_RECENT,
65
55
  COMPACTION_MAX_MESSAGES,
66
56
  COMPACTION_MAX_TOKENS_RATIO,
@@ -72,21 +62,28 @@ import {
72
62
  DEFAULT_MAX_SUMMARY_TOKENS,
73
63
  DEFAULT_MAX_TOKENS,
74
64
  DEFAULT_SOFT_THRESHOLD_TOKENS,
75
- DEFAULT_SUMMARY_FALLBACK_TOKENS,
65
+ EMBEDDING_QUERY_MAX_CHARS,
76
66
  FALLBACK_SOFT_THRESHOLD_TOKENS,
77
67
  MASKING_KEEP_RECENT_COUNT,
78
68
  MAX_TOOL_RESULT_SIZE,
79
69
  MEMORY_FLUSH_RECENT_MESSAGES,
80
- OVERSIZED_MESSAGE_RATIO,
81
70
  PAYMENT_TOLERANCE_RATIO,
82
71
  RATE_LIMIT_MAX_RETRIES,
83
72
  RESULT_TRUNCATION_KEEP_CHARS,
84
73
  RESULT_TRUNCATION_THRESHOLD,
85
74
  SERVER_ERROR_MAX_RETRIES,
86
- SESSION_SLUG_MAX_TOKENS,
87
- SESSION_SLUG_RECENT_MESSAGES,
88
- TOKEN_ESTIMATE_SAFETY_MARGIN
89
- } from "./chunk-UP55PXFH.js";
75
+ TOOL_CONCURRENCY_LIMIT
76
+ } from "./chunk-C4NKJT2Z.js";
77
+ import {
78
+ chatWithContext,
79
+ getEffectiveApiKey,
80
+ getProviderModel,
81
+ loadContextFromTranscript
82
+ } from "./chunk-LVTKJQ7O.js";
83
+ import {
84
+ getProviderMetadata,
85
+ getSupportedProviders
86
+ } from "./chunk-6OOHHJ4N.js";
90
87
  import {
91
88
  fetchWithTimeout
92
89
  } from "./chunk-XQUHC3JZ.js";
@@ -99,6 +96,11 @@ import {
99
96
  RETRY_DEFAULT_MAX_DELAY_MS,
100
97
  RETRY_DEFAULT_TIMEOUT_MS
101
98
  } from "./chunk-R4YSJ4EY.js";
99
+ import {
100
+ appendToTranscript,
101
+ archiveTranscript,
102
+ transcriptExists
103
+ } from "./chunk-LC4TV3KL.js";
102
104
  import {
103
105
  ALLOWED_EXTENSIONS,
104
106
  TELETON_ROOT,
@@ -107,131 +109,19 @@ import {
107
109
  } from "./chunk-EYWNOHMJ.js";
108
110
  import {
109
111
  createLogger
110
- } from "./chunk-RCMD3U65.js";
111
-
112
- // src/config/loader.ts
113
- import { readFileSync, existsSync, writeFileSync, mkdirSync } from "fs";
114
- import { parse, stringify } from "yaml";
115
- import { homedir } from "os";
116
- import { dirname, join } from "path";
117
- var log = createLogger("Config");
118
- var DEFAULT_CONFIG_PATH = join(TELETON_ROOT, "config.yaml");
119
- function expandPath(path) {
120
- if (path.startsWith("~")) {
121
- return join(homedir(), path.slice(1));
122
- }
123
- return path;
124
- }
125
- function loadConfig(configPath = DEFAULT_CONFIG_PATH) {
126
- const fullPath = expandPath(configPath);
127
- if (!existsSync(fullPath)) {
128
- throw new Error(`Config file not found: ${fullPath}
129
- Run 'teleton setup' to create one.`);
130
- }
131
- let content;
132
- try {
133
- content = readFileSync(fullPath, "utf-8");
134
- } catch (error) {
135
- throw new Error(`Cannot read config file ${fullPath}: ${error.message}`);
136
- }
137
- let raw;
138
- try {
139
- raw = parse(content);
140
- } catch (error) {
141
- throw new Error(`Invalid YAML in ${fullPath}: ${error.message}`);
142
- }
143
- if (raw && typeof raw === "object" && "market" in raw) {
144
- log.warn("config.market is deprecated and ignored. Use market-api plugin instead.");
145
- delete raw.market;
146
- }
147
- const result = ConfigSchema.safeParse(raw);
148
- if (!result.success) {
149
- throw new Error(`Invalid config: ${result.error.message}`);
150
- }
151
- const config = result.data;
152
- const provider = config.agent.provider;
153
- if (provider !== "anthropic" && provider !== "claude-code" && !raw.agent?.model) {
154
- const meta = getProviderMetadata(provider);
155
- config.agent.model = meta.defaultModel;
156
- }
157
- config.telegram.session_path = expandPath(config.telegram.session_path);
158
- config.storage.sessions_file = expandPath(config.storage.sessions_file);
159
- config.storage.memory_file = expandPath(config.storage.memory_file);
160
- if (process.env.TELETON_API_KEY) {
161
- config.agent.api_key = process.env.TELETON_API_KEY;
162
- }
163
- if (process.env.TELETON_TG_API_ID) {
164
- const apiId = parseInt(process.env.TELETON_TG_API_ID, 10);
165
- if (isNaN(apiId)) {
166
- throw new Error(
167
- `Invalid TELETON_TG_API_ID environment variable: "${process.env.TELETON_TG_API_ID}" is not a valid integer`
168
- );
169
- }
170
- config.telegram.api_id = apiId;
171
- }
172
- if (process.env.TELETON_TG_API_HASH) {
173
- config.telegram.api_hash = process.env.TELETON_TG_API_HASH;
174
- }
175
- if (process.env.TELETON_TG_PHONE) {
176
- config.telegram.phone = process.env.TELETON_TG_PHONE;
177
- }
178
- if (process.env.TELETON_WEBUI_ENABLED) {
179
- config.webui.enabled = process.env.TELETON_WEBUI_ENABLED === "true";
180
- }
181
- if (process.env.TELETON_WEBUI_PORT) {
182
- const port = parseInt(process.env.TELETON_WEBUI_PORT, 10);
183
- if (!isNaN(port) && port >= 1024 && port <= 65535) {
184
- config.webui.port = port;
185
- }
186
- }
187
- if (process.env.TELETON_WEBUI_HOST) {
188
- config.webui.host = process.env.TELETON_WEBUI_HOST;
189
- if (!["127.0.0.1", "localhost", "::1"].includes(config.webui.host)) {
190
- log.warn(
191
- { host: config.webui.host },
192
- "WebUI bound to non-loopback address \u2014 ensure auth_token is set"
193
- );
194
- }
195
- }
196
- if (process.env.TELETON_BASE_URL) {
197
- try {
198
- new URL(process.env.TELETON_BASE_URL);
199
- config.agent.base_url = process.env.TELETON_BASE_URL;
200
- } catch {
201
- throw new Error(
202
- `Invalid TELETON_BASE_URL: "${process.env.TELETON_BASE_URL}" is not a valid URL`
203
- );
204
- }
205
- }
206
- if (process.env.TELETON_TAVILY_API_KEY) {
207
- config.tavily_api_key = process.env.TELETON_TAVILY_API_KEY;
208
- }
209
- if (process.env.TELETON_TONAPI_KEY) {
210
- config.tonapi_key = process.env.TELETON_TONAPI_KEY;
211
- }
212
- if (process.env.TELETON_TONCENTER_API_KEY) {
213
- config.toncenter_api_key = process.env.TELETON_TONCENTER_API_KEY;
214
- }
215
- return config;
216
- }
217
- function configExists(configPath = DEFAULT_CONFIG_PATH) {
218
- return existsSync(expandPath(configPath));
219
- }
220
- function getDefaultConfigPath() {
221
- return DEFAULT_CONFIG_PATH;
222
- }
112
+ } from "./chunk-NQ6FZKCE.js";
223
113
 
224
114
  // src/soul/loader.ts
225
- import { readFileSync as readFileSync3, existsSync as existsSync4 } from "fs";
115
+ import { readFileSync as readFileSync2, existsSync as existsSync3 } from "fs";
226
116
 
227
117
  // src/memory/daily-logs.ts
228
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, appendFileSync, readFileSync as readFileSync2 } from "fs";
229
- import { join as join2 } from "path";
118
+ import { existsSync as existsSync2, mkdirSync, appendFileSync, readFileSync } from "fs";
119
+ import { join } from "path";
230
120
 
231
121
  // src/workspace/validator.ts
232
- import { existsSync as existsSync2, lstatSync, readdirSync } from "fs";
122
+ import { existsSync, lstatSync, readdirSync } from "fs";
233
123
  import { resolve, normalize, relative, extname, basename } from "path";
234
- import { homedir as homedir2 } from "os";
124
+ import { homedir } from "os";
235
125
  var WorkspaceSecurityError = class extends Error {
236
126
  constructor(message, attemptedPath) {
237
127
  super(message);
@@ -265,7 +155,7 @@ function validatePath(inputPath, allowCreate = false) {
265
155
  if (decodedPath.startsWith("/")) {
266
156
  absolutePath = resolve(normalize(decodedPath));
267
157
  } else if (decodedPath.startsWith("~/")) {
268
- const expanded = decodedPath.replace(/^~(?=$|[\\/])/, homedir2());
158
+ const expanded = decodedPath.replace(/^~(?=$|[\\/])/, homedir());
269
159
  absolutePath = resolve(expanded);
270
160
  } else {
271
161
  absolutePath = resolve(WORKSPACE_ROOT, normalize(decodedPath));
@@ -277,7 +167,7 @@ function validatePath(inputPath, allowCreate = false) {
277
167
  inputPath
278
168
  );
279
169
  }
280
- const exists = existsSync2(absolutePath);
170
+ const exists = existsSync(absolutePath);
281
171
  if (!exists && !allowCreate) {
282
172
  throw new WorkspaceSecurityError(
283
173
  `File not found: '${inputPath}' does not exist in workspace.`,
@@ -341,7 +231,7 @@ function validateDirectory(inputPath) {
341
231
  }
342
232
 
343
233
  // src/memory/daily-logs.ts
344
- var log2 = createLogger("Memory");
234
+ var log = createLogger("Memory");
345
235
  var MEMORY_DIR = WORKSPACE_PATHS.MEMORY_DIR;
346
236
  function formatDate(date) {
347
237
  const year = date.getFullYear();
@@ -350,11 +240,11 @@ function formatDate(date) {
350
240
  return `${year}-${month}-${day}`;
351
241
  }
352
242
  function getDailyLogPath(date = /* @__PURE__ */ new Date()) {
353
- return join2(MEMORY_DIR, `${formatDate(date)}.md`);
243
+ return join(MEMORY_DIR, `${formatDate(date)}.md`);
354
244
  }
355
245
  function ensureMemoryDir() {
356
- if (!existsSync3(MEMORY_DIR)) {
357
- mkdirSync2(MEMORY_DIR, { recursive: true });
246
+ if (!existsSync2(MEMORY_DIR)) {
247
+ mkdirSync(MEMORY_DIR, { recursive: true });
358
248
  }
359
249
  }
360
250
  function appendToDailyLog(content, date = /* @__PURE__ */ new Date()) {
@@ -362,11 +252,11 @@ function appendToDailyLog(content, date = /* @__PURE__ */ new Date()) {
362
252
  ensureMemoryDir();
363
253
  const logPath = getDailyLogPath(date);
364
254
  const timestamp = date.toLocaleTimeString("en-US", { hour12: false });
365
- if (!existsSync3(logPath)) {
255
+ if (!existsSync2(logPath)) {
366
256
  const header = `# Daily Log - ${formatDate(date)}
367
257
 
368
258
  `;
369
- appendFileSync(logPath, header, "utf-8");
259
+ appendFileSync(logPath, header, { encoding: "utf-8", mode: 384 });
370
260
  }
371
261
  const entry = `## ${timestamp}
372
262
 
@@ -376,16 +266,16 @@ ${content}
376
266
 
377
267
  `;
378
268
  appendFileSync(logPath, entry, "utf-8");
379
- log2.info(`Daily log updated: ${logPath}`);
269
+ log.info(`Daily log updated: ${logPath}`);
380
270
  } catch (error) {
381
- log2.error({ err: error }, "Failed to write daily log");
271
+ log.error({ err: error }, "Failed to write daily log");
382
272
  }
383
273
  }
384
274
  function readDailyLog(date = /* @__PURE__ */ new Date()) {
385
275
  try {
386
276
  const logPath = getDailyLogPath(date);
387
- if (!existsSync3(logPath)) return null;
388
- return readFileSync2(logPath, "utf-8");
277
+ if (!existsSync2(logPath)) return null;
278
+ return readFileSync(logPath, "utf-8");
389
279
  } catch {
390
280
  return null;
391
281
  }
@@ -466,7 +356,7 @@ function cachedReadFile(path) {
466
356
  if (cached && now < cached.expiry) return cached.content;
467
357
  let content = null;
468
358
  try {
469
- if (existsSync4(path)) content = readFileSync3(path, "utf-8");
359
+ if (existsSync3(path)) content = readFileSync2(path, "utf-8");
470
360
  } catch {
471
361
  }
472
362
  fileCache.set(path, { content, expiry: now + FILE_CACHE_TTL });
@@ -741,397 +631,6 @@ ${body}`;
741
631
 
742
632
  // src/memory/compaction.ts
743
633
  import { randomUUID } from "crypto";
744
-
745
- // src/memory/ai-summarization.ts
746
- import {
747
- complete
748
- } from "@mariozechner/pi-ai";
749
- var log3 = createLogger("Memory");
750
- function estimateMessageTokens(content) {
751
- return Math.ceil(content.length / CHARS_PER_TOKEN_ESTIMATE * TOKEN_ESTIMATE_SAFETY_MARGIN);
752
- }
753
- function splitMessagesByTokens(messages, maxChunkTokens) {
754
- if (messages.length === 0) {
755
- return [];
756
- }
757
- const chunks = [];
758
- let currentChunk = [];
759
- let currentTokens = 0;
760
- for (const message of messages) {
761
- const content = extractMessageContent(message);
762
- const messageTokens = estimateMessageTokens(content);
763
- if (currentChunk.length > 0 && currentTokens + messageTokens > maxChunkTokens) {
764
- chunks.push(currentChunk);
765
- currentChunk = [];
766
- currentTokens = 0;
767
- }
768
- currentChunk.push(message);
769
- currentTokens += messageTokens;
770
- if (messageTokens > maxChunkTokens && currentChunk.length === 1) {
771
- chunks.push(currentChunk);
772
- currentChunk = [];
773
- currentTokens = 0;
774
- }
775
- }
776
- if (currentChunk.length > 0) {
777
- chunks.push(currentChunk);
778
- }
779
- return chunks;
780
- }
781
- function extractMessageContent(message) {
782
- if (message.role === "user") {
783
- return typeof message.content === "string" ? message.content : "[complex content]";
784
- } else if (message.role === "assistant") {
785
- return message.content.filter((block) => block.type === "text").map((block) => block.text).join("\n");
786
- }
787
- return "";
788
- }
789
- function formatMessagesForSummary(messages) {
790
- const formatted = [];
791
- for (const msg of messages) {
792
- if (msg.role === "user") {
793
- const content = typeof msg.content === "string" ? msg.content : "[complex]";
794
- const bodyMatch = content.match(/\] (.+)/s);
795
- const body = bodyMatch ? bodyMatch[1] : content;
796
- formatted.push(`User: ${body}`);
797
- } else if (msg.role === "assistant") {
798
- const textBlocks = msg.content.filter((b) => b.type === "text");
799
- if (textBlocks.length > 0) {
800
- const text = textBlocks.map((b) => b.text).join("\n");
801
- formatted.push(`Assistant: ${text}`);
802
- }
803
- const toolCalls = msg.content.filter((b) => b.type === "toolCall");
804
- if (toolCalls.length > 0) {
805
- const toolNames = toolCalls.map((b) => b.name).join(", ");
806
- formatted.push(`[Used tools: ${toolNames}]`);
807
- }
808
- } else if (msg.role === "toolResult") {
809
- formatted.push(`[Tool result: ${msg.toolName}]`);
810
- }
811
- }
812
- return formatted.join("\n\n");
813
- }
814
- function isOversizedForSummary(message, contextWindow) {
815
- const content = extractMessageContent(message);
816
- const tokens = estimateMessageTokens(content);
817
- return tokens > contextWindow * OVERSIZED_MESSAGE_RATIO;
818
- }
819
- function computeAdaptiveChunkRatio(messages, contextWindow) {
820
- const BASE_CHUNK_RATIO = ADAPTIVE_CHUNK_RATIO_BASE;
821
- const MIN_CHUNK_RATIO = ADAPTIVE_CHUNK_RATIO_MIN;
822
- if (messages.length === 0) {
823
- return BASE_CHUNK_RATIO;
824
- }
825
- let totalTokens = 0;
826
- for (const msg of messages) {
827
- const content = extractMessageContent(msg);
828
- totalTokens += estimateMessageTokens(content);
829
- }
830
- const avgTokens = totalTokens / messages.length;
831
- const avgRatio = avgTokens / contextWindow;
832
- if (avgRatio > ADAPTIVE_CHUNK_RATIO_TRIGGER) {
833
- const reduction = Math.min(avgRatio * 2, BASE_CHUNK_RATIO - MIN_CHUNK_RATIO);
834
- return Math.max(MIN_CHUNK_RATIO, BASE_CHUNK_RATIO - reduction);
835
- }
836
- return BASE_CHUNK_RATIO;
837
- }
838
- async function summarizeViaClaude(params) {
839
- const provider = params.provider || "anthropic";
840
- const model = getUtilityModel(provider, params.utilityModel);
841
- const maxTokens = params.maxSummaryTokens ?? DEFAULT_SUMMARY_FALLBACK_TOKENS;
842
- const formatted = formatMessagesForSummary(params.messages);
843
- if (!formatted.trim()) {
844
- return "No conversation content to summarize.";
845
- }
846
- const defaultInstructions = `Summarize this conversation concisely. Focus on:
847
- - Key decisions made
848
- - Action items and TODOs
849
- - Open questions
850
- - Important context and constraints
851
- - Technical details that matter
852
-
853
- Be specific but concise. Preserve critical information.`;
854
- const instructions = params.customInstructions ? `${defaultInstructions}
855
-
856
- Additional focus:
857
- ${params.customInstructions}` : defaultInstructions;
858
- try {
859
- const context = {
860
- messages: [
861
- {
862
- role: "user",
863
- content: `${instructions}
864
-
865
- Conversation:
866
- ${formatted}`,
867
- timestamp: Date.now()
868
- }
869
- ]
870
- };
871
- const response = await complete(model, context, {
872
- apiKey: params.apiKey,
873
- maxTokens
874
- });
875
- const textContent = response.content.find((block) => block.type === "text");
876
- const summary = textContent?.type === "text" ? textContent.text : "";
877
- return summary.trim() || "Unable to generate summary.";
878
- } catch (error) {
879
- log3.error({ err: error }, "Summarization error");
880
- throw new Error(`Summarization failed: ${getErrorMessage(error)}`);
881
- }
882
- }
883
- async function summarizeInChunks(params) {
884
- if (params.messages.length === 0) {
885
- return {
886
- summary: "No messages to summarize.",
887
- tokensUsed: 0,
888
- chunksProcessed: 0
889
- };
890
- }
891
- const chunks = splitMessagesByTokens(params.messages, params.maxChunkTokens);
892
- log3.info(`Splitting into ${chunks.length} chunks for summarization`);
893
- if (chunks.length === 1) {
894
- const summary = await summarizeViaClaude({
895
- messages: chunks[0],
896
- apiKey: params.apiKey,
897
- maxSummaryTokens: params.maxSummaryTokens,
898
- customInstructions: params.customInstructions,
899
- provider: params.provider,
900
- utilityModel: params.utilityModel
901
- });
902
- return {
903
- summary,
904
- tokensUsed: estimateMessageTokens(summary),
905
- chunksProcessed: 1
906
- };
907
- }
908
- const partialSummaries = [];
909
- for (let i = 0; i < chunks.length; i++) {
910
- log3.info(`Summarizing chunk ${i + 1}/${chunks.length} (${chunks[i].length} messages)`);
911
- const partial = await summarizeViaClaude({
912
- messages: chunks[i],
913
- apiKey: params.apiKey,
914
- maxSummaryTokens: Math.floor(
915
- (params.maxSummaryTokens ?? DEFAULT_SUMMARY_FALLBACK_TOKENS) / 2
916
- ),
917
- customInstructions: params.customInstructions,
918
- provider: params.provider,
919
- utilityModel: params.utilityModel
920
- });
921
- partialSummaries.push(partial);
922
- }
923
- log3.info(`Merging ${partialSummaries.length} partial summaries`);
924
- const provider = params.provider || "anthropic";
925
- const model = getUtilityModel(provider, params.utilityModel);
926
- const mergeContext = {
927
- messages: [
928
- {
929
- role: "user",
930
- content: `Merge these partial conversation summaries into one cohesive summary.
931
- Preserve all key decisions, action items, open questions, and important context.
932
- Do not add new information - only synthesize what's provided.
933
-
934
- Partial summaries:
935
-
936
- ${partialSummaries.map((s, i) => `Part ${i + 1}:
937
- ${s}`).join("\n\n---\n\n")}`,
938
- timestamp: Date.now()
939
- }
940
- ]
941
- };
942
- const mergeResponse = await complete(model, mergeContext, {
943
- apiKey: params.apiKey,
944
- maxTokens: params.maxSummaryTokens ?? DEFAULT_SUMMARY_FALLBACK_TOKENS
945
- });
946
- const textContent = mergeResponse.content.find((block) => block.type === "text");
947
- const merged = textContent?.type === "text" ? textContent.text : "";
948
- return {
949
- summary: merged.trim() || "Unable to merge summaries.",
950
- tokensUsed: estimateMessageTokens(merged),
951
- chunksProcessed: chunks.length
952
- };
953
- }
954
- async function summarizeWithFallback(params) {
955
- if (params.messages.length === 0) {
956
- return {
957
- summary: "No messages to summarize.",
958
- tokensUsed: 0,
959
- chunksProcessed: 0
960
- };
961
- }
962
- const chunkRatio = computeAdaptiveChunkRatio(params.messages, params.contextWindow);
963
- const maxChunkTokens = Math.floor(params.contextWindow * chunkRatio);
964
- log3.info(
965
- `AI Summarization: ${params.messages.length} messages, chunk ratio: ${(chunkRatio * 100).toFixed(0)}%`
966
- );
967
- try {
968
- return await summarizeInChunks({
969
- messages: params.messages,
970
- apiKey: params.apiKey,
971
- maxChunkTokens,
972
- maxSummaryTokens: params.maxSummaryTokens,
973
- customInstructions: params.customInstructions,
974
- provider: params.provider,
975
- utilityModel: params.utilityModel
976
- });
977
- } catch (fullError) {
978
- log3.warn(
979
- `Full summarization failed: ${fullError instanceof Error ? fullError.message : String(fullError)}`
980
- );
981
- }
982
- const smallMessages = [];
983
- const oversizedNotes = [];
984
- for (const msg of params.messages) {
985
- if (isOversizedForSummary(msg, params.contextWindow)) {
986
- const content = extractMessageContent(msg);
987
- const tokens = estimateMessageTokens(content);
988
- oversizedNotes.push(
989
- `[Large ${msg.role} message (~${Math.round(tokens / 1e3)}K tokens) omitted from summary]`
990
- );
991
- } else {
992
- smallMessages.push(msg);
993
- }
994
- }
995
- log3.info(
996
- `Fallback: Processing ${smallMessages.length} messages, skipping ${oversizedNotes.length} oversized`
997
- );
998
- if (smallMessages.length > 0) {
999
- try {
1000
- const result = await summarizeInChunks({
1001
- messages: smallMessages,
1002
- apiKey: params.apiKey,
1003
- maxChunkTokens,
1004
- maxSummaryTokens: params.maxSummaryTokens,
1005
- customInstructions: params.customInstructions,
1006
- provider: params.provider,
1007
- utilityModel: params.utilityModel
1008
- });
1009
- const notes = oversizedNotes.length > 0 ? `
1010
-
1011
- ${oversizedNotes.join("\n")}` : "";
1012
- return {
1013
- summary: result.summary + notes,
1014
- tokensUsed: result.tokensUsed,
1015
- chunksProcessed: result.chunksProcessed
1016
- };
1017
- } catch (partialError) {
1018
- log3.warn(
1019
- `Partial summarization also failed: ${partialError instanceof Error ? partialError.message : String(partialError)}`
1020
- );
1021
- }
1022
- }
1023
- const note = `Context contained ${params.messages.length} messages (${oversizedNotes.length} were oversized). AI summarization unavailable due to size constraints. Recent conversation history was preserved.`;
1024
- return {
1025
- summary: note,
1026
- tokensUsed: estimateMessageTokens(note),
1027
- chunksProcessed: 0
1028
- };
1029
- }
1030
-
1031
- // src/session/memory-hook.ts
1032
- import { writeFile, mkdir } from "fs/promises";
1033
- import { join as join3 } from "path";
1034
- import { complete as complete2 } from "@mariozechner/pi-ai";
1035
- var log4 = createLogger("Session");
1036
- async function generateSlugViaClaude(params) {
1037
- const provider = params.provider || "anthropic";
1038
- const model = getUtilityModel(provider, params.utilityModel);
1039
- const formatted = formatMessagesForSummary(params.messages.slice(-SESSION_SLUG_RECENT_MESSAGES));
1040
- if (!formatted.trim()) {
1041
- return "empty-session";
1042
- }
1043
- try {
1044
- const context = {
1045
- messages: [
1046
- {
1047
- role: "user",
1048
- content: `Generate a short, descriptive slug (2-4 words, kebab-case) for this conversation.
1049
- Examples: "gift-transfer-fix", "context-overflow-debug", "telegram-integration"
1050
-
1051
- Conversation:
1052
- ${formatted}
1053
-
1054
- Slug:`,
1055
- timestamp: Date.now()
1056
- }
1057
- ]
1058
- };
1059
- const response = await complete2(model, context, {
1060
- apiKey: params.apiKey,
1061
- maxTokens: SESSION_SLUG_MAX_TOKENS
1062
- });
1063
- const textContent = response.content.find((block) => block.type === "text");
1064
- const slug = textContent?.type === "text" ? textContent.text.trim() : "";
1065
- return slug.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").slice(0, 50) || "session";
1066
- } catch (error) {
1067
- log4.warn({ err: error }, "Slug generation failed, using fallback");
1068
- const now = /* @__PURE__ */ new Date();
1069
- return `session-${now.getHours().toString().padStart(2, "0")}${now.getMinutes().toString().padStart(2, "0")}`;
1070
- }
1071
- }
1072
- async function saveSessionMemory(params) {
1073
- try {
1074
- const { TELETON_ROOT: TELETON_ROOT2 } = await import("./paths-XA2RJH4S.js");
1075
- const memoryDir = join3(TELETON_ROOT2, "memory");
1076
- await mkdir(memoryDir, { recursive: true });
1077
- const now = /* @__PURE__ */ new Date();
1078
- const dateStr = now.toISOString().split("T")[0];
1079
- log4.info("Generating semantic slug for session memory...");
1080
- const slug = await generateSlugViaClaude({
1081
- messages: params.context.messages,
1082
- apiKey: params.apiKey,
1083
- provider: params.provider,
1084
- utilityModel: params.utilityModel
1085
- });
1086
- const filename = `${dateStr}-${slug}.md`;
1087
- const filepath = join3(memoryDir, filename);
1088
- const timeStr = now.toISOString().split("T")[1].split(".")[0];
1089
- log4.info("Generating session summary...");
1090
- let summary;
1091
- try {
1092
- summary = await summarizeViaClaude({
1093
- messages: params.context.messages,
1094
- apiKey: params.apiKey,
1095
- maxSummaryTokens: DEFAULT_MAX_SUMMARY_TOKENS,
1096
- customInstructions: "Summarize this session comprehensively. Include key topics, decisions made, problems solved, and important context.",
1097
- provider: params.provider,
1098
- utilityModel: params.utilityModel
1099
- });
1100
- } catch (error) {
1101
- log4.warn({ err: error }, "Session summary generation failed");
1102
- summary = `Session contained ${params.context.messages.length} messages. Summary generation failed.`;
1103
- }
1104
- const content = `# Session Memory: ${dateStr} ${timeStr} UTC
1105
-
1106
- ## Metadata
1107
-
1108
- - **Old Session ID**: \`${params.oldSessionId}\`
1109
- - **New Session ID**: \`${params.newSessionId}\`
1110
- - **Chat ID**: \`${params.chatId}\`
1111
- - **Timestamp**: ${now.toISOString()}
1112
- - **Message Count**: ${params.context.messages.length}
1113
-
1114
- ## Session Summary
1115
-
1116
- ${summary}
1117
-
1118
- ## Context
1119
-
1120
- This session was compacted and migrated to a new session ID. The summary above preserves key information for continuity.
1121
-
1122
- ---
1123
-
1124
- *Generated automatically by Teleton-AI session memory hook*
1125
- `;
1126
- await writeFile(filepath, content, "utf-8");
1127
- const relPath = filepath.replace(TELETON_ROOT2, "~/.teleton");
1128
- log4.info(`Session memory saved: ${relPath}`);
1129
- } catch (error) {
1130
- log4.error({ err: error }, "Failed to save session memory");
1131
- }
1132
- }
1133
-
1134
- // src/memory/compaction.ts
1135
634
  var DEFAULT_COMPACTION_CONFIG = {
1136
635
  enabled: true,
1137
636
  maxMessages: COMPACTION_MAX_MESSAGES,
@@ -1140,7 +639,7 @@ var DEFAULT_COMPACTION_CONFIG = {
1140
639
  memoryFlushEnabled: true,
1141
640
  softThresholdTokens: DEFAULT_SOFT_THRESHOLD_TOKENS
1142
641
  };
1143
- var log5 = createLogger("Memory");
642
+ var log2 = createLogger("Memory");
1144
643
  function estimateContextTokens(context) {
1145
644
  let charCount = 0;
1146
645
  if (context.systemPrompt) {
@@ -1172,7 +671,7 @@ function shouldFlushMemory(context, config, tokenCount) {
1172
671
  const tokens = tokenCount ?? estimateContextTokens(context);
1173
672
  const softThreshold = config.softThresholdTokens ?? FALLBACK_SOFT_THRESHOLD_TOKENS;
1174
673
  if (tokens >= softThreshold) {
1175
- log5.info(`Memory flush needed: ~${tokens} tokens (soft threshold: ${softThreshold})`);
674
+ log2.info(`Memory flush needed: ~${tokens} tokens (soft threshold: ${softThreshold})`);
1176
675
  return true;
1177
676
  }
1178
677
  return false;
@@ -1194,7 +693,7 @@ function flushMemoryToDailyLog(context) {
1194
693
  }
1195
694
  }
1196
695
  writeSummaryToDailyLog(summary.join("\n"));
1197
- log5.info(`Memory flushed to daily log`);
696
+ log2.info(`Memory flushed to daily log`);
1198
697
  }
1199
698
  function shouldCompact(context, config, tokenCount) {
1200
699
  if (!config.enabled) {
@@ -1202,13 +701,13 @@ function shouldCompact(context, config, tokenCount) {
1202
701
  }
1203
702
  const messageCount = context.messages.length;
1204
703
  if (config.maxMessages && messageCount >= config.maxMessages) {
1205
- log5.info(`Compaction needed: ${messageCount} messages (max: ${config.maxMessages})`);
704
+ log2.info(`Compaction needed: ${messageCount} messages (max: ${config.maxMessages})`);
1206
705
  return true;
1207
706
  }
1208
707
  if (config.maxTokens) {
1209
708
  const tokens = tokenCount ?? estimateContextTokens(context);
1210
709
  if (tokens >= config.maxTokens) {
1211
- log5.info(`Compaction needed: ~${tokens} tokens (max: ${config.maxTokens})`);
710
+ log2.info(`Compaction needed: ~${tokens} tokens (max: ${config.maxTokens})`);
1212
711
  return true;
1213
712
  }
1214
713
  }
@@ -1254,12 +753,12 @@ async function compactContext(context, config, apiKey, provider, utilityModel) {
1254
753
  iterations++;
1255
754
  }
1256
755
  if (hasOrphanedToolResults(context.messages.slice(cutIndex))) {
1257
- log5.warn(`Compaction: couldn't find clean cut point, keeping all messages`);
756
+ log2.warn(`Compaction: couldn't find clean cut point, keeping all messages`);
1258
757
  return context;
1259
758
  }
1260
759
  const recentMessages = context.messages.slice(cutIndex);
1261
760
  const oldMessages = context.messages.slice(0, cutIndex);
1262
- log5.info(
761
+ log2.info(
1263
762
  `Compacting ${oldMessages.length} old messages, keeping ${recentMessages.length} recent (cut at clean boundary)`
1264
763
  );
1265
764
  try {
@@ -1289,7 +788,7 @@ Keep each section concise. Omit a section if empty. Preserve specific names, num
1289
788
  provider,
1290
789
  utilityModel
1291
790
  });
1292
- log5.info(`AI Summary: ${result.tokensUsed} tokens, ${result.chunksProcessed} chunks processed`);
791
+ log2.info(`AI Summary: ${result.tokensUsed} tokens, ${result.chunksProcessed} chunks processed`);
1293
792
  const summaryText = `[Auto-compacted ${oldMessages.length} messages]
1294
793
 
1295
794
  ${result.summary}`;
@@ -1303,7 +802,7 @@ ${result.summary}`;
1303
802
  messages: [summaryMessage, ...recentMessages]
1304
803
  };
1305
804
  } catch (error) {
1306
- log5.error({ err: error }, "AI summarization failed, using fallback");
805
+ log2.error({ err: error }, "AI summarization failed, using fallback");
1307
806
  const summaryText = `[Auto-compacted: ${oldMessages.length} earlier messages from this conversation]`;
1308
807
  const summaryMessage = {
1309
808
  role: "user",
@@ -1318,7 +817,7 @@ ${result.summary}`;
1318
817
  }
1319
818
  async function compactAndSaveTranscript(sessionId, context, config, apiKey, chatId, provider, utilityModel) {
1320
819
  const newSessionId = randomUUID();
1321
- log5.info(`Creating compacted transcript: ${sessionId} \u2192 ${newSessionId}`);
820
+ log2.info(`Creating compacted transcript: ${sessionId} \u2192 ${newSessionId}`);
1322
821
  if (chatId) {
1323
822
  await saveSessionMemory({
1324
823
  oldSessionId: sessionId,
@@ -1352,7 +851,7 @@ var CompactionManager = class {
1352
851
  if (this.config.memoryFlushEnabled) {
1353
852
  flushMemoryToDailyLog(context);
1354
853
  }
1355
- log5.info(`Auto-compacting session ${sessionId}`);
854
+ log2.info(`Auto-compacting session ${sessionId}`);
1356
855
  const newSessionId = await compactAndSaveTranscript(
1357
856
  sessionId,
1358
857
  context,
@@ -1362,7 +861,7 @@ var CompactionManager = class {
1362
861
  provider,
1363
862
  utilityModel
1364
863
  );
1365
- log5.info(`Compaction complete: ${newSessionId}`);
864
+ log2.info(`Compaction complete: ${newSessionId}`);
1366
865
  return newSessionId;
1367
866
  }
1368
867
  updateConfig(config) {
@@ -1494,7 +993,7 @@ function maskOldToolResults(messages, options) {
1494
993
  }
1495
994
 
1496
995
  // src/agent/runtime.ts
1497
- var log6 = createLogger("Agent");
996
+ var log3 = createLogger("Agent");
1498
997
  var globalTokenUsage = { totalTokens: 0, totalCost: 0 };
1499
998
  function getTokenUsage() {
1500
999
  return { ...globalTokenUsage };
@@ -1607,7 +1106,7 @@ var AgentRuntime = class {
1607
1106
  if (this.userHookEvaluator) {
1608
1107
  const hookResult = this.userHookEvaluator.evaluate(userMessage);
1609
1108
  if (hookResult.blocked) {
1610
- log6.info("Message blocked by keyword filter");
1109
+ log3.info("Message blocked by keyword filter");
1611
1110
  return { content: hookResult.blockMessage ?? "", toolCalls: [] };
1612
1111
  }
1613
1112
  if (hookResult.additionalContext) {
@@ -1633,7 +1132,7 @@ var AgentRuntime = class {
1633
1132
  };
1634
1133
  await this.hookRunner.runModifyingHook("message:receive", msgEvent);
1635
1134
  if (msgEvent.block) {
1636
- log6.info(`\u{1F6AB} Message blocked by hook: ${msgEvent.blockReason || "no reason"}`);
1135
+ log3.info(`\u{1F6AB} Message blocked by hook: ${msgEvent.blockReason || "no reason"}`);
1637
1136
  return { content: "", toolCalls: [] };
1638
1137
  }
1639
1138
  effectiveMessage = sanitizeForContext(msgEvent.text);
@@ -1645,7 +1144,7 @@ var AgentRuntime = class {
1645
1144
  const now = timestamp ?? Date.now();
1646
1145
  const resetPolicy = this.config.agent.session_reset_policy;
1647
1146
  if (shouldResetSession(session, resetPolicy)) {
1648
- log6.info(`\u{1F504} Auto-resetting session based on policy`);
1147
+ log3.info(`\u{1F504} Auto-resetting session based on policy`);
1649
1148
  if (this.hookRunner) {
1650
1149
  await this.hookRunner.runObservingHook("session:end", {
1651
1150
  sessionId: session.sessionId,
@@ -1655,7 +1154,7 @@ var AgentRuntime = class {
1655
1154
  }
1656
1155
  if (transcriptExists(session.sessionId)) {
1657
1156
  try {
1658
- log6.info(`\u{1F4BE} Saving memory before daily reset...`);
1157
+ log3.info(`\u{1F4BE} Saving memory before daily reset...`);
1659
1158
  const oldContext = loadContextFromTranscript(session.sessionId);
1660
1159
  await saveSessionMemory({
1661
1160
  oldSessionId: session.sessionId,
@@ -1666,9 +1165,9 @@ var AgentRuntime = class {
1666
1165
  provider: this.config.agent.provider,
1667
1166
  utilityModel: this.config.agent.utility_model
1668
1167
  });
1669
- log6.info(`\u2705 Memory saved before reset`);
1168
+ log3.info(`\u2705 Memory saved before reset`);
1670
1169
  } catch (error) {
1671
- log6.warn({ err: error }, `\u26A0\uFE0F Failed to save memory before reset`);
1170
+ log3.warn({ err: error }, `\u26A0\uFE0F Failed to save memory before reset`);
1672
1171
  }
1673
1172
  }
1674
1173
  session = resetSessionWithPolicy(chatId, resetPolicy);
@@ -1676,9 +1175,9 @@ var AgentRuntime = class {
1676
1175
  let context = loadContextFromTranscript(session.sessionId);
1677
1176
  const isNewSession = context.messages.length === 0;
1678
1177
  if (!isNewSession) {
1679
- log6.info(`\u{1F4D6} Loading existing session: ${session.sessionId}`);
1178
+ log3.info(`\u{1F4D6} Loading existing session: ${session.sessionId}`);
1680
1179
  } else {
1681
- log6.info(`\u{1F195} Starting new session: ${session.sessionId}`);
1180
+ log3.info(`\u{1F195} Starting new session: ${session.sessionId}`);
1682
1181
  }
1683
1182
  if (this.hookRunner) {
1684
1183
  await this.hookRunner.runObservingHook("session:start", {
@@ -1707,21 +1206,32 @@ var AgentRuntime = class {
1707
1206
  formattedMessage = `${pendingContext}
1708
1207
 
1709
1208
  ${formattedMessage}`;
1710
- log6.debug(`\u{1F4CB} Including ${pendingContext.split("\n").length - 1} pending messages`);
1209
+ log3.debug(`\u{1F4CB} Including ${pendingContext.split("\n").length - 1} pending messages`);
1711
1210
  }
1712
- log6.debug(`\u{1F4E8} Formatted message: ${formattedMessage.substring(0, 100)}...`);
1211
+ log3.debug(`\u{1F4E8} Formatted message: ${formattedMessage.substring(0, 100)}...`);
1713
1212
  const preview = formattedMessage.slice(0, 50).replace(/\n/g, " ");
1714
1213
  const who = senderUsername ? `@${senderUsername}` : userName;
1715
1214
  const msgType = isGroup ? `Group ${chatId} ${who}` : `DM ${who}`;
1716
- log6.info(`\u{1F4E8} ${msgType}: "${preview}${formattedMessage.length > 50 ? "..." : ""}"`);
1215
+ log3.info(`\u{1F4E8} ${msgType}: "${preview}${formattedMessage.length > 50 ? "..." : ""}"`);
1717
1216
  let relevantContext = "";
1718
1217
  let queryEmbedding;
1719
1218
  const isNonTrivial = !isTrivialMessage(effectiveMessage);
1720
1219
  if (this.embedder && isNonTrivial) {
1721
1220
  try {
1722
- queryEmbedding = await this.embedder.embedQuery(effectiveMessage);
1221
+ let searchQuery = effectiveMessage;
1222
+ const recentUserMsgs = context.messages.filter((m) => m.role === "user" && typeof m.content === "string").slice(-3).map((m) => {
1223
+ const text = m.content;
1224
+ const bodyMatch = text.match(/\] (.+)/s);
1225
+ return (bodyMatch ? bodyMatch[1] : text).trim();
1226
+ }).filter((t) => t.length > 0);
1227
+ if (recentUserMsgs.length > 0) {
1228
+ searchQuery = recentUserMsgs.join(" ") + " " + effectiveMessage;
1229
+ }
1230
+ queryEmbedding = await this.embedder.embedQuery(
1231
+ searchQuery.slice(0, EMBEDDING_QUERY_MAX_CHARS)
1232
+ );
1723
1233
  } catch (error) {
1724
- log6.warn({ err: error }, "Embedding computation failed");
1234
+ log3.warn({ err: error }, "Embedding computation failed");
1725
1235
  }
1726
1236
  }
1727
1237
  if (this.contextBuilder && isNonTrivial) {
@@ -1755,12 +1265,12 @@ ${sanitizedFeed.join("\n")}`
1755
1265
  }
1756
1266
  if (contextParts.length > 0) {
1757
1267
  relevantContext = contextParts.join("\n\n");
1758
- log6.debug(
1268
+ log3.debug(
1759
1269
  `\u{1F50D} Found ${dbContext.relevantKnowledge.length} knowledge chunks, ${dbContext.relevantFeed.length} feed messages`
1760
1270
  );
1761
1271
  }
1762
1272
  } catch (error) {
1763
- log6.warn({ err: error }, "Context building failed");
1273
+ log3.warn({ err: error }, "Context building failed");
1764
1274
  }
1765
1275
  }
1766
1276
  const memoryStats = this.getMemoryStats();
@@ -1828,7 +1338,7 @@ ${allHookContext}` : "");
1828
1338
  this.config.agent.utility_model
1829
1339
  );
1830
1340
  if (preemptiveCompaction) {
1831
- log6.info(`\u{1F5DC}\uFE0F Preemptive compaction triggered, reloading session...`);
1341
+ log3.info(`\u{1F5DC}\uFE0F Preemptive compaction triggered, reloading session...`);
1832
1342
  session = getSession(chatId);
1833
1343
  context = loadContextFromTranscript(session.sessionId);
1834
1344
  context.messages.push(userMsg);
@@ -1850,7 +1360,7 @@ ${allHookContext}` : "");
1850
1360
  chatId,
1851
1361
  isAdmin
1852
1362
  );
1853
- log6.info(`\u{1F50D} Tool RAG: ${tools.length}/${this.toolRegistry.count} tools selected`);
1363
+ log3.info(`\u{1F50D} Tool RAG: ${tools.length}/${this.toolRegistry.count} tools selected`);
1854
1364
  } else {
1855
1365
  tools = this.toolRegistry?.getForContext(
1856
1366
  effectiveIsGroup,
@@ -1869,9 +1379,10 @@ ${allHookContext}` : "");
1869
1379
  const totalToolCalls = [];
1870
1380
  const accumulatedTexts = [];
1871
1381
  const accumulatedUsage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalCost: 0 };
1382
+ const seenToolSignatures = /* @__PURE__ */ new Set();
1872
1383
  while (iteration < maxIterations) {
1873
1384
  iteration++;
1874
- log6.debug(`\u{1F504} Agentic iteration ${iteration}/${maxIterations}`);
1385
+ log3.debug(`\u{1F504} Agentic iteration ${iteration}/${maxIterations}`);
1875
1386
  const iterationStartIndex = context.messages.length;
1876
1387
  const maskedMessages = maskOldToolResults(context.messages, {
1877
1388
  toolRegistry: this.toolRegistry ?? void 0,
@@ -1910,35 +1421,35 @@ ${allHookContext}` : "");
1910
1421
  "Context overflow persists after session reset. Message may be too large for the model's context window."
1911
1422
  );
1912
1423
  }
1913
- log6.error(`\u{1F6A8} Context overflow detected: ${errorMsg}`);
1914
- log6.info(`\u{1F4BE} Saving session memory before reset...`);
1424
+ log3.error(`\u{1F6A8} Context overflow detected: ${errorMsg}`);
1425
+ log3.info(`\u{1F4BE} Saving session memory before reset...`);
1915
1426
  const summary = extractContextSummary(context, CONTEXT_OVERFLOW_SUMMARY_MESSAGES);
1916
1427
  appendToDailyLog(summary);
1917
- log6.info(`\u2705 Memory saved to daily log`);
1428
+ log3.info(`\u2705 Memory saved to daily log`);
1918
1429
  const archived = archiveTranscript(session.sessionId);
1919
1430
  if (!archived) {
1920
- log6.error(
1431
+ log3.error(
1921
1432
  `\u26A0\uFE0F Failed to archive transcript ${session.sessionId}, proceeding with reset anyway`
1922
1433
  );
1923
1434
  }
1924
- log6.info(`\u{1F504} Resetting session due to context overflow...`);
1435
+ log3.info(`\u{1F504} Resetting session due to context overflow...`);
1925
1436
  session = resetSession(chatId);
1926
1437
  context = { messages: [userMsg] };
1927
1438
  appendToTranscript(session.sessionId, userMsg);
1928
- log6.info(`\u{1F504} Retrying with fresh context...`);
1439
+ log3.info(`\u{1F504} Retrying with fresh context...`);
1929
1440
  continue;
1930
1441
  } else if (errorMsg.toLowerCase().includes("rate") || errorMsg.includes("429")) {
1931
1442
  rateLimitRetries++;
1932
1443
  if (rateLimitRetries <= RATE_LIMIT_MAX_RETRIES) {
1933
1444
  const delay = 1e3 * Math.pow(2, rateLimitRetries - 1);
1934
- log6.warn(
1445
+ log3.warn(
1935
1446
  `\u{1F6AB} Rate limited, retrying in ${delay}ms (attempt ${rateLimitRetries}/${RATE_LIMIT_MAX_RETRIES})...`
1936
1447
  );
1937
1448
  await new Promise((r3) => setTimeout(r3, delay));
1938
1449
  iteration--;
1939
1450
  continue;
1940
1451
  }
1941
- log6.error(`\u{1F6AB} Rate limited after ${RATE_LIMIT_MAX_RETRIES} retries: ${errorMsg}`);
1452
+ log3.error(`\u{1F6AB} Rate limited after ${RATE_LIMIT_MAX_RETRIES} retries: ${errorMsg}`);
1942
1453
  throw new Error(
1943
1454
  `API rate limited after ${RATE_LIMIT_MAX_RETRIES} retries. Please try again later.`
1944
1455
  );
@@ -1946,19 +1457,19 @@ ${allHookContext}` : "");
1946
1457
  serverErrorRetries++;
1947
1458
  if (serverErrorRetries <= SERVER_ERROR_MAX_RETRIES) {
1948
1459
  const delay = 2e3 * Math.pow(2, serverErrorRetries - 1);
1949
- log6.warn(
1460
+ log3.warn(
1950
1461
  `\u{1F504} Server error, retrying in ${delay}ms (attempt ${serverErrorRetries}/${SERVER_ERROR_MAX_RETRIES})...`
1951
1462
  );
1952
1463
  await new Promise((r3) => setTimeout(r3, delay));
1953
1464
  iteration--;
1954
1465
  continue;
1955
1466
  }
1956
- log6.error(`\u{1F6A8} Server error after ${SERVER_ERROR_MAX_RETRIES} retries: ${errorMsg}`);
1467
+ log3.error(`\u{1F6A8} Server error after ${SERVER_ERROR_MAX_RETRIES} retries: ${errorMsg}`);
1957
1468
  throw new Error(
1958
1469
  `API server error after ${SERVER_ERROR_MAX_RETRIES} retries. The provider may be experiencing issues.`
1959
1470
  );
1960
1471
  } else {
1961
- log6.error(`\u{1F6A8} API error: ${errorMsg}`);
1472
+ log3.error(`\u{1F6A8} API error: ${errorMsg}`);
1962
1473
  throw new Error(`API error: ${errorMsg || "Unknown error"}`);
1963
1474
  }
1964
1475
  }
@@ -1975,24 +1486,25 @@ ${allHookContext}` : "");
1975
1486
  }
1976
1487
  const toolCalls = response2.message.content.filter((block) => block.type === "toolCall");
1977
1488
  if (toolCalls.length === 0) {
1978
- log6.info(`\u{1F504} ${iteration}/${maxIterations} \u2192 done`);
1489
+ log3.info(`\u{1F504} ${iteration}/${maxIterations} \u2192 done`);
1979
1490
  finalResponse = response2;
1980
1491
  break;
1981
1492
  }
1982
1493
  if (!this.toolRegistry || !toolContext) {
1983
- log6.error("\u26A0\uFE0F Cannot execute tools: registry or context missing");
1494
+ log3.error("\u26A0\uFE0F Cannot execute tools: registry or context missing");
1984
1495
  break;
1985
1496
  }
1986
- log6.debug(`\u{1F527} Executing ${toolCalls.length} tool call(s)`);
1497
+ log3.debug(`\u{1F527} Executing ${toolCalls.length} tool call(s)`);
1987
1498
  context.messages.push(response2.message);
1988
1499
  const iterationToolNames = [];
1500
+ const fullContext = {
1501
+ ...toolContext,
1502
+ chatId,
1503
+ isGroup: effectiveIsGroup
1504
+ };
1505
+ const toolPlans = [];
1989
1506
  for (const block of toolCalls) {
1990
1507
  if (block.type !== "toolCall") continue;
1991
- const fullContext = {
1992
- ...toolContext,
1993
- chatId,
1994
- isGroup: effectiveIsGroup
1995
- };
1996
1508
  let toolParams = block.arguments ?? {};
1997
1509
  let blocked = false;
1998
1510
  let blockReason = "";
@@ -2013,74 +1525,88 @@ ${allHookContext}` : "");
2013
1525
  toolParams = structuredClone(beforeEvent.params);
2014
1526
  }
2015
1527
  }
2016
- let result;
2017
- if (blocked) {
2018
- result = { success: false, error: blockReason };
2019
- if (this.hookRunner) {
2020
- const afterEvent = {
2021
- toolName: block.name,
2022
- params: structuredClone(toolParams),
2023
- result: { success: false, error: blockReason },
2024
- durationMs: 0,
2025
- chatId,
2026
- isGroup: effectiveIsGroup,
2027
- blocked: true,
2028
- blockReason
2029
- };
2030
- await this.hookRunner.runObservingHook("tool:after", afterEvent);
2031
- }
2032
- } else {
2033
- const startTime = Date.now();
2034
- try {
2035
- result = await this.toolRegistry.execute(
2036
- { ...block, arguments: toolParams },
2037
- fullContext
2038
- );
2039
- } catch (execErr) {
2040
- const durationMs2 = Date.now() - startTime;
2041
- const errMsg = execErr instanceof Error ? execErr.message : String(execErr);
2042
- const errStack = execErr instanceof Error ? execErr.stack : void 0;
2043
- result = { success: false, error: errMsg };
2044
- if (this.hookRunner) {
2045
- const errorEvent = {
2046
- toolName: block.name,
2047
- params: structuredClone(toolParams),
2048
- error: errMsg,
2049
- // Note: stack traces are exposed to plugins for debugging — accepted tradeoff
2050
- stack: errStack,
2051
- chatId,
2052
- isGroup: effectiveIsGroup,
2053
- durationMs: durationMs2
1528
+ toolPlans.push({ block, blocked, blockReason, params: toolParams });
1529
+ }
1530
+ const execResults = new Array(toolPlans.length);
1531
+ {
1532
+ let cursor = 0;
1533
+ const runWorker = async () => {
1534
+ while (cursor < toolPlans.length) {
1535
+ const idx = cursor++;
1536
+ const plan = toolPlans[idx];
1537
+ if (plan.blocked) {
1538
+ execResults[idx] = {
1539
+ result: { success: false, error: plan.blockReason },
1540
+ durationMs: 0
1541
+ };
1542
+ continue;
1543
+ }
1544
+ const startTime = Date.now();
1545
+ try {
1546
+ const result = await this.toolRegistry.execute(
1547
+ { ...plan.block, arguments: plan.params },
1548
+ fullContext
1549
+ );
1550
+ execResults[idx] = { result, durationMs: Date.now() - startTime };
1551
+ } catch (execErr) {
1552
+ const errMsg = execErr instanceof Error ? execErr.message : String(execErr);
1553
+ const errStack = execErr instanceof Error ? execErr.stack : void 0;
1554
+ execResults[idx] = {
1555
+ result: { success: false, error: errMsg },
1556
+ durationMs: Date.now() - startTime,
1557
+ execError: { message: errMsg, stack: errStack }
2054
1558
  };
2055
- await this.hookRunner.runObservingHook("tool:error", errorEvent);
2056
1559
  }
2057
1560
  }
2058
- const durationMs = Date.now() - startTime;
2059
- if (this.hookRunner) {
2060
- const afterEvent = {
2061
- toolName: block.name,
2062
- params: structuredClone(toolParams),
2063
- result: { success: result.success, data: result.data, error: result.error },
2064
- durationMs,
2065
- chatId,
2066
- isGroup: effectiveIsGroup
2067
- };
2068
- await this.hookRunner.runObservingHook("tool:after", afterEvent);
2069
- }
1561
+ };
1562
+ const workers = Math.min(TOOL_CONCURRENCY_LIMIT, toolPlans.length);
1563
+ await Promise.all(Array.from({ length: workers }, () => runWorker()));
1564
+ }
1565
+ for (let i = 0; i < toolPlans.length; i++) {
1566
+ const plan = toolPlans[i];
1567
+ const { block } = plan;
1568
+ const exec = execResults[i];
1569
+ if (exec.execError && this.hookRunner) {
1570
+ const errorEvent = {
1571
+ toolName: block.name,
1572
+ params: structuredClone(plan.params),
1573
+ error: exec.execError.message,
1574
+ stack: exec.execError.stack,
1575
+ chatId,
1576
+ isGroup: effectiveIsGroup,
1577
+ durationMs: exec.durationMs
1578
+ };
1579
+ await this.hookRunner.runObservingHook("tool:error", errorEvent);
2070
1580
  }
2071
- log6.debug(`${block.name}: ${result.success ? "\u2713" : "\u2717"} ${result.error || ""}`);
2072
- iterationToolNames.push(`${block.name} ${result.success ? "\u2713" : "\u2717"}`);
1581
+ if (this.hookRunner) {
1582
+ const afterEvent = {
1583
+ toolName: block.name,
1584
+ params: structuredClone(plan.params),
1585
+ result: {
1586
+ success: exec.result.success,
1587
+ data: exec.result.data,
1588
+ error: exec.result.error
1589
+ },
1590
+ durationMs: exec.durationMs,
1591
+ chatId,
1592
+ isGroup: effectiveIsGroup,
1593
+ ...plan.blocked ? { blocked: true, blockReason: plan.blockReason } : {}
1594
+ };
1595
+ await this.hookRunner.runObservingHook("tool:after", afterEvent);
1596
+ }
1597
+ log3.debug(`${block.name}: ${exec.result.success ? "\u2713" : "\u2717"} ${exec.result.error || ""}`);
1598
+ iterationToolNames.push(`${block.name} ${exec.result.success ? "\u2713" : "\u2717"}`);
2073
1599
  totalToolCalls.push({
2074
1600
  name: block.name,
2075
1601
  input: block.arguments
2076
1602
  });
2077
- let resultText = JSON.stringify(result);
1603
+ let resultText = JSON.stringify(exec.result);
2078
1604
  if (resultText.length > MAX_TOOL_RESULT_SIZE) {
2079
- log6.warn(`\u26A0\uFE0F Tool result too large (${resultText.length} chars), truncating...`);
2080
- const data = result.data;
1605
+ log3.warn(`\u26A0\uFE0F Tool result too large (${resultText.length} chars), truncating...`);
1606
+ const data = exec.result.data;
2081
1607
  if (data?.summary || data?.message) {
2082
1608
  resultText = JSON.stringify({
2083
- success: result.success,
1609
+ success: exec.result.success,
2084
1610
  data: {
2085
1611
  summary: data.summary || data.message,
2086
1612
  _truncated: true,
@@ -2089,11 +1615,27 @@ ${allHookContext}` : "");
2089
1615
  }
2090
1616
  });
2091
1617
  } else {
2092
- resultText = resultText.slice(0, MAX_TOOL_RESULT_SIZE) + "\n...[TRUNCATED]";
1618
+ const summarized = {
1619
+ _truncated: true,
1620
+ _originalSize: resultText.length,
1621
+ _message: "Full data truncated. Use limit parameter for smaller results."
1622
+ };
1623
+ if (data && typeof data === "object") {
1624
+ for (const [key, value] of Object.entries(data)) {
1625
+ if (Array.isArray(value)) {
1626
+ summarized[key] = `[${value.length} items]`;
1627
+ } else if (typeof value === "string" && value.length > 500) {
1628
+ summarized[key] = value.slice(0, 500) + "...[truncated]";
1629
+ } else {
1630
+ summarized[key] = value;
1631
+ }
1632
+ }
1633
+ }
1634
+ resultText = JSON.stringify({ success: exec.result.success, data: summarized });
2093
1635
  }
2094
1636
  }
2095
1637
  if (provider === "cocoon") {
2096
- const { wrapToolResult } = await import("./tool-adapter-IH5VGBOO.js");
1638
+ const { wrapToolResult } = await import("./tool-adapter-IVX2XQJE.js");
2097
1639
  const cocoonResultMsg = {
2098
1640
  role: "user",
2099
1641
  content: [
@@ -2117,21 +1659,33 @@ ${allHookContext}` : "");
2117
1659
  text: resultText
2118
1660
  }
2119
1661
  ],
2120
- isError: !result.success,
1662
+ isError: !exec.result.success,
2121
1663
  timestamp: Date.now()
2122
1664
  };
2123
1665
  context.messages.push(toolResultMsg);
2124
1666
  appendToTranscript(session.sessionId, toolResultMsg);
2125
1667
  }
2126
1668
  }
2127
- log6.info(`\u{1F504} ${iteration}/${maxIterations} \u2192 ${iterationToolNames.join(", ")}`);
1669
+ log3.info(`\u{1F504} ${iteration}/${maxIterations} \u2192 ${iterationToolNames.join(", ")}`);
1670
+ const iterSignatures = toolPlans.map(
1671
+ (p2) => `${p2.block.name}:${JSON.stringify(p2.params, Object.keys(p2.params).sort())}`
1672
+ );
1673
+ const allDuplicates = iterSignatures.length > 0 && iterSignatures.every((sig) => seenToolSignatures.has(sig));
1674
+ for (const sig of iterSignatures) seenToolSignatures.add(sig);
1675
+ if (allDuplicates) {
1676
+ log3.warn(
1677
+ `\u{1F501} Loop stall detected: all ${iterSignatures.length} tool call(s) are repeats \u2014 breaking early`
1678
+ );
1679
+ finalResponse = response2;
1680
+ break;
1681
+ }
2128
1682
  if (iteration === maxIterations) {
2129
- log6.info(`\u26A0\uFE0F Max iterations reached (${maxIterations})`);
1683
+ log3.info(`\u26A0\uFE0F Max iterations reached (${maxIterations})`);
2130
1684
  finalResponse = response2;
2131
1685
  }
2132
1686
  }
2133
1687
  if (!finalResponse) {
2134
- log6.error("\u26A0\uFE0F Agentic loop exited early without final response");
1688
+ log3.error("\u26A0\uFE0F Agentic loop exited early without final response");
2135
1689
  return {
2136
1690
  content: "Internal error: Agent loop failed to produce a response.",
2137
1691
  toolCalls: []
@@ -2142,14 +1696,6 @@ ${allHookContext}` : "");
2142
1696
  if (lastMsg?.role !== "assistant") {
2143
1697
  context.messages.push(response.message);
2144
1698
  }
2145
- const newSessionId = await this.compactionManager.checkAndCompact(
2146
- session.sessionId,
2147
- context,
2148
- getEffectiveApiKey(this.config.agent.provider, this.config.agent.api_key),
2149
- chatId,
2150
- this.config.agent.provider,
2151
- this.config.agent.utility_model
2152
- );
2153
1699
  const sessionUpdate = {
2154
1700
  updatedAt: Date.now(),
2155
1701
  messageCount: session.messageCount + 1,
@@ -2158,9 +1704,6 @@ ${allHookContext}` : "");
2158
1704
  inputTokens: (session.inputTokens ?? 0) + accumulatedUsage.input + accumulatedUsage.cacheRead + accumulatedUsage.cacheWrite,
2159
1705
  outputTokens: (session.outputTokens ?? 0) + accumulatedUsage.output
2160
1706
  };
2161
- if (newSessionId) {
2162
- sessionUpdate.sessionId = newSessionId;
2163
- }
2164
1707
  updateSession(chatId, sessionUpdate);
2165
1708
  if (accumulatedUsage.input > 0 || accumulatedUsage.output > 0) {
2166
1709
  const u = accumulatedUsage;
@@ -2170,20 +1713,20 @@ ${allHookContext}` : "");
2170
1713
  if (u.cacheRead) cacheParts.push(`${(u.cacheRead / 1e3).toFixed(1)}K cached`);
2171
1714
  if (u.cacheWrite) cacheParts.push(`${(u.cacheWrite / 1e3).toFixed(1)}K new`);
2172
1715
  const cacheInfo = cacheParts.length > 0 ? ` (${cacheParts.join(", ")})` : "";
2173
- log6.info(`\u{1F4B0} ${inK}K in${cacheInfo}, ${u.output} out | $${u.totalCost.toFixed(3)}`);
1716
+ log3.info(`\u{1F4B0} ${inK}K in${cacheInfo}, ${u.output} out | $${u.totalCost.toFixed(3)}`);
2174
1717
  globalTokenUsage.totalTokens += u.input + u.output + u.cacheRead + u.cacheWrite;
2175
1718
  globalTokenUsage.totalCost += u.totalCost;
2176
1719
  }
2177
1720
  let content = accumulatedTexts.join("\n").trim() || response.text;
2178
1721
  const usedTelegramSendTool = totalToolCalls.some((tc) => TELEGRAM_SEND_TOOLS.has(tc.name));
2179
1722
  if (!content && totalToolCalls.length > 0 && !usedTelegramSendTool) {
2180
- log6.warn("\u26A0\uFE0F Empty response after tool calls - generating fallback");
1723
+ log3.warn("\u26A0\uFE0F Empty response after tool calls - generating fallback");
2181
1724
  content = "I executed the requested action but couldn't generate a response. Please try again.";
2182
1725
  } else if (!content && usedTelegramSendTool) {
2183
- log6.info("\u2705 Response sent via Telegram tool - no additional text needed");
1726
+ log3.info("\u2705 Response sent via Telegram tool - no additional text needed");
2184
1727
  content = "";
2185
1728
  } else if (!content && accumulatedUsage.input === 0 && accumulatedUsage.output === 0) {
2186
- log6.warn("\u26A0\uFE0F Empty response with zero tokens - possible API issue");
1729
+ log3.warn("\u26A0\uFE0F Empty response with zero tokens - possible API issue");
2187
1730
  content = "I couldn't process your request. Please try again.";
2188
1731
  }
2189
1732
  let responseMetadata = {};
@@ -2200,7 +1743,7 @@ ${allHookContext}` : "");
2200
1743
  };
2201
1744
  await this.hookRunner.runModifyingHook("response:before", responseBeforeEvent);
2202
1745
  if (responseBeforeEvent.block) {
2203
- log6.info(
1746
+ log3.info(
2204
1747
  `\u{1F6AB} Response blocked by hook: ${responseBeforeEvent.blockReason || "no reason"}`
2205
1748
  );
2206
1749
  content = "";
@@ -2227,7 +1770,7 @@ ${allHookContext}` : "");
2227
1770
  toolCalls: totalToolCalls
2228
1771
  };
2229
1772
  } catch (error) {
2230
- log6.error({ err: error }, "Agent error");
1773
+ log3.error({ err: error }, "Agent error");
2231
1774
  throw error;
2232
1775
  }
2233
1776
  }
@@ -2240,7 +1783,7 @@ ${allHookContext}` : "");
2240
1783
  ).run(chatId);
2241
1784
  db.prepare(`DELETE FROM tg_messages WHERE chat_id = ?`).run(chatId);
2242
1785
  resetSession(chatId);
2243
- log6.info(`\u{1F5D1}\uFE0F Cleared history for chat ${chatId}`);
1786
+ log3.info(`\u{1F5D1}\uFE0F Cleared history for chat ${chatId}`);
2244
1787
  }
2245
1788
  getConfig() {
2246
1789
  return this.config;
@@ -2261,7 +1804,7 @@ ${allHookContext}` : "");
2261
1804
  }
2262
1805
  configureCompaction(config) {
2263
1806
  this.compactionManager.updateConfig(config);
2264
- log6.info({ config: this.compactionManager.getConfig() }, `\u{1F5DC}\uFE0F Compaction config updated`);
1807
+ log3.info({ config: this.compactionManager.getConfig() }, `\u{1F5DC}\uFE0F Compaction config updated`);
2265
1808
  }
2266
1809
  getCompactionConfig() {
2267
1810
  return this.compactionManager.getConfig();
@@ -2349,6 +1892,17 @@ function prefixButtons(rows, pluginName) {
2349
1892
 
2350
1893
  // src/bot/services/html-parser.ts
2351
1894
  import { Api as Api2 } from "telegram";
1895
+
1896
+ // src/utils/gramjs-bigint.ts
1897
+ import { randomBytes } from "crypto";
1898
+ function toLong(value) {
1899
+ return typeof value === "bigint" ? value : BigInt(value);
1900
+ }
1901
+ function randomLong() {
1902
+ return randomBytes(8).readBigUInt64BE();
1903
+ }
1904
+
1905
+ // src/bot/services/html-parser.ts
2352
1906
  function parseHtml(html) {
2353
1907
  const entities = [];
2354
1908
  let text = "";
@@ -2399,8 +1953,7 @@ function parseHtml(html) {
2399
1953
  new Api2.MessageEntityCustomEmoji({
2400
1954
  offset: open.offset,
2401
1955
  length,
2402
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS BigInteger compat
2403
- documentId: BigInt(open.emojiId)
1956
+ documentId: toLong(open.emojiId)
2404
1957
  })
2405
1958
  );
2406
1959
  }
@@ -2461,7 +2014,7 @@ function unescapeHtml(text) {
2461
2014
  }
2462
2015
 
2463
2016
  // src/bot/inline-router.ts
2464
- var log7 = createLogger("InlineRouter");
2017
+ var log4 = createLogger("InlineRouter");
2465
2018
  var INLINE_TIMEOUT_MS = 5e3;
2466
2019
  var CALLBACK_TIMEOUT_MS = 15e3;
2467
2020
  function compileGlob(pattern) {
@@ -2482,11 +2035,11 @@ var InlineRouter = class {
2482
2035
  }
2483
2036
  registerPlugin(name, handlers) {
2484
2037
  this.plugins.set(name, handlers);
2485
- log7.info(`Registered plugin "${name}" for inline routing`);
2038
+ log4.info(`Registered plugin "${name}" for inline routing`);
2486
2039
  }
2487
2040
  unregisterPlugin(name) {
2488
2041
  this.plugins.delete(name);
2489
- log7.info(`Unregistered plugin "${name}" from inline routing`);
2042
+ log4.info(`Unregistered plugin "${name}" from inline routing`);
2490
2043
  }
2491
2044
  hasPlugin(name) {
2492
2045
  return this.plugins.has(name);
@@ -2558,7 +2111,7 @@ var InlineRouter = class {
2558
2111
  is_personal: true
2559
2112
  });
2560
2113
  } catch (error) {
2561
- log7.error({ err: error }, `Plugin "${pluginName}" inline query handler failed`);
2114
+ log4.error({ err: error }, `Plugin "${pluginName}" inline query handler failed`);
2562
2115
  try {
2563
2116
  await ctx.answerInlineQuery([], { cache_time: 0, is_personal: true });
2564
2117
  } catch {
@@ -2618,7 +2171,7 @@ var InlineRouter = class {
2618
2171
  } catch (error) {
2619
2172
  const errMsg = error?.errorMessage;
2620
2173
  if (errMsg === "MESSAGE_NOT_MODIFIED") return;
2621
- log7.debug(`GramJS edit failed, falling back to Grammy: ${errMsg || error}`);
2174
+ log4.debug(`GramJS edit failed, falling back to Grammy: ${errMsg || error}`);
2622
2175
  }
2623
2176
  }
2624
2177
  const replyMarkup = styledButtons ? toGrammyKeyboard(styledButtons) : void 0;
@@ -2638,7 +2191,7 @@ var InlineRouter = class {
2638
2191
  await ctx.answerCallbackQuery();
2639
2192
  }
2640
2193
  } catch (error) {
2641
- log7.error({ err: error }, `Plugin "${pluginName}" callback handler failed`);
2194
+ log4.error({ err: error }, `Plugin "${pluginName}" callback handler failed`);
2642
2195
  if (!answered) {
2643
2196
  try {
2644
2197
  await ctx.answerCallbackQuery({ text: "Error processing action" });
@@ -2661,7 +2214,7 @@ var InlineRouter = class {
2661
2214
  };
2662
2215
  await plugin.onChosenResult(crCtx);
2663
2216
  } catch (error) {
2664
- log7.error({ err: error }, `Plugin "${pluginName}" chosen result handler failed`);
2217
+ log4.error({ err: error }, `Plugin "${pluginName}" chosen result handler failed`);
2665
2218
  }
2666
2219
  }
2667
2220
  /**
@@ -2739,8 +2292,8 @@ function withTimeout(promise, ms, message) {
2739
2292
  }
2740
2293
 
2741
2294
  // src/agent/tools/plugin-loader.ts
2742
- import { readdirSync as readdirSync2, readFileSync as readFileSync5, existsSync as existsSync6, statSync } from "fs";
2743
- import { join as join5 } from "path";
2295
+ import { readdirSync as readdirSync2, readFileSync as readFileSync4, existsSync as existsSync5, statSync } from "fs";
2296
+ import { join as join3 } from "path";
2744
2297
  import { pathToFileURL } from "url";
2745
2298
  import { execFile } from "child_process";
2746
2299
 
@@ -2771,7 +2324,7 @@ import { promisify } from "util";
2771
2324
 
2772
2325
  // src/agent/tools/plugin-validator.ts
2773
2326
  import { z } from "zod";
2774
- var log8 = createLogger("PluginValidator");
2327
+ var log5 = createLogger("PluginValidator");
2775
2328
  var ManifestSchema = z.object({
2776
2329
  name: z.string().min(1).max(64).regex(
2777
2330
  /^[a-z0-9][a-z0-9-]*$/,
@@ -2814,20 +2367,20 @@ function validateToolDefs(defs, pluginName) {
2814
2367
  const valid = [];
2815
2368
  for (const def of defs) {
2816
2369
  if (!def || typeof def !== "object") {
2817
- log8.warn(`[${pluginName}] tool is not an object, skipping`);
2370
+ log5.warn(`[${pluginName}] tool is not an object, skipping`);
2818
2371
  continue;
2819
2372
  }
2820
2373
  const t = def;
2821
2374
  if (!t.name || typeof t.name !== "string") {
2822
- log8.warn(`[${pluginName}] tool missing 'name', skipping`);
2375
+ log5.warn(`[${pluginName}] tool missing 'name', skipping`);
2823
2376
  continue;
2824
2377
  }
2825
2378
  if (!t.description || typeof t.description !== "string") {
2826
- log8.warn(`[${pluginName}] tool "${t.name}" missing 'description', skipping`);
2379
+ log5.warn(`[${pluginName}] tool "${t.name}" missing 'description', skipping`);
2827
2380
  continue;
2828
2381
  }
2829
2382
  if (!t.execute || typeof t.execute !== "function") {
2830
- log8.warn(`[${pluginName}] tool "${t.name}" missing 'execute' function, skipping`);
2383
+ log5.warn(`[${pluginName}] tool "${t.name}" missing 'execute' function, skipping`);
2831
2384
  continue;
2832
2385
  }
2833
2386
  valid.push(t);
@@ -2864,8 +2417,19 @@ import { Address, SendMode } from "@ton/core";
2864
2417
 
2865
2418
  // src/ton/tx-lock.ts
2866
2419
  var pending = Promise.resolve();
2420
+ var TX_LOCK_TIMEOUT_MS = 6e4;
2867
2421
  function withTxLock(fn) {
2868
- const execute = pending.then(fn, fn);
2422
+ const guarded = () => {
2423
+ let timerId;
2424
+ const timeoutPromise = new Promise((_, reject) => {
2425
+ timerId = setTimeout(
2426
+ () => reject(new Error("TON tx-lock timeout (60s)")),
2427
+ TX_LOCK_TIMEOUT_MS
2428
+ );
2429
+ });
2430
+ return Promise.race([fn(), timeoutPromise]).finally(() => clearTimeout(timerId));
2431
+ };
2432
+ const execute = pending.then(guarded, guarded);
2869
2433
  pending = execute.then(
2870
2434
  () => {
2871
2435
  },
@@ -2876,25 +2440,25 @@ function withTxLock(fn) {
2876
2440
  }
2877
2441
 
2878
2442
  // src/ton/transfer.ts
2879
- var log9 = createLogger("TON");
2443
+ var log6 = createLogger("TON");
2880
2444
  async function sendTon(params) {
2881
2445
  return withTxLock(async () => {
2882
2446
  try {
2883
2447
  const { toAddress: toAddress2, amount, comment = "", bounce = false } = params;
2884
2448
  if (!Number.isFinite(amount) || amount <= 0) {
2885
- log9.error({ amount }, "Invalid transfer amount");
2449
+ log6.error({ amount }, "Invalid transfer amount");
2886
2450
  return null;
2887
2451
  }
2888
2452
  let recipientAddress;
2889
2453
  try {
2890
2454
  recipientAddress = Address.parse(toAddress2);
2891
2455
  } catch (e) {
2892
- log9.error({ err: e }, `Invalid recipient address: ${toAddress2}`);
2456
+ log6.error({ err: e }, `Invalid recipient address: ${toAddress2}`);
2893
2457
  return null;
2894
2458
  }
2895
2459
  const keyPair = await getKeyPair();
2896
2460
  if (!keyPair) {
2897
- log9.error("Wallet not initialized");
2461
+ log6.error("Wallet not initialized");
2898
2462
  return null;
2899
2463
  }
2900
2464
  const wallet = WalletContractV5R1.create({
@@ -2918,7 +2482,7 @@ async function sendTon(params) {
2918
2482
  ]
2919
2483
  });
2920
2484
  const pseudoHash = `${seqno}_${Date.now()}_${amount.toFixed(2)}`;
2921
- log9.info(`Sent ${amount} TON to ${toAddress2.slice(0, 8)}... - seqno: ${seqno}`);
2485
+ log6.info(`Sent ${amount} TON to ${toAddress2.slice(0, 8)}... - seqno: ${seqno}`);
2922
2486
  return pseudoHash;
2923
2487
  } catch (error) {
2924
2488
  const err = error;
@@ -2926,14 +2490,14 @@ async function sendTon(params) {
2926
2490
  if (status === 429 || status !== void 0 && status >= 500) {
2927
2491
  invalidateTonClientCache();
2928
2492
  }
2929
- log9.error({ err: error }, "Error sending TON");
2493
+ log6.error({ err: error }, "Error sending TON");
2930
2494
  throw error;
2931
2495
  }
2932
2496
  });
2933
2497
  }
2934
2498
 
2935
2499
  // src/utils/retry.ts
2936
- var log10 = createLogger("Utils");
2500
+ var log7 = createLogger("Utils");
2937
2501
  var DEFAULT_OPTIONS = {
2938
2502
  maxAttempts: RETRY_DEFAULT_MAX_ATTEMPTS,
2939
2503
  baseDelayMs: RETRY_DEFAULT_BASE_DELAY_MS,
@@ -2957,7 +2521,7 @@ async function withRetry(fn, options = {}) {
2957
2521
  return result;
2958
2522
  } catch (error) {
2959
2523
  lastError = error instanceof Error ? error : new Error(String(error));
2960
- log10.warn(`Retry attempt ${attempt}/${opts.maxAttempts} failed: ${lastError.message}`);
2524
+ log7.warn(`Retry attempt ${attempt}/${opts.maxAttempts} failed: ${lastError.message}`);
2961
2525
  if (attempt < opts.maxAttempts) {
2962
2526
  const delay = Math.min(opts.baseDelayMs * Math.pow(2, attempt - 1), opts.maxDelayMs);
2963
2527
  await sleep(delay);
@@ -6435,7 +5999,7 @@ var DEDUST_GAS = {
6435
5999
  var NATIVE_TON_ADDRESS = "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c";
6436
6000
 
6437
6001
  // src/agent/tools/dedust/asset-cache.ts
6438
- var log11 = createLogger("Tools");
6002
+ var log8 = createLogger("Tools");
6439
6003
  var ASSET_LIST_URL = "https://assets.dedust.io/list.json";
6440
6004
  var CACHE_TTL_MS = 10 * 60 * 1e3;
6441
6005
  var cachedAssets = [];
@@ -6454,7 +6018,7 @@ async function getAssetList() {
6454
6018
  return cachedAssets;
6455
6019
  } catch (error) {
6456
6020
  if (cachedAssets.length > 0) {
6457
- log11.warn({ err: error }, "Asset list fetch failed, using stale cache");
6021
+ log8.warn({ err: error }, "Asset list fetch failed, using stale cache");
6458
6022
  return cachedAssets;
6459
6023
  }
6460
6024
  throw error;
@@ -6507,7 +6071,7 @@ var stonApiClient = new StonApiClient();
6507
6071
  function isTon(asset) {
6508
6072
  return asset.toLowerCase() === "ton";
6509
6073
  }
6510
- async function getStonfiQuote(fromAsset, toAsset, amount, slippage, log15) {
6074
+ async function getStonfiQuote(fromAsset, toAsset, amount, slippage, log12) {
6511
6075
  try {
6512
6076
  const isTonInput = isTon(fromAsset);
6513
6077
  const isTonOutput = isTon(toAsset);
@@ -6538,11 +6102,11 @@ async function getStonfiQuote(fromAsset, toAsset, amount, slippage, log15) {
6538
6102
  fee: feeAmount.toFixed(6)
6539
6103
  };
6540
6104
  } catch (err) {
6541
- log15.debug("dex.quoteSTONfi() failed:", err);
6105
+ log12.debug("dex.quoteSTONfi() failed:", err);
6542
6106
  return null;
6543
6107
  }
6544
6108
  }
6545
- async function getDedustQuote(fromAsset, toAsset, amount, slippage, log15) {
6109
+ async function getDedustQuote(fromAsset, toAsset, amount, slippage, log12) {
6546
6110
  try {
6547
6111
  const isTonInput = isTon(fromAsset);
6548
6112
  const isTonOutput = isTon(toAsset);
@@ -6576,7 +6140,7 @@ async function getDedustQuote(fromAsset, toAsset, amount, slippage, log15) {
6576
6140
  poolType
6577
6141
  };
6578
6142
  } catch (err) {
6579
- log15.debug("dex.quoteDeDust() failed:", err);
6143
+ log12.debug("dex.quoteDeDust() failed:", err);
6580
6144
  return null;
6581
6145
  }
6582
6146
  }
@@ -6748,14 +6312,14 @@ function validateDexParams(amount, slippage) {
6748
6312
  throw new PluginSDKError("Slippage must be between 0 and 1", "OPERATION_FAILED");
6749
6313
  }
6750
6314
  }
6751
- function createDexSDK(log15) {
6315
+ function createDexSDK(log12) {
6752
6316
  return {
6753
6317
  async quote(params) {
6754
6318
  validateDexParams(params.amount, params.slippage);
6755
6319
  const slippage = params.slippage ?? 0.01;
6756
6320
  const [stonfi, dedust] = await Promise.all([
6757
- getStonfiQuote(params.fromAsset, params.toAsset, params.amount, slippage, log15),
6758
- getDedustQuote(params.fromAsset, params.toAsset, params.amount, slippage, log15)
6321
+ getStonfiQuote(params.fromAsset, params.toAsset, params.amount, slippage, log12),
6322
+ getDedustQuote(params.fromAsset, params.toAsset, params.amount, slippage, log12)
6759
6323
  ]);
6760
6324
  if (!stonfi && !dedust) {
6761
6325
  throw new PluginSDKError("No DEX has liquidity for this pair", "OPERATION_FAILED");
@@ -6789,7 +6353,7 @@ function createDexSDK(log15) {
6789
6353
  params.toAsset,
6790
6354
  params.amount,
6791
6355
  params.slippage ?? 0.01,
6792
- log15
6356
+ log12
6793
6357
  );
6794
6358
  },
6795
6359
  async quoteDeDust(params) {
@@ -6798,25 +6362,25 @@ function createDexSDK(log15) {
6798
6362
  params.toAsset,
6799
6363
  params.amount,
6800
6364
  params.slippage ?? 0.01,
6801
- log15
6365
+ log12
6802
6366
  );
6803
6367
  },
6804
6368
  async swap(params) {
6805
6369
  validateDexParams(params.amount, params.slippage);
6806
6370
  if (params.dex === "stonfi") {
6807
- return executeSTONfiSwap(params, log15);
6371
+ return executeSTONfiSwap(params, log12);
6808
6372
  }
6809
6373
  if (params.dex === "dedust") {
6810
- return executeDedustSwap(params, log15);
6374
+ return executeDedustSwap(params, log12);
6811
6375
  }
6812
6376
  const quoteResult = await this.quote(params);
6813
- return quoteResult.recommended === "stonfi" ? executeSTONfiSwap(params, log15) : executeDedustSwap(params, log15);
6377
+ return quoteResult.recommended === "stonfi" ? executeSTONfiSwap(params, log12) : executeDedustSwap(params, log12);
6814
6378
  },
6815
6379
  async swapSTONfi(params) {
6816
- return executeSTONfiSwap(params, log15);
6380
+ return executeSTONfiSwap(params, log12);
6817
6381
  },
6818
6382
  async swapDeDust(params) {
6819
- return executeDedustSwap(params, log15);
6383
+ return executeDedustSwap(params, log12);
6820
6384
  }
6821
6385
  };
6822
6386
  }
@@ -6853,7 +6417,7 @@ function normalizeDomain(domain) {
6853
6417
  if (!d.endsWith(".ton")) d += ".ton";
6854
6418
  return d;
6855
6419
  }
6856
- function createDnsSDK(log15) {
6420
+ function createDnsSDK(log12) {
6857
6421
  return {
6858
6422
  async check(domain) {
6859
6423
  const normalized = normalizeDomain(domain);
@@ -6876,7 +6440,7 @@ function createDnsSDK(log15) {
6876
6440
  };
6877
6441
  } catch (err) {
6878
6442
  if (err instanceof PluginSDKError) throw err;
6879
- log15.debug("dns.check() failed:", err);
6443
+ log12.debug("dns.check() failed:", err);
6880
6444
  throw new PluginSDKError(
6881
6445
  `Failed to check domain: ${err instanceof Error ? err.message : String(err)}`,
6882
6446
  "OPERATION_FAILED"
@@ -6889,7 +6453,7 @@ function createDnsSDK(log15) {
6889
6453
  const response = await tonapiFetch(`/dns/${encodeURIComponent(normalized)}`);
6890
6454
  if (response.status === 404) return null;
6891
6455
  if (!response.ok) {
6892
- log15.debug(`dns.resolve() TonAPI error: ${response.status}`);
6456
+ log12.debug(`dns.resolve() TonAPI error: ${response.status}`);
6893
6457
  return null;
6894
6458
  }
6895
6459
  const data = await response.json();
@@ -6901,7 +6465,7 @@ function createDnsSDK(log15) {
6901
6465
  expirationDate: data.expiring_at || void 0
6902
6466
  };
6903
6467
  } catch (err) {
6904
- log15.debug("dns.resolve() failed:", err);
6468
+ log12.debug("dns.resolve() failed:", err);
6905
6469
  return null;
6906
6470
  }
6907
6471
  },
@@ -6911,7 +6475,7 @@ function createDnsSDK(log15) {
6911
6475
  `/dns/auctions?tld=ton&limit=${Math.min(limit ?? 20, 100)}`
6912
6476
  );
6913
6477
  if (!response.ok) {
6914
- log15.debug(`dns.getAuctions() TonAPI error: ${response.status}`);
6478
+ log12.debug(`dns.getAuctions() TonAPI error: ${response.status}`);
6915
6479
  return [];
6916
6480
  }
6917
6481
  const data = await response.json();
@@ -6924,7 +6488,7 @@ function createDnsSDK(log15) {
6924
6488
  bids: a.bids || 0
6925
6489
  }));
6926
6490
  } catch (err) {
6927
- log15.debug("dns.getAuctions() failed:", err);
6491
+ log12.debug("dns.getAuctions() failed:", err);
6928
6492
  return [];
6929
6493
  }
6930
6494
  },
@@ -7238,25 +6802,25 @@ function findJettonBalance(balances, jettonAddress) {
7238
6802
  }
7239
6803
  });
7240
6804
  }
7241
- function cleanupOldTransactions(db, retentionDays, log15) {
6805
+ function cleanupOldTransactions(db, retentionDays, log12) {
7242
6806
  if (Math.random() > CLEANUP_PROBABILITY) return;
7243
6807
  try {
7244
6808
  const cutoff = Math.floor(Date.now() / 1e3) - retentionDays * 24 * 60 * 60;
7245
6809
  const result = db.prepare("DELETE FROM used_transactions WHERE used_at < ?").run(cutoff);
7246
6810
  if (result.changes > 0) {
7247
- log15.debug(`Cleaned up ${result.changes} old transaction records (>${retentionDays}d)`);
6811
+ log12.debug(`Cleaned up ${result.changes} old transaction records (>${retentionDays}d)`);
7248
6812
  }
7249
6813
  } catch (err) {
7250
- log15.error("Transaction cleanup failed:", err);
6814
+ log12.error("Transaction cleanup failed:", err);
7251
6815
  }
7252
6816
  }
7253
- function createTonSDK(log15, db) {
6817
+ function createTonSDK(log12, db) {
7254
6818
  return {
7255
6819
  getAddress() {
7256
6820
  try {
7257
6821
  return getWalletAddress();
7258
6822
  } catch (err) {
7259
- log15.error("ton.getAddress() failed:", err);
6823
+ log12.error("ton.getAddress() failed:", err);
7260
6824
  return null;
7261
6825
  }
7262
6826
  },
@@ -7266,7 +6830,7 @@ function createTonSDK(log15, db) {
7266
6830
  if (!addr) return null;
7267
6831
  return await getWalletBalance(addr);
7268
6832
  } catch (err) {
7269
- log15.error("ton.getBalance() failed:", err);
6833
+ log12.error("ton.getBalance() failed:", err);
7270
6834
  return null;
7271
6835
  }
7272
6836
  },
@@ -7274,7 +6838,7 @@ function createTonSDK(log15, db) {
7274
6838
  try {
7275
6839
  return await getTonPrice();
7276
6840
  } catch (err) {
7277
- log15.error("ton.getPrice() failed:", err);
6841
+ log12.error("ton.getPrice() failed:", err);
7278
6842
  return null;
7279
6843
  }
7280
6844
  },
@@ -7325,7 +6889,7 @@ function createTonSDK(log15, db) {
7325
6889
  );
7326
6890
  return formatTransactions(transactions);
7327
6891
  } catch (err) {
7328
- log15.error("ton.getTransactions() failed:", err);
6892
+ log12.error("ton.getTransactions() failed:", err);
7329
6893
  return [];
7330
6894
  }
7331
6895
  },
@@ -7348,7 +6912,7 @@ function createTonSDK(log15, db) {
7348
6912
  throw new PluginSDKError("Wallet not initialized", "WALLET_NOT_INITIALIZED");
7349
6913
  }
7350
6914
  const maxAgeMinutes = params.maxAgeMinutes ?? DEFAULT_MAX_AGE_MINUTES;
7351
- cleanupOldTransactions(db, DEFAULT_TX_RETENTION_DAYS, log15);
6915
+ cleanupOldTransactions(db, DEFAULT_TX_RETENTION_DAYS, log12);
7352
6916
  try {
7353
6917
  const txs = await this.getTransactions(address4, 20);
7354
6918
  for (const tx of txs) {
@@ -7382,7 +6946,7 @@ function createTonSDK(log15, db) {
7382
6946
  };
7383
6947
  } catch (err) {
7384
6948
  if (err instanceof PluginSDKError) throw err;
7385
- log15.error("ton.verifyPayment() failed:", err);
6949
+ log12.error("ton.verifyPayment() failed:", err);
7386
6950
  return {
7387
6951
  verified: false,
7388
6952
  error: `Verification failed: ${err instanceof Error ? err.message : String(err)}`
@@ -7396,7 +6960,7 @@ function createTonSDK(log15, db) {
7396
6960
  if (!addr) return [];
7397
6961
  const response = await tonapiFetch(`/accounts/${encodeURIComponent(addr)}/jettons`);
7398
6962
  if (!response.ok) {
7399
- log15.error(`ton.getJettonBalances() TonAPI error: ${response.status}`);
6963
+ log12.error(`ton.getJettonBalances() TonAPI error: ${response.status}`);
7400
6964
  return [];
7401
6965
  }
7402
6966
  const data = await response.json();
@@ -7420,7 +6984,7 @@ function createTonSDK(log15, db) {
7420
6984
  }
7421
6985
  return balances;
7422
6986
  } catch (err) {
7423
- log15.error("ton.getJettonBalances() failed:", err);
6987
+ log12.error("ton.getJettonBalances() failed:", err);
7424
6988
  return [];
7425
6989
  }
7426
6990
  },
@@ -7429,7 +6993,7 @@ function createTonSDK(log15, db) {
7429
6993
  const response = await tonapiFetch(`/jettons/${encodeURIComponent(jettonAddress)}`);
7430
6994
  if (response.status === 404) return null;
7431
6995
  if (!response.ok) {
7432
- log15.error(`ton.getJettonInfo() TonAPI error: ${response.status}`);
6996
+ log12.error(`ton.getJettonInfo() TonAPI error: ${response.status}`);
7433
6997
  return null;
7434
6998
  }
7435
6999
  const data = await response.json();
@@ -7447,7 +7011,7 @@ function createTonSDK(log15, db) {
7447
7011
  image: data.preview || metadata.image || void 0
7448
7012
  };
7449
7013
  } catch (err) {
7450
- log15.error("ton.getJettonInfo() failed:", err);
7014
+ log12.error("ton.getJettonInfo() failed:", err);
7451
7015
  return null;
7452
7016
  }
7453
7017
  },
@@ -7534,12 +7098,13 @@ function createTonSDK(log15, db) {
7534
7098
  return seq;
7535
7099
  } catch (err) {
7536
7100
  lastErr = err;
7537
- const status = err?.status || err?.response?.status;
7538
- const respData = err?.response?.data;
7101
+ const httpErr = isHttpError(err) ? err : void 0;
7102
+ const status = httpErr?.status || httpErr?.response?.status;
7103
+ const respData = httpErr?.response?.data;
7539
7104
  if (status === 429 || status && status >= 500) {
7540
7105
  invalidateTonClientCache();
7541
7106
  if (attempt < MAX_SEND_ATTEMPTS) {
7542
- log15.warn(
7107
+ log12.warn(
7543
7108
  `sendJetton attempt ${attempt} failed (${status}): ${JSON.stringify(respData ?? err.message)}, retrying...`
7544
7109
  );
7545
7110
  await new Promise((r3) => setTimeout(r3, 1e3 * attempt));
@@ -7553,7 +7118,8 @@ function createTonSDK(log15, db) {
7553
7118
  });
7554
7119
  return { success: true, seqno };
7555
7120
  } catch (err) {
7556
- const status = err?.status || err?.response?.status;
7121
+ const outerHttpErr = isHttpError(err) ? err : void 0;
7122
+ const status = outerHttpErr?.status || outerHttpErr?.response?.status;
7557
7123
  if (status === 429 || status && status >= 500) {
7558
7124
  invalidateTonClientCache();
7559
7125
  }
@@ -7568,14 +7134,14 @@ function createTonSDK(log15, db) {
7568
7134
  try {
7569
7135
  const response = await tonapiFetch(`/accounts/${encodeURIComponent(ownerAddress)}/jettons`);
7570
7136
  if (!response.ok) {
7571
- log15.error(`ton.getJettonWalletAddress() TonAPI error: ${response.status}`);
7137
+ log12.error(`ton.getJettonWalletAddress() TonAPI error: ${response.status}`);
7572
7138
  return null;
7573
7139
  }
7574
7140
  const data = await response.json();
7575
7141
  const match = findJettonBalance(data.balances ?? [], jettonAddress);
7576
7142
  return match ? match.wallet_address.address : null;
7577
7143
  } catch (err) {
7578
- log15.error("ton.getJettonWalletAddress() failed:", err);
7144
+ log12.error("ton.getJettonWalletAddress() failed:", err);
7579
7145
  return null;
7580
7146
  }
7581
7147
  },
@@ -7752,7 +7318,7 @@ function createTonSDK(log15, db) {
7752
7318
  const wallet = loadWallet();
7753
7319
  return wallet?.publicKey ?? null;
7754
7320
  } catch (err) {
7755
- log15.error("ton.getPublicKey() failed:", err);
7321
+ log12.error("ton.getPublicKey() failed:", err);
7756
7322
  return null;
7757
7323
  }
7758
7324
  },
@@ -7768,14 +7334,14 @@ function createTonSDK(log15, db) {
7768
7334
  `/accounts/${encodeURIComponent(addr)}/nfts?limit=100&indirect_ownership=true`
7769
7335
  );
7770
7336
  if (!response.ok) {
7771
- log15.error(`ton.getNftItems() TonAPI error: ${response.status}`);
7337
+ log12.error(`ton.getNftItems() TonAPI error: ${response.status}`);
7772
7338
  return [];
7773
7339
  }
7774
7340
  const data = await response.json();
7775
7341
  if (!Array.isArray(data.nft_items)) return [];
7776
7342
  return data.nft_items.filter((item) => item.trust !== "blacklist").map((item) => mapNftItem(item));
7777
7343
  } catch (err) {
7778
- log15.error("ton.getNftItems() failed:", err);
7344
+ log12.error("ton.getNftItems() failed:", err);
7779
7345
  return [];
7780
7346
  }
7781
7347
  },
@@ -7784,13 +7350,13 @@ function createTonSDK(log15, db) {
7784
7350
  const response = await tonapiFetch(`/nfts/${encodeURIComponent(nftAddress)}`);
7785
7351
  if (response.status === 404) return null;
7786
7352
  if (!response.ok) {
7787
- log15.error(`ton.getNftInfo() TonAPI error: ${response.status}`);
7353
+ log12.error(`ton.getNftInfo() TonAPI error: ${response.status}`);
7788
7354
  return null;
7789
7355
  }
7790
7356
  const item = await response.json();
7791
7357
  return mapNftItem(item);
7792
7358
  } catch (err) {
7793
- log15.error("ton.getNftInfo() failed:", err);
7359
+ log12.error("ton.getNftInfo() failed:", err);
7794
7360
  return null;
7795
7361
  }
7796
7362
  },
@@ -7823,7 +7389,7 @@ function createTonSDK(log15, db) {
7823
7389
  `/rates?tokens=${encodeURIComponent(jettonAddress)}&currencies=usd,ton`
7824
7390
  );
7825
7391
  if (!response.ok) {
7826
- log15.debug(`ton.getJettonPrice() TonAPI error: ${response.status}`);
7392
+ log12.debug(`ton.getJettonPrice() TonAPI error: ${response.status}`);
7827
7393
  return null;
7828
7394
  }
7829
7395
  const data = await response.json();
@@ -7837,7 +7403,7 @@ function createTonSDK(log15, db) {
7837
7403
  change30d: rateData.diff_30d?.USD ?? null
7838
7404
  };
7839
7405
  } catch (err) {
7840
- log15.debug("ton.getJettonPrice() failed:", err);
7406
+ log12.debug("ton.getJettonPrice() failed:", err);
7841
7407
  return null;
7842
7408
  }
7843
7409
  },
@@ -7851,7 +7417,7 @@ function createTonSDK(log15, db) {
7851
7417
  tonapiFetch(`/jettons/${encodeURIComponent(jettonAddress)}`)
7852
7418
  ]);
7853
7419
  if (!holdersResponse.ok) {
7854
- log15.debug(`ton.getJettonHolders() TonAPI error: ${holdersResponse.status}`);
7420
+ log12.debug(`ton.getJettonHolders() TonAPI error: ${holdersResponse.status}`);
7855
7421
  return [];
7856
7422
  }
7857
7423
  const data = await holdersResponse.json();
@@ -7871,7 +7437,7 @@ function createTonSDK(log15, db) {
7871
7437
  };
7872
7438
  });
7873
7439
  } catch (err) {
7874
- log15.debug("ton.getJettonHolders() failed:", err);
7440
+ log12.debug("ton.getJettonHolders() failed:", err);
7875
7441
  return [];
7876
7442
  }
7877
7443
  },
@@ -7943,13 +7509,13 @@ function createTonSDK(log15, db) {
7943
7509
  holders: holdersCount
7944
7510
  };
7945
7511
  } catch (err) {
7946
- log15.debug("ton.getJettonHistory() failed:", err);
7512
+ log12.debug("ton.getJettonHistory() failed:", err);
7947
7513
  return null;
7948
7514
  }
7949
7515
  },
7950
7516
  // ─── Sub-namespaces ───────────────────────────────────────────
7951
- dex: Object.freeze(createDexSDK(log15)),
7952
- dns: Object.freeze(createDnsSDK(log15))
7517
+ dex: Object.freeze(createDexSDK(log12)),
7518
+ dns: Object.freeze(createDnsSDK(log12))
7953
7519
  };
7954
7520
  }
7955
7521
  function mapNftItem(item) {
@@ -7973,15 +7539,6 @@ function mapNftItem(item) {
7973
7539
  // src/sdk/telegram.ts
7974
7540
  import { Api as Api3 } from "telegram";
7975
7541
 
7976
- // src/utils/gramjs-bigint.ts
7977
- import { randomBytes } from "crypto";
7978
- function toLong(value) {
7979
- return typeof value === "bigint" ? value : BigInt(value);
7980
- }
7981
- function randomLong() {
7982
- return randomBytes(8).readBigUInt64BE();
7983
- }
7984
-
7985
7542
  // src/sdk/telegram-utils.ts
7986
7543
  function requireBridge(bridge) {
7987
7544
  if (!bridge.isAvailable()) {
@@ -7998,7 +7555,6 @@ function toSimpleMessage(msg) {
7998
7555
  return {
7999
7556
  id: msg.id,
8000
7557
  text: msg.message ?? "",
8001
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS fromId is a union of untyped peer types
8002
7558
  senderId: Number(msg.fromId?.userId ?? msg.fromId?.channelId ?? 0),
8003
7559
  timestamp: new Date(msg.date * 1e3)
8004
7560
  };
@@ -8012,7 +7568,7 @@ async function getApi() {
8012
7568
  }
8013
7569
 
8014
7570
  // src/sdk/telegram-messages.ts
8015
- function createTelegramMessagesSDK(bridge, log15) {
7571
+ function createTelegramMessagesSDK(bridge, log12) {
8016
7572
  function requireBridge2() {
8017
7573
  requireBridge(bridge);
8018
7574
  }
@@ -8119,7 +7675,7 @@ function createTelegramMessagesSDK(bridge, log15) {
8119
7675
  return (resultData.messages ?? []).map(toSimpleMessage);
8120
7676
  } catch (err) {
8121
7677
  if (err instanceof PluginSDKError) throw err;
8122
- log15.error("telegram.searchMessages() failed:", err);
7678
+ log12.error("telegram.searchMessages() failed:", err);
8123
7679
  return [];
8124
7680
  }
8125
7681
  },
@@ -8156,8 +7712,7 @@ function createTelegramMessagesSDK(bridge, log15) {
8156
7712
  limit,
8157
7713
  maxId: 0,
8158
7714
  minId: 0,
8159
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS BigInteger compat requires bigint cast
8160
- hash: 0n
7715
+ hash: toLong(0n)
8161
7716
  })
8162
7717
  );
8163
7718
  const messages = [];
@@ -8320,10 +7875,12 @@ function createTelegramMessagesSDK(bridge, log15) {
8320
7875
  if (!messages || messages.length === 0 || !messages[0].media) {
8321
7876
  return null;
8322
7877
  }
8323
- const doc = messages[0].media?.document;
8324
- if (doc?.size && Number(doc.size) > MAX_DOWNLOAD_SIZE) {
7878
+ const media = messages[0].media;
7879
+ const doc = media && "document" in media ? media.document : void 0;
7880
+ const docSize = doc && "size" in doc ? doc.size : void 0;
7881
+ if (docSize && Number(docSize) > MAX_DOWNLOAD_SIZE) {
8325
7882
  throw new PluginSDKError(
8326
- `File too large (${Math.round(Number(doc.size) / 1024 / 1024)}MB). Max: 50MB`,
7883
+ `File too large (${Math.round(Number(docSize) / 1024 / 1024)}MB). Max: 50MB`,
8327
7884
  "OPERATION_FAILED"
8328
7885
  );
8329
7886
  }
@@ -8347,8 +7904,7 @@ function createTelegramMessagesSDK(bridge, log15) {
8347
7904
  const result = await gramJsClient.invoke(
8348
7905
  new Api4.messages.GetScheduledHistory({
8349
7906
  peer,
8350
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS BigInteger compat requires bigint cast
8351
- hash: 0n
7907
+ hash: toLong(0n)
8352
7908
  })
8353
7909
  );
8354
7910
  const messages = [];
@@ -8362,7 +7918,7 @@ function createTelegramMessagesSDK(bridge, log15) {
8362
7918
  return messages;
8363
7919
  } catch (err) {
8364
7920
  if (err instanceof PluginSDKError) throw err;
8365
- log15.error("telegram.getScheduledMessages() failed:", err);
7921
+ log12.error("telegram.getScheduledMessages() failed:", err);
8366
7922
  return [];
8367
7923
  }
8368
7924
  },
@@ -8423,7 +7979,7 @@ function createTelegramMessagesSDK(bridge, log15) {
8423
7979
  }
8424
7980
 
8425
7981
  // src/sdk/telegram-social.ts
8426
- function createTelegramSocialSDK(bridge, log15) {
7982
+ function createTelegramSocialSDK(bridge, log12) {
8427
7983
  function requireBridge2() {
8428
7984
  requireBridge(bridge);
8429
7985
  }
@@ -8498,7 +8054,7 @@ function createTelegramSocialSDK(bridge, log15) {
8498
8054
  return null;
8499
8055
  } catch (err) {
8500
8056
  if (err instanceof PluginSDKError) throw err;
8501
- log15.error("telegram.getChatInfo() failed:", err);
8057
+ log12.error("telegram.getChatInfo() failed:", err);
8502
8058
  return null;
8503
8059
  }
8504
8060
  },
@@ -8612,7 +8168,7 @@ function createTelegramSocialSDK(bridge, log15) {
8612
8168
  });
8613
8169
  } catch (err) {
8614
8170
  if (err instanceof PluginSDKError) throw err;
8615
- log15.error("telegram.getParticipants() failed:", err);
8171
+ log12.error("telegram.getParticipants() failed:", err);
8616
8172
  return [];
8617
8173
  }
8618
8174
  },
@@ -8829,7 +8385,7 @@ function createTelegramSocialSDK(bridge, log15) {
8829
8385
  const user = await client.getInputEntity(userId.toString());
8830
8386
  const invoiceData = {
8831
8387
  peer: user,
8832
- giftId: BigInt(giftId),
8388
+ giftId: toLong(giftId),
8833
8389
  hideName: opts?.anonymous ?? false,
8834
8390
  message: opts?.message ? new Api4.TextWithEntities({ text: opts.message, entities: [] }) : void 0
8835
8391
  };
@@ -8913,7 +8469,7 @@ function createTelegramSocialSDK(bridge, log15) {
8913
8469
  const Api4 = await getApi();
8914
8470
  const result = await client.invoke(
8915
8471
  new Api4.payments.GetResaleStarGifts({
8916
- giftId: BigInt(giftId),
8472
+ giftId: toLong(giftId),
8917
8473
  offset: "",
8918
8474
  limit: limit ?? 50
8919
8475
  })
@@ -8974,7 +8530,7 @@ function createTelegramSocialSDK(bridge, log15) {
8974
8530
  }));
8975
8531
  } catch (err) {
8976
8532
  if (err instanceof PluginSDKError) throw err;
8977
- log15.error("telegram.getDialogs() failed:", err);
8533
+ log12.error("telegram.getDialogs() failed:", err);
8978
8534
  return [];
8979
8535
  }
8980
8536
  },
@@ -8988,7 +8544,7 @@ function createTelegramSocialSDK(bridge, log15) {
8988
8544
  return messages.map(toSimpleMessage);
8989
8545
  } catch (err) {
8990
8546
  if (err instanceof PluginSDKError) throw err;
8991
- log15.error("telegram.getHistory() failed:", err);
8547
+ log12.error("telegram.getHistory() failed:", err);
8992
8548
  return [];
8993
8549
  }
8994
8550
  },
@@ -9019,7 +8575,7 @@ function createTelegramSocialSDK(bridge, log15) {
9019
8575
  }));
9020
8576
  } catch (err) {
9021
8577
  if (err instanceof PluginSDKError) throw err;
9022
- log15.error("telegram.getStarsTransactions() failed:", err);
8578
+ log12.error("telegram.getStarsTransactions() failed:", err);
9023
8579
  return [];
9024
8580
  }
9025
8581
  },
@@ -9072,7 +8628,7 @@ function createTelegramSocialSDK(bridge, log15) {
9072
8628
  new Api4.payments.UpdateStarGiftPrice({
9073
8629
  stargift: new Api4.InputSavedStarGiftUser({ msgId }),
9074
8630
  resellAmount: new Api4.StarsAmount({
9075
- amount: BigInt(price),
8631
+ amount: toLong(price),
9076
8632
  nanos: 0
9077
8633
  })
9078
8634
  })
@@ -9124,7 +8680,7 @@ function createTelegramSocialSDK(bridge, log15) {
9124
8680
  };
9125
8681
  } catch (err) {
9126
8682
  if (err instanceof PluginSDKError) throw err;
9127
- log15.error("telegram.getCollectibleInfo() failed:", err);
8683
+ log12.error("telegram.getCollectibleInfo() failed:", err);
9128
8684
  return null;
9129
8685
  }
9130
8686
  },
@@ -9162,7 +8718,7 @@ function createTelegramSocialSDK(bridge, log15) {
9162
8718
  } catch (err) {
9163
8719
  if (err.errorMessage === "STARGIFT_SLUG_INVALID") return null;
9164
8720
  if (err instanceof PluginSDKError) throw err;
9165
- log15.error("telegram.getUniqueGift() failed:", err);
8721
+ log12.error("telegram.getUniqueGift() failed:", err);
9166
8722
  return null;
9167
8723
  }
9168
8724
  },
@@ -9188,7 +8744,7 @@ function createTelegramSocialSDK(bridge, log15) {
9188
8744
  } catch (err) {
9189
8745
  if (err.errorMessage === "STARGIFT_SLUG_INVALID") return null;
9190
8746
  if (err instanceof PluginSDKError) throw err;
9191
- log15.error("telegram.getUniqueGiftValue() failed:", err);
8747
+ log12.error("telegram.getUniqueGiftValue() failed:", err);
9192
8748
  return null;
9193
8749
  }
9194
8750
  },
@@ -9203,7 +8759,7 @@ function createTelegramSocialSDK(bridge, log15) {
9203
8759
  new Api4.payments.SendStarGiftOffer({
9204
8760
  peer,
9205
8761
  slug: giftSlug,
9206
- price: new Api4.StarsAmount({ amount: BigInt(price), nanos: 0 }),
8762
+ price: new Api4.StarsAmount({ amount: toLong(price), nanos: 0 }),
9207
8763
  duration,
9208
8764
  randomId: randomLong()
9209
8765
  })
@@ -9223,13 +8779,13 @@ function createTelegramSocialSDK(bridge, log15) {
9223
8779
  const client = getClient2();
9224
8780
  const { Api: Api4, helpers } = await import("telegram");
9225
8781
  const { CustomFile } = await import("telegram/client/uploads.js");
9226
- const { readFileSync: readFileSync8, statSync: statSync2 } = await import("fs");
8782
+ const { readFileSync: readFileSync7, statSync: statSync2 } = await import("fs");
9227
8783
  const { basename: basename2 } = await import("path");
9228
8784
  const { resolve: resolve2, normalize: normalize2 } = await import("path");
9229
- const { homedir: homedir3 } = await import("os");
8785
+ const { homedir: homedir2 } = await import("os");
9230
8786
  const { realpathSync } = await import("fs");
9231
8787
  const filePath = realpathSync(resolve2(normalize2(mediaPath)));
9232
- const home = homedir3();
8788
+ const home = homedir2();
9233
8789
  const teletonWorkspace = `${home}/.teleton/workspace/`;
9234
8790
  const allowedPrefixes = [
9235
8791
  "/tmp/",
@@ -9248,7 +8804,7 @@ function createTelegramSocialSDK(bridge, log15) {
9248
8804
  }
9249
8805
  const fileName = basename2(filePath);
9250
8806
  const fileSize = statSync2(filePath).size;
9251
- const fileBuffer = readFileSync8(filePath);
8807
+ const fileBuffer = readFileSync7(filePath);
9252
8808
  const isVideo = filePath.toLowerCase().match(/\.(mp4|mov|avi|webm|mkv|m4v)$/);
9253
8809
  const customFile = new CustomFile(fileName, fileSize, filePath, fileBuffer);
9254
8810
  const uploadedFile = await client.uploadFile({
@@ -9299,7 +8855,7 @@ function createTelegramSocialSDK(bridge, log15) {
9299
8855
  }
9300
8856
 
9301
8857
  // src/sdk/telegram.ts
9302
- function createTelegramSDK(bridge, log15) {
8858
+ function createTelegramSDK(bridge, log12) {
9303
8859
  function requireBridge2() {
9304
8860
  requireBridge(bridge);
9305
8861
  }
@@ -9403,7 +8959,7 @@ function createTelegramSDK(bridge, log15) {
9403
8959
  timestamp: m.timestamp
9404
8960
  }));
9405
8961
  } catch (err) {
9406
- log15.error("telegram.getMessages() failed:", err);
8962
+ log12.error("telegram.getMessages() failed:", err);
9407
8963
  return [];
9408
8964
  }
9409
8965
  },
@@ -9425,7 +8981,7 @@ function createTelegramSDK(bridge, log15) {
9425
8981
  return bridge.isAvailable();
9426
8982
  },
9427
8983
  getRawClient() {
9428
- log15.warn("getRawClient() called \u2014 this bypasses SDK sandbox guarantees");
8984
+ log12.warn("getRawClient() called \u2014 this bypasses SDK sandbox guarantees");
9429
8985
  if (!bridge.isAvailable()) return null;
9430
8986
  try {
9431
8987
  return bridge.getClient().getClient();
@@ -9434,23 +8990,23 @@ function createTelegramSDK(bridge, log15) {
9434
8990
  }
9435
8991
  },
9436
8992
  // Spread extended methods from sub-modules
9437
- ...createTelegramMessagesSDK(bridge, log15),
9438
- ...createTelegramSocialSDK(bridge, log15)
8993
+ ...createTelegramMessagesSDK(bridge, log12),
8994
+ ...createTelegramSocialSDK(bridge, log12)
9439
8995
  };
9440
8996
  }
9441
8997
 
9442
8998
  // src/sdk/secrets.ts
9443
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, existsSync as existsSync5 } from "fs";
9444
- import { join as join4 } from "path";
9445
- var SECRETS_DIR = join4(TELETON_ROOT, "plugins", "data");
8999
+ import { readFileSync as readFileSync3, writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync4 } from "fs";
9000
+ import { join as join2 } from "path";
9001
+ var SECRETS_DIR = join2(TELETON_ROOT, "plugins", "data");
9446
9002
  function getSecretsPath(pluginName) {
9447
- return join4(SECRETS_DIR, `${pluginName}.secrets.json`);
9003
+ return join2(SECRETS_DIR, `${pluginName}.secrets.json`);
9448
9004
  }
9449
9005
  function readSecretsFile(pluginName) {
9450
9006
  const filePath = getSecretsPath(pluginName);
9451
9007
  try {
9452
- if (!existsSync5(filePath)) return {};
9453
- const raw = readFileSync4(filePath, "utf-8");
9008
+ if (!existsSync4(filePath)) return {};
9009
+ const raw = readFileSync3(filePath, "utf-8");
9454
9010
  const parsed = JSON.parse(raw);
9455
9011
  if (typeof parsed !== "object" || parsed === null) return {};
9456
9012
  return parsed;
@@ -9459,40 +9015,40 @@ function readSecretsFile(pluginName) {
9459
9015
  }
9460
9016
  }
9461
9017
  function writePluginSecret(pluginName, key, value) {
9462
- mkdirSync3(SECRETS_DIR, { recursive: true, mode: 448 });
9018
+ mkdirSync2(SECRETS_DIR, { recursive: true, mode: 448 });
9463
9019
  const filePath = getSecretsPath(pluginName);
9464
9020
  const existing = readSecretsFile(pluginName);
9465
9021
  existing[key] = value;
9466
- writeFileSync2(filePath, JSON.stringify(existing, null, 2), { mode: 384 });
9022
+ writeFileSync(filePath, JSON.stringify(existing, null, 2), { mode: 384 });
9467
9023
  }
9468
9024
  function deletePluginSecret(pluginName, key) {
9469
9025
  const existing = readSecretsFile(pluginName);
9470
9026
  if (!(key in existing)) return false;
9471
9027
  delete existing[key];
9472
9028
  const filePath = getSecretsPath(pluginName);
9473
- writeFileSync2(filePath, JSON.stringify(existing, null, 2), { mode: 384 });
9029
+ writeFileSync(filePath, JSON.stringify(existing, null, 2), { mode: 384 });
9474
9030
  return true;
9475
9031
  }
9476
9032
  function listPluginSecretKeys(pluginName) {
9477
9033
  return Object.keys(readSecretsFile(pluginName));
9478
9034
  }
9479
- function createSecretsSDK(pluginName, pluginConfig, log15) {
9035
+ function createSecretsSDK(pluginName, pluginConfig, log12) {
9480
9036
  const envPrefix = pluginName.replace(/-/g, "_").toUpperCase();
9481
9037
  function get(key) {
9482
9038
  const envKey = `${envPrefix}_${key.toUpperCase()}`;
9483
9039
  const envValue = process.env[envKey];
9484
9040
  if (envValue) {
9485
- log15.debug(`Secret "${key}" resolved from env var ${envKey}`);
9041
+ log12.debug(`Secret "${key}" resolved from env var ${envKey}`);
9486
9042
  return envValue;
9487
9043
  }
9488
9044
  const stored = readSecretsFile(pluginName);
9489
9045
  if (key in stored && stored[key]) {
9490
- log15.debug(`Secret "${key}" resolved from secrets store`);
9046
+ log12.debug(`Secret "${key}" resolved from secrets store`);
9491
9047
  return stored[key];
9492
9048
  }
9493
9049
  const configValue = pluginConfig[key];
9494
9050
  if (configValue !== void 0 && configValue !== null) {
9495
- log15.debug(`Secret "${key}" resolved from pluginConfig`);
9051
+ log12.debug(`Secret "${key}" resolved from pluginConfig`);
9496
9052
  return String(configValue);
9497
9053
  }
9498
9054
  return void 0;
@@ -9594,7 +9150,7 @@ function createStorageSDK(db) {
9594
9150
  }
9595
9151
 
9596
9152
  // src/sdk/bot.ts
9597
- function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLimiter, log15) {
9153
+ function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLimiter, log12) {
9598
9154
  if (!router || !manifest || !manifest.inline && !manifest.callbacks) {
9599
9155
  return null;
9600
9156
  }
@@ -9617,7 +9173,7 @@ function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLi
9617
9173
  },
9618
9174
  onInlineQuery(handler) {
9619
9175
  if (handlers.onInlineQuery) {
9620
- log15.warn("onInlineQuery called again \u2014 overwriting previous handler");
9176
+ log12.warn("onInlineQuery called again \u2014 overwriting previous handler");
9621
9177
  }
9622
9178
  handlers.onInlineQuery = async (ctx) => {
9623
9179
  if (rateLimiter) {
@@ -9663,7 +9219,7 @@ function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLi
9663
9219
  return;
9664
9220
  } catch (error) {
9665
9221
  if (error?.errorMessage === "MESSAGE_NOT_MODIFIED") return;
9666
- log15.warn(`GramJS edit failed, falling back to Grammy: ${error?.errorMessage || error}`);
9222
+ log12.warn(`GramJS edit failed, falling back to Grammy: ${error?.errorMessage || error}`);
9667
9223
  }
9668
9224
  }
9669
9225
  if (grammyBot) {
@@ -9676,7 +9232,7 @@ function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLi
9676
9232
  });
9677
9233
  } catch (error) {
9678
9234
  if (error?.description?.includes("message is not modified")) return;
9679
- log15.error(`Failed to edit inline message: ${error?.description || error}`);
9235
+ log12.error(`Failed to edit inline message: ${error?.description || error}`);
9680
9236
  }
9681
9237
  }
9682
9238
  },
@@ -9735,13 +9291,13 @@ function createSafeDb(db) {
9735
9291
  });
9736
9292
  }
9737
9293
  function createPluginSDK(deps, opts) {
9738
- const log15 = createLogger2(opts.pluginName);
9294
+ const log12 = createLogger2(opts.pluginName);
9739
9295
  const safeDb = opts.db ? createSafeDb(opts.db) : null;
9740
- const ton = Object.freeze(createTonSDK(log15, safeDb));
9741
- const telegram = Object.freeze(createTelegramSDK(deps.bridge, log15));
9742
- const secrets = Object.freeze(createSecretsSDK(opts.pluginName, opts.pluginConfig, log15));
9296
+ const ton = Object.freeze(createTonSDK(log12, safeDb));
9297
+ const telegram = Object.freeze(createTelegramSDK(deps.bridge, log12));
9298
+ const secrets = Object.freeze(createSecretsSDK(opts.pluginName, opts.pluginConfig, log12));
9743
9299
  const storage = safeDb ? Object.freeze(createStorageSDK(safeDb)) : null;
9744
- const frozenLog = Object.freeze(log15);
9300
+ const frozenLog = Object.freeze(log12);
9745
9301
  const frozenConfig = Object.freeze(JSON.parse(JSON.stringify(opts.sanitizedConfig ?? {})));
9746
9302
  const frozenPluginConfig = Object.freeze(JSON.parse(JSON.stringify(opts.pluginConfig ?? {})));
9747
9303
  let cachedBot;
@@ -9772,20 +9328,20 @@ function createPluginSDK(deps, opts) {
9772
9328
  },
9773
9329
  on(hookName, handler, onOpts) {
9774
9330
  if (!opts.hookRegistry) {
9775
- log15.warn(`Hook registration unavailable \u2014 sdk.on() ignored`);
9331
+ log12.warn(`Hook registration unavailable \u2014 sdk.on() ignored`);
9776
9332
  return;
9777
9333
  }
9778
9334
  if (opts.declaredHooks) {
9779
9335
  const declared = opts.declaredHooks.some((h2) => h2.name === hookName);
9780
9336
  if (!declared) {
9781
- log15.warn(`Hook "${hookName}" not declared in manifest \u2014 registration rejected`);
9337
+ log12.warn(`Hook "${hookName}" not declared in manifest \u2014 registration rejected`);
9782
9338
  return;
9783
9339
  }
9784
9340
  }
9785
9341
  const rawPriority = Number(onOpts?.priority) || 0;
9786
9342
  const clampedPriority = Math.max(-1e3, Math.min(1e3, rawPriority));
9787
9343
  if (rawPriority !== clampedPriority) {
9788
- log15.debug(`Hook "${hookName}" priority ${rawPriority} clamped to ${clampedPriority}`);
9344
+ log12.debug(`Hook "${hookName}" priority ${rawPriority} clamped to ${clampedPriority}`);
9789
9345
  }
9790
9346
  const registered = opts.hookRegistry.register({
9791
9347
  pluginId: opts.pluginName,
@@ -9795,7 +9351,7 @@ function createPluginSDK(deps, opts) {
9795
9351
  globalPriority: opts.globalPriority ?? 0
9796
9352
  });
9797
9353
  if (!registered) {
9798
- log15.warn(
9354
+ log12.warn(
9799
9355
  `Hook registration limit reached for plugin "${opts.pluginName}" \u2014 "${hookName}" rejected`
9800
9356
  );
9801
9357
  }
@@ -9914,24 +9470,24 @@ var HookRegistry = class {
9914
9470
 
9915
9471
  // src/agent/tools/plugin-loader.ts
9916
9472
  var execFileAsync = promisify(execFile);
9917
- var log12 = createLogger("PluginLoader");
9918
- var PLUGIN_DATA_DIR = join5(TELETON_ROOT, "plugins", "data");
9473
+ var log9 = createLogger("PluginLoader");
9474
+ var PLUGIN_DATA_DIR = join3(TELETON_ROOT, "plugins", "data");
9919
9475
  function adaptPlugin(raw, entryName, config, loadedModuleNames, sdkDeps, hookRegistry, pluginPriorities) {
9920
9476
  let manifest = null;
9921
9477
  if (raw.manifest) {
9922
9478
  try {
9923
9479
  manifest = validateManifest(raw.manifest);
9924
9480
  } catch (err) {
9925
- log12.warn(
9481
+ log9.warn(
9926
9482
  `[${entryName}] invalid manifest, ignoring: ${err instanceof Error ? err.message : err}`
9927
9483
  );
9928
9484
  }
9929
9485
  }
9930
9486
  if (!manifest) {
9931
- const manifestPath = join5(WORKSPACE_PATHS.PLUGINS_DIR, entryName, "manifest.json");
9487
+ const manifestPath = join3(WORKSPACE_PATHS.PLUGINS_DIR, entryName, "manifest.json");
9932
9488
  try {
9933
- if (existsSync6(manifestPath)) {
9934
- const diskManifest = JSON.parse(readFileSync5(manifestPath, "utf-8"));
9489
+ if (existsSync5(manifestPath)) {
9490
+ const diskManifest = JSON.parse(readFileSync4(manifestPath, "utf-8"));
9935
9491
  if (diskManifest && typeof diskManifest.version === "string") {
9936
9492
  manifest = {
9937
9493
  name: entryName,
@@ -10006,7 +9562,7 @@ function adaptPlugin(raw, entryName, config, loadedModuleNames, sdkDeps, hookReg
10006
9562
  },
10007
9563
  migrate() {
10008
9564
  try {
10009
- const dbPath = join5(PLUGIN_DATA_DIR, `${pluginName}.db`);
9565
+ const dbPath = join3(PLUGIN_DATA_DIR, `${pluginName}.db`);
10010
9566
  pluginDb = openModuleDb(dbPath);
10011
9567
  if (hasMigrate) {
10012
9568
  raw.migrate?.(pluginDb);
@@ -10111,36 +9667,36 @@ function adaptPlugin(raw, entryName, config, loadedModuleNames, sdkDeps, hookReg
10111
9667
  return module;
10112
9668
  }
10113
9669
  async function ensurePluginDeps(pluginDir, pluginEntry) {
10114
- const pkgJson = join5(pluginDir, "package.json");
10115
- const lockfile = join5(pluginDir, "package-lock.json");
10116
- const nodeModules = join5(pluginDir, "node_modules");
10117
- if (!existsSync6(pkgJson)) return;
10118
- if (!existsSync6(lockfile)) {
10119
- log12.warn(
9670
+ const pkgJson = join3(pluginDir, "package.json");
9671
+ const lockfile = join3(pluginDir, "package-lock.json");
9672
+ const nodeModules = join3(pluginDir, "node_modules");
9673
+ if (!existsSync5(pkgJson)) return;
9674
+ if (!existsSync5(lockfile)) {
9675
+ log9.warn(
10120
9676
  `[${pluginEntry}] package.json without package-lock.json \u2014 skipping (lockfile required)`
10121
9677
  );
10122
9678
  return;
10123
9679
  }
10124
- if (existsSync6(nodeModules)) {
10125
- const marker = join5(nodeModules, ".package-lock.json");
10126
- if (existsSync6(marker) && statSync(marker).mtimeMs >= statSync(lockfile).mtimeMs) return;
9680
+ if (existsSync5(nodeModules)) {
9681
+ const marker = join3(nodeModules, ".package-lock.json");
9682
+ if (existsSync5(marker) && statSync(marker).mtimeMs >= statSync(lockfile).mtimeMs) return;
10127
9683
  }
10128
- log12.info(`[${pluginEntry}] Installing dependencies...`);
9684
+ log9.info(`[${pluginEntry}] Installing dependencies...`);
10129
9685
  try {
10130
9686
  await execFileAsync("npm", ["ci", "--ignore-scripts", "--no-audit", "--no-fund"], {
10131
9687
  cwd: pluginDir,
10132
9688
  timeout: 6e4,
10133
9689
  env: { ...process.env, NODE_ENV: "production" }
10134
9690
  });
10135
- log12.info(`[${pluginEntry}] Dependencies installed`);
9691
+ log9.info(`[${pluginEntry}] Dependencies installed`);
10136
9692
  } catch (err) {
10137
- log12.error(`[${pluginEntry}] Failed to install deps: ${String(err).slice(0, 300)}`);
9693
+ log9.error(`[${pluginEntry}] Failed to install deps: ${String(err).slice(0, 300)}`);
10138
9694
  }
10139
9695
  }
10140
9696
  async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
10141
9697
  const hookRegistry = new HookRegistry();
10142
9698
  const pluginsDir = WORKSPACE_PATHS.PLUGINS_DIR;
10143
- if (!existsSync6(pluginsDir)) {
9699
+ if (!existsSync5(pluginsDir)) {
10144
9700
  return { modules: [], hookRegistry };
10145
9701
  }
10146
9702
  let pluginPriorities = /* @__PURE__ */ new Map();
@@ -10156,15 +9712,15 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
10156
9712
  const pluginPaths = [];
10157
9713
  for (const entry of entries) {
10158
9714
  if (entry === "data") continue;
10159
- const entryPath = join5(pluginsDir, entry);
9715
+ const entryPath = join3(pluginsDir, entry);
10160
9716
  let modulePath = null;
10161
9717
  try {
10162
9718
  const stat = statSync(entryPath);
10163
9719
  if (stat.isFile() && entry.endsWith(".js")) {
10164
9720
  modulePath = entryPath;
10165
9721
  } else if (stat.isDirectory()) {
10166
- const indexPath = join5(entryPath, "index.js");
10167
- if (existsSync6(indexPath)) {
9722
+ const indexPath = join3(entryPath, "index.js");
9723
+ if (existsSync5(indexPath)) {
10168
9724
  modulePath = indexPath;
10169
9725
  }
10170
9726
  }
@@ -10176,7 +9732,7 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
10176
9732
  }
10177
9733
  }
10178
9734
  await Promise.allSettled(
10179
- pluginPaths.filter(({ path }) => path.endsWith("index.js")).map(({ entry }) => ensurePluginDeps(join5(pluginsDir, entry), entry))
9735
+ pluginPaths.filter(({ path }) => path.endsWith("index.js")).map(({ entry }) => ensurePluginDeps(join3(pluginsDir, entry), entry))
10180
9736
  );
10181
9737
  const loadResults = await Promise.allSettled(
10182
9738
  pluginPaths.map(async ({ entry, path }) => {
@@ -10187,7 +9743,7 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
10187
9743
  );
10188
9744
  for (const result of loadResults) {
10189
9745
  if (result.status === "rejected") {
10190
- log12.error(
9746
+ log9.error(
10191
9747
  `Plugin failed to load: ${result.reason instanceof Error ? result.reason.message : result.reason}`
10192
9748
  );
10193
9749
  continue;
@@ -10195,7 +9751,7 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
10195
9751
  const { entry, mod } = result.value;
10196
9752
  try {
10197
9753
  if (!mod.tools || typeof mod.tools !== "function" && !Array.isArray(mod.tools)) {
10198
- log12.warn(`Plugin "${entry}": no 'tools' array or function exported, skipping`);
9754
+ log9.warn(`Plugin "${entry}": no 'tools' array or function exported, skipping`);
10199
9755
  continue;
10200
9756
  }
10201
9757
  const adapted = adaptPlugin(
@@ -10208,21 +9764,21 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
10208
9764
  pluginPriorities
10209
9765
  );
10210
9766
  if (loadedNames.has(adapted.name)) {
10211
- log12.warn(`Plugin "${adapted.name}" already loaded, skipping duplicate from "${entry}"`);
9767
+ log9.warn(`Plugin "${adapted.name}" already loaded, skipping duplicate from "${entry}"`);
10212
9768
  continue;
10213
9769
  }
10214
9770
  loadedNames.add(adapted.name);
10215
9771
  modules.push(adapted);
10216
9772
  } catch (err) {
10217
- log12.error(`Plugin "${entry}" failed to adapt: ${err instanceof Error ? err.message : err}`);
9773
+ log9.error(`Plugin "${entry}" failed to adapt: ${err instanceof Error ? err.message : err}`);
10218
9774
  }
10219
9775
  }
10220
9776
  return { modules, hookRegistry };
10221
9777
  }
10222
9778
 
10223
9779
  // src/config/configurable-keys.ts
10224
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, existsSync as existsSync7 } from "fs";
10225
- import { parse as parse2, stringify as stringify2 } from "yaml";
9780
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, existsSync as existsSync6 } from "fs";
9781
+ import { parse, stringify } from "yaml";
10226
9782
  var noValidation = () => void 0;
10227
9783
  var identity = (v) => v;
10228
9784
  var nonEmpty = (v) => v.length > 0 ? void 0 : "Must not be empty";
@@ -10841,11 +10397,11 @@ function deleteNestedValue(obj, path) {
10841
10397
  }
10842
10398
  function readRawConfig(configPath) {
10843
10399
  const fullPath = expandPath(configPath);
10844
- if (!existsSync7(fullPath)) {
10400
+ if (!existsSync6(fullPath)) {
10845
10401
  throw new Error(`Config file not found: ${fullPath}
10846
10402
  Run 'teleton setup' to create one.`);
10847
10403
  }
10848
- const raw = parse2(readFileSync6(fullPath, "utf-8"));
10404
+ const raw = parse(readFileSync5(fullPath, "utf-8"));
10849
10405
  if (!raw || typeof raw !== "object") {
10850
10406
  throw new Error(`Invalid config file: ${fullPath}`);
10851
10407
  }
@@ -10861,26 +10417,26 @@ function writeRawConfig(raw, configPath) {
10861
10417
  raw.meta = raw.meta ?? {};
10862
10418
  raw.meta.last_modified_at = (/* @__PURE__ */ new Date()).toISOString();
10863
10419
  const fullPath = expandPath(configPath);
10864
- writeFileSync3(fullPath, stringify2(raw), { encoding: "utf-8", mode: 384 });
10420
+ writeFileSync2(fullPath, stringify(raw), { encoding: "utf-8", mode: 384 });
10865
10421
  }
10866
10422
 
10867
10423
  // src/ton-proxy/manager.ts
10868
10424
  import { spawn, execSync } from "child_process";
10869
10425
  import {
10870
- existsSync as existsSync8,
10426
+ existsSync as existsSync7,
10871
10427
  chmodSync,
10872
10428
  createWriteStream,
10873
- readFileSync as readFileSync7,
10874
- writeFileSync as writeFileSync4,
10429
+ readFileSync as readFileSync6,
10430
+ writeFileSync as writeFileSync3,
10875
10431
  unlinkSync
10876
10432
  } from "fs";
10877
- import { mkdir as mkdir2 } from "fs/promises";
10878
- import { join as join6 } from "path";
10433
+ import { mkdir } from "fs/promises";
10434
+ import { join as join4 } from "path";
10879
10435
  import { pipeline } from "stream/promises";
10880
- var log13 = createLogger("TonProxy");
10436
+ var log10 = createLogger("TonProxy");
10881
10437
  var GITHUB_REPO = "xssnick/Tonutils-Proxy";
10882
- var BINARY_DIR = join6(TELETON_ROOT, "bin");
10883
- var PID_FILE = join6(TELETON_ROOT, "ton-proxy.pid");
10438
+ var BINARY_DIR = join4(TELETON_ROOT, "bin");
10439
+ var PID_FILE = join4(TELETON_ROOT, "ton-proxy.pid");
10884
10440
  var HEALTH_CHECK_INTERVAL_MS = 3e4;
10885
10441
  var HEALTH_CHECK_TIMEOUT_MS = 5e3;
10886
10442
  var KILL_GRACE_MS = 5e3;
@@ -10896,11 +10452,11 @@ var TonProxyManager = class {
10896
10452
  /** Resolve the binary path — user-specified or auto-detected */
10897
10453
  getBinaryPath() {
10898
10454
  if (this.config.binary_path) return this.config.binary_path;
10899
- return join6(BINARY_DIR, getBinaryName());
10455
+ return join4(BINARY_DIR, getBinaryName());
10900
10456
  }
10901
10457
  /** Check if the binary exists on disk */
10902
10458
  isInstalled() {
10903
- return existsSync8(this.getBinaryPath());
10459
+ return existsSync7(this.getBinaryPath());
10904
10460
  }
10905
10461
  /** Whether the proxy process is currently running */
10906
10462
  isRunning() {
@@ -10912,8 +10468,8 @@ var TonProxyManager = class {
10912
10468
  */
10913
10469
  async install() {
10914
10470
  const binaryName = getBinaryName();
10915
- log13.info(`Downloading TON Proxy binary (${binaryName})...`);
10916
- await mkdir2(BINARY_DIR, { recursive: true });
10471
+ log10.info(`Downloading TON Proxy binary (${binaryName})...`);
10472
+ await mkdir(BINARY_DIR, { recursive: true });
10917
10473
  const releaseUrl = `https://api.github.com/repos/${GITHUB_REPO}/releases/latest`;
10918
10474
  const releaseRes = await fetch(releaseUrl, {
10919
10475
  headers: { Accept: "application/vnd.github.v3+json" }
@@ -10924,7 +10480,7 @@ var TonProxyManager = class {
10924
10480
  const release = await releaseRes.json();
10925
10481
  const tag = release.tag_name;
10926
10482
  const downloadUrl = `https://github.com/${GITHUB_REPO}/releases/download/${tag}/${binaryName}`;
10927
- log13.info(`Downloading ${downloadUrl}`);
10483
+ log10.info(`Downloading ${downloadUrl}`);
10928
10484
  const res = await fetch(downloadUrl);
10929
10485
  if (!res.ok || !res.body) {
10930
10486
  throw new Error(`Download failed: ${res.status} ${res.statusText}`);
@@ -10933,17 +10489,17 @@ var TonProxyManager = class {
10933
10489
  const fileStream = createWriteStream(dest);
10934
10490
  await pipeline(res.body, fileStream);
10935
10491
  chmodSync(dest, 493);
10936
- log13.info(`TON Proxy installed: ${dest} (${tag})`);
10492
+ log10.info(`TON Proxy installed: ${dest} (${tag})`);
10937
10493
  }
10938
10494
  /** Kill any orphan proxy process from a previous session */
10939
10495
  killOrphan() {
10940
- if (existsSync8(PID_FILE)) {
10496
+ if (existsSync7(PID_FILE)) {
10941
10497
  try {
10942
- const pid = parseInt(readFileSync7(PID_FILE, "utf-8").trim(), 10);
10498
+ const pid = parseInt(readFileSync6(PID_FILE, "utf-8").trim(), 10);
10943
10499
  if (pid && !isNaN(pid)) {
10944
10500
  try {
10945
10501
  process.kill(pid, 0);
10946
- log13.warn(`Killing orphan TON Proxy (PID ${pid}) from previous session`);
10502
+ log10.warn(`Killing orphan TON Proxy (PID ${pid}) from previous session`);
10947
10503
  process.kill(pid, "SIGTERM");
10948
10504
  } catch {
10949
10505
  }
@@ -10960,7 +10516,7 @@ var TonProxyManager = class {
10960
10516
  const pidMatch = out.match(/pid=(\d+)/);
10961
10517
  if (pidMatch) {
10962
10518
  const pid = parseInt(pidMatch[1], 10);
10963
- log13.warn(`Port ${this.config.port} occupied by PID ${pid}, killing it`);
10519
+ log10.warn(`Port ${this.config.port} occupied by PID ${pid}, killing it`);
10964
10520
  try {
10965
10521
  process.kill(pid, "SIGTERM");
10966
10522
  } catch {
@@ -10973,22 +10529,22 @@ var TonProxyManager = class {
10973
10529
  /** Write PID to file for orphan detection */
10974
10530
  writePidFile(pid) {
10975
10531
  try {
10976
- writeFileSync4(PID_FILE, String(pid), { mode: 384 });
10532
+ writeFileSync3(PID_FILE, String(pid), { mode: 384 });
10977
10533
  } catch {
10978
- log13.warn("Failed to write TON Proxy PID file");
10534
+ log10.warn("Failed to write TON Proxy PID file");
10979
10535
  }
10980
10536
  }
10981
10537
  /** Remove PID file */
10982
10538
  removePidFile() {
10983
10539
  try {
10984
- if (existsSync8(PID_FILE)) unlinkSync(PID_FILE);
10540
+ if (existsSync7(PID_FILE)) unlinkSync(PID_FILE);
10985
10541
  } catch {
10986
10542
  }
10987
10543
  }
10988
10544
  /** Start the proxy process */
10989
10545
  async start() {
10990
10546
  if (this.isRunning()) {
10991
- log13.warn("TON Proxy is already running");
10547
+ log10.warn("TON Proxy is already running");
10992
10548
  return;
10993
10549
  }
10994
10550
  this.restartCount = 0;
@@ -10999,7 +10555,7 @@ var TonProxyManager = class {
10999
10555
  }
11000
10556
  const binaryPath = this.getBinaryPath();
11001
10557
  const port = String(this.config.port);
11002
- log13.info(`Starting TON Proxy on 127.0.0.1:${port}`);
10558
+ log10.info(`Starting TON Proxy on 127.0.0.1:${port}`);
11003
10559
  this.process = spawn(binaryPath, ["-addr", `127.0.0.1:${port}`], {
11004
10560
  cwd: BINARY_DIR,
11005
10561
  stdio: ["ignore", "pipe", "pipe"],
@@ -11007,24 +10563,24 @@ var TonProxyManager = class {
11007
10563
  });
11008
10564
  this.process.stdout?.on("data", (chunk) => {
11009
10565
  const line = chunk.toString().trim();
11010
- if (line) log13.debug(`[proxy] ${line}`);
10566
+ if (line) log10.debug(`[proxy] ${line}`);
11011
10567
  });
11012
10568
  this.process.stderr?.on("data", (chunk) => {
11013
10569
  const line = chunk.toString().trim();
11014
- if (line) log13.warn(`[proxy:err] ${line}`);
10570
+ if (line) log10.warn(`[proxy:err] ${line}`);
11015
10571
  });
11016
10572
  this.process.on("exit", (code, signal) => {
11017
- log13.info(`TON Proxy exited (code=${code}, signal=${signal})`);
10573
+ log10.info(`TON Proxy exited (code=${code}, signal=${signal})`);
11018
10574
  this.process = null;
11019
10575
  this.removePidFile();
11020
10576
  if (code !== 0 && code !== null && this.restartCount < this.maxRestarts) {
11021
10577
  this.restartCount++;
11022
- log13.warn(`Auto-restarting TON Proxy (attempt ${this.restartCount}/${this.maxRestarts})`);
11023
- this.start().catch((err) => log13.error({ err }, "Failed to auto-restart TON Proxy"));
10578
+ log10.warn(`Auto-restarting TON Proxy (attempt ${this.restartCount}/${this.maxRestarts})`);
10579
+ this.start().catch((err) => log10.error({ err }, "Failed to auto-restart TON Proxy"));
11024
10580
  }
11025
10581
  });
11026
10582
  this.process.on("error", (err) => {
11027
- log13.error({ err }, "TON Proxy process error");
10583
+ log10.error({ err }, "TON Proxy process error");
11028
10584
  this.process = null;
11029
10585
  });
11030
10586
  this.startHealthCheck();
@@ -11042,14 +10598,14 @@ var TonProxyManager = class {
11042
10598
  });
11043
10599
  });
11044
10600
  if (this.process?.pid) this.writePidFile(this.process.pid);
11045
- log13.info(`TON Proxy running on 127.0.0.1:${port} (PID ${this.process?.pid})`);
10601
+ log10.info(`TON Proxy running on 127.0.0.1:${port} (PID ${this.process?.pid})`);
11046
10602
  }
11047
10603
  /** Stop the proxy process gracefully */
11048
10604
  async stop() {
11049
10605
  this.stopHealthCheck();
11050
10606
  if (!this.process) return;
11051
10607
  this.maxRestarts = 0;
11052
- log13.info("Stopping TON Proxy...");
10608
+ log10.info("Stopping TON Proxy...");
11053
10609
  return new Promise((resolve2) => {
11054
10610
  if (!this.process) {
11055
10611
  resolve2();
@@ -11057,7 +10613,7 @@ var TonProxyManager = class {
11057
10613
  }
11058
10614
  const forceKill = setTimeout(() => {
11059
10615
  if (this.process) {
11060
- log13.warn("TON Proxy did not exit gracefully, sending SIGKILL");
10616
+ log10.warn("TON Proxy did not exit gracefully, sending SIGKILL");
11061
10617
  this.process.kill("SIGKILL");
11062
10618
  }
11063
10619
  }, KILL_GRACE_MS);
@@ -11076,10 +10632,10 @@ var TonProxyManager = class {
11076
10632
  await this.stop();
11077
10633
  }
11078
10634
  const binaryPath = this.getBinaryPath();
11079
- if (existsSync8(binaryPath)) {
10635
+ if (existsSync7(binaryPath)) {
11080
10636
  const { unlink } = await import("fs/promises");
11081
10637
  await unlink(binaryPath);
11082
- log13.info(`TON Proxy binary removed: ${binaryPath}`);
10638
+ log10.info(`TON Proxy binary removed: ${binaryPath}`);
11083
10639
  }
11084
10640
  }
11085
10641
  /** Get proxy status for WebUI / tools */
@@ -11113,7 +10669,7 @@ var TonProxyManager = class {
11113
10669
  }).catch(() => null);
11114
10670
  clearTimeout(timeout);
11115
10671
  if (!res) {
11116
- log13.warn("TON Proxy health check failed (no response)");
10672
+ log10.warn("TON Proxy health check failed (no response)");
11117
10673
  }
11118
10674
  } catch {
11119
10675
  }
@@ -11170,7 +10726,7 @@ var tonProxyStatusExecutor = async () => {
11170
10726
  };
11171
10727
 
11172
10728
  // src/ton-proxy/module.ts
11173
- var log14 = createLogger("TonProxyModule");
10729
+ var log11 = createLogger("TonProxyModule");
11174
10730
  var manager = null;
11175
10731
  function getTonProxyManager() {
11176
10732
  return manager;
@@ -11197,9 +10753,9 @@ var tonProxyModule = {
11197
10753
  setProxyManager(manager);
11198
10754
  try {
11199
10755
  await manager.start();
11200
- log14.info(`TON Proxy started on port ${proxyConfig.port}`);
10756
+ log11.info(`TON Proxy started on port ${proxyConfig.port}`);
11201
10757
  } catch (err) {
11202
- log14.error({ err }, "Failed to start TON Proxy");
10758
+ log11.error({ err }, "Failed to start TON Proxy");
11203
10759
  manager = null;
11204
10760
  }
11205
10761
  },
@@ -11251,9 +10807,6 @@ function setTriggersConfig(db, triggers) {
11251
10807
  }
11252
10808
 
11253
10809
  export {
11254
- loadConfig,
11255
- configExists,
11256
- getDefaultConfigPath,
11257
10810
  WorkspaceSecurityError,
11258
10811
  validatePath,
11259
10812
  validateReadPath,