teleton 0.8.2 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +230 -294
  2. package/dist/bootstrap-NNEI3Z5H.js +126 -0
  3. package/dist/{chunk-HEDJCLA6.js → chunk-35MX4ZUI.js} +2 -122
  4. package/dist/{chunk-57URFK6M.js → chunk-5LOHRZYY.js} +64 -15
  5. package/dist/{chunk-YOSUPUAJ.js → chunk-6OOHHJ4N.js} +1 -174
  6. package/dist/{chunk-W25Z7CM6.js → chunk-ALKAAG4O.js} +3 -3
  7. package/dist/chunk-CUE4UZXR.js +129 -0
  8. package/dist/{chunk-XBSCYMKM.js → chunk-G7PCW63M.js} +14 -14
  9. package/dist/{chunk-VYKW7FMV.js → chunk-GHMXWAXI.js} +1 -1
  10. package/dist/chunk-JROBTXWY.js +908 -0
  11. package/dist/{chunk-J73TA3UM.js → chunk-LVTKJQ7O.js} +7 -5
  12. package/dist/{chunk-GGXJLMOH.js → chunk-LZQOX6YY.js} +283 -1061
  13. package/dist/{chunk-7YKSXOQQ.js → chunk-NH2CNRKJ.js} +131 -241
  14. package/dist/chunk-NVKBBTI6.js +128 -0
  15. package/dist/{chunk-2IZU3REP.js → chunk-UMUONAD6.js} +143 -220
  16. package/dist/chunk-WTDAICGT.js +175 -0
  17. package/dist/{chunk-55SKE6YH.js → chunk-XDZDOKIF.js} +1 -1
  18. package/dist/cli/index.js +41 -24
  19. package/dist/{client-YOOHI776.js → client-5KD25NOP.js} +4 -3
  20. package/dist/index.js +14 -10
  21. package/dist/local-IHKJFQJS.js +9 -0
  22. package/dist/{memory-Q6EWGK2S.js → memory-QMJRM3XJ.js} +5 -3
  23. package/dist/{memory-hook-WUXJNVT5.js → memory-hook-VUNWZ3NY.js} +5 -4
  24. package/dist/{migrate-WFU6COBN.js → migrate-5VBAP52B.js} +3 -2
  25. package/dist/{server-YODFBZKG.js → server-AJCOURH7.js} +13 -10
  26. package/dist/{server-GYZXKIKU.js → server-WWGVDFPW.js} +38 -13
  27. package/dist/{setup-server-IZBUOJRU.js → setup-server-VDY64CWW.js} +5 -3
  28. package/dist/{store-7M4XV6M5.js → store-BY7S6IFN.js} +4 -3
  29. package/dist/{tool-index-NYH57UWP.js → tool-index-FTERJSZK.js} +2 -1
  30. package/package.json +1 -1
@@ -1,5 +1,4 @@
1
1
  import {
2
- ConfigSchema,
3
2
  getCachedTonClient,
4
3
  getKeyPair,
5
4
  getTonPrice,
@@ -7,7 +6,7 @@ import {
7
6
  getWalletBalance,
8
7
  invalidateTonClientCache,
9
8
  loadWallet
10
- } from "./chunk-7YKSXOQQ.js";
9
+ } from "./chunk-JROBTXWY.js";
11
10
  import {
12
11
  getOrCreateSession,
13
12
  getSession,
@@ -15,11 +14,18 @@ import {
15
14
  resetSessionWithPolicy,
16
15
  shouldResetSession,
17
16
  updateSession
18
- } from "./chunk-55SKE6YH.js";
17
+ } from "./chunk-XDZDOKIF.js";
18
+ import {
19
+ ContextBuilder,
20
+ createDbWrapper,
21
+ getDatabase,
22
+ migrateFromMainDb,
23
+ openModuleDb
24
+ } from "./chunk-GHMXWAXI.js";
19
25
  import {
20
26
  saveSessionMemory,
21
27
  summarizeWithFallback
22
- } from "./chunk-W25Z7CM6.js";
28
+ } from "./chunk-ALKAAG4O.js";
23
29
  import {
24
30
  getErrorMessage,
25
31
  isHttpError
@@ -34,28 +40,6 @@ import {
34
40
  ut,
35
41
  ye
36
42
  } from "./chunk-7TECSLJ4.js";
37
- import {
38
- chatWithContext,
39
- getEffectiveApiKey,
40
- getProviderModel,
41
- loadContextFromTranscript
42
- } from "./chunk-J73TA3UM.js";
43
- import {
44
- getProviderMetadata,
45
- getSupportedProviders
46
- } from "./chunk-YOSUPUAJ.js";
47
- import {
48
- appendToTranscript,
49
- archiveTranscript,
50
- transcriptExists
51
- } from "./chunk-LC4TV3KL.js";
52
- import {
53
- ContextBuilder,
54
- createDbWrapper,
55
- getDatabase,
56
- migrateFromMainDb,
57
- openModuleDb
58
- } from "./chunk-VYKW7FMV.js";
59
43
  import {
60
44
  GECKOTERMINAL_API_URL,
61
45
  tonapiFetch
@@ -84,6 +68,15 @@ import {
84
68
  SERVER_ERROR_MAX_RETRIES,
85
69
  TOOL_CONCURRENCY_LIMIT
86
70
  } from "./chunk-C4NKJT2Z.js";
71
+ import {
72
+ chatWithContext,
73
+ getEffectiveApiKey,
74
+ getProviderModel,
75
+ loadContextFromTranscript
76
+ } from "./chunk-LVTKJQ7O.js";
77
+ import {
78
+ getProviderMetadata
79
+ } from "./chunk-6OOHHJ4N.js";
87
80
  import {
88
81
  fetchWithTimeout
89
82
  } from "./chunk-XQUHC3JZ.js";
@@ -96,6 +89,11 @@ import {
96
89
  RETRY_DEFAULT_MAX_DELAY_MS,
97
90
  RETRY_DEFAULT_TIMEOUT_MS
98
91
  } from "./chunk-R4YSJ4EY.js";
92
+ import {
93
+ appendToTranscript,
94
+ archiveTranscript,
95
+ transcriptExists
96
+ } from "./chunk-LC4TV3KL.js";
99
97
  import {
100
98
  ALLOWED_EXTENSIONS,
101
99
  TELETON_ROOT,
@@ -106,140 +104,17 @@ import {
106
104
  createLogger
107
105
  } from "./chunk-NQ6FZKCE.js";
108
106
 
109
- // src/config/loader.ts
110
- import { readFileSync, existsSync, writeFileSync, mkdirSync } from "fs";
111
- import { parse, stringify } from "yaml";
112
- import { homedir } from "os";
113
- import { dirname, join } from "path";
114
- var log = createLogger("Config");
115
- var DEFAULT_CONFIG_PATH = join(TELETON_ROOT, "config.yaml");
116
- function expandPath(path) {
117
- if (path.startsWith("~")) {
118
- return join(homedir(), path.slice(1));
119
- }
120
- return path;
121
- }
122
- function loadConfig(configPath = DEFAULT_CONFIG_PATH) {
123
- const fullPath = expandPath(configPath);
124
- if (!existsSync(fullPath)) {
125
- throw new Error(`Config file not found: ${fullPath}
126
- Run 'teleton setup' to create one.`);
127
- }
128
- let content;
129
- try {
130
- content = readFileSync(fullPath, "utf-8");
131
- } catch (error) {
132
- throw new Error(`Cannot read config file ${fullPath}: ${error.message}`);
133
- }
134
- let raw;
135
- try {
136
- raw = parse(content);
137
- } catch (error) {
138
- throw new Error(`Invalid YAML in ${fullPath}: ${error.message}`);
139
- }
140
- if (raw && typeof raw === "object" && "market" in raw) {
141
- log.warn("config.market is deprecated and ignored. Use market-api plugin instead.");
142
- delete raw.market;
143
- }
144
- const result = ConfigSchema.safeParse(raw);
145
- if (!result.success) {
146
- throw new Error(`Invalid config: ${result.error.message}`);
147
- }
148
- const config = result.data;
149
- const provider = config.agent.provider;
150
- if (provider !== "anthropic" && provider !== "claude-code" && !raw.agent?.model) {
151
- const meta = getProviderMetadata(provider);
152
- config.agent.model = meta.defaultModel;
153
- }
154
- config.telegram.session_path = expandPath(config.telegram.session_path);
155
- config.storage.sessions_file = expandPath(config.storage.sessions_file);
156
- config.storage.memory_file = expandPath(config.storage.memory_file);
157
- if (process.env.TELETON_API_KEY) {
158
- config.agent.api_key = process.env.TELETON_API_KEY;
159
- }
160
- if (process.env.TELETON_TG_API_ID) {
161
- const apiId = parseInt(process.env.TELETON_TG_API_ID, 10);
162
- if (isNaN(apiId)) {
163
- throw new Error(
164
- `Invalid TELETON_TG_API_ID environment variable: "${process.env.TELETON_TG_API_ID}" is not a valid integer`
165
- );
166
- }
167
- config.telegram.api_id = apiId;
168
- }
169
- if (process.env.TELETON_TG_API_HASH) {
170
- config.telegram.api_hash = process.env.TELETON_TG_API_HASH;
171
- }
172
- if (process.env.TELETON_TG_PHONE) {
173
- config.telegram.phone = process.env.TELETON_TG_PHONE;
174
- }
175
- if (process.env.TELETON_WEBUI_ENABLED) {
176
- config.webui.enabled = process.env.TELETON_WEBUI_ENABLED === "true";
177
- }
178
- if (process.env.TELETON_WEBUI_PORT) {
179
- const port = parseInt(process.env.TELETON_WEBUI_PORT, 10);
180
- if (!isNaN(port) && port >= 1024 && port <= 65535) {
181
- config.webui.port = port;
182
- }
183
- }
184
- if (process.env.TELETON_WEBUI_HOST) {
185
- config.webui.host = process.env.TELETON_WEBUI_HOST;
186
- if (!["127.0.0.1", "localhost", "::1"].includes(config.webui.host)) {
187
- log.warn(
188
- { host: config.webui.host },
189
- "WebUI bound to non-loopback address \u2014 ensure auth_token is set"
190
- );
191
- }
192
- }
193
- if (process.env.TELETON_API_ENABLED) {
194
- if (!config.api) config.api = { enabled: false, port: 7778, key_hash: "", allowed_ips: [] };
195
- config.api.enabled = process.env.TELETON_API_ENABLED === "true";
196
- }
197
- if (process.env.TELETON_API_PORT) {
198
- const port = parseInt(process.env.TELETON_API_PORT, 10);
199
- if (!isNaN(port) && port >= 1024 && port <= 65535) {
200
- if (!config.api) config.api = { enabled: false, port: 7778, key_hash: "", allowed_ips: [] };
201
- config.api.port = port;
202
- }
203
- }
204
- if (process.env.TELETON_BASE_URL) {
205
- try {
206
- new URL(process.env.TELETON_BASE_URL);
207
- config.agent.base_url = process.env.TELETON_BASE_URL;
208
- } catch {
209
- throw new Error(
210
- `Invalid TELETON_BASE_URL: "${process.env.TELETON_BASE_URL}" is not a valid URL`
211
- );
212
- }
213
- }
214
- if (process.env.TELETON_TAVILY_API_KEY) {
215
- config.tavily_api_key = process.env.TELETON_TAVILY_API_KEY;
216
- }
217
- if (process.env.TELETON_TONAPI_KEY) {
218
- config.tonapi_key = process.env.TELETON_TONAPI_KEY;
219
- }
220
- if (process.env.TELETON_TONCENTER_API_KEY) {
221
- config.toncenter_api_key = process.env.TELETON_TONCENTER_API_KEY;
222
- }
223
- return config;
224
- }
225
- function configExists(configPath = DEFAULT_CONFIG_PATH) {
226
- return existsSync(expandPath(configPath));
227
- }
228
- function getDefaultConfigPath() {
229
- return DEFAULT_CONFIG_PATH;
230
- }
231
-
232
107
  // src/soul/loader.ts
233
- import { readFileSync as readFileSync3, existsSync as existsSync4 } from "fs";
108
+ import { readFileSync as readFileSync2, existsSync as existsSync3 } from "fs";
234
109
 
235
110
  // src/memory/daily-logs.ts
236
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, appendFileSync, readFileSync as readFileSync2 } from "fs";
237
- import { join as join2 } from "path";
111
+ import { existsSync as existsSync2, mkdirSync, appendFileSync, readFileSync } from "fs";
112
+ import { join } from "path";
238
113
 
239
114
  // src/workspace/validator.ts
240
- import { existsSync as existsSync2, lstatSync, readdirSync } from "fs";
115
+ import { existsSync, lstatSync, readdirSync } from "fs";
241
116
  import { resolve, normalize, relative, extname, basename } from "path";
242
- import { homedir as homedir2 } from "os";
117
+ import { homedir } from "os";
243
118
  var WorkspaceSecurityError = class extends Error {
244
119
  constructor(message, attemptedPath) {
245
120
  super(message);
@@ -273,7 +148,7 @@ function validatePath(inputPath, allowCreate = false) {
273
148
  if (decodedPath.startsWith("/")) {
274
149
  absolutePath = resolve(normalize(decodedPath));
275
150
  } else if (decodedPath.startsWith("~/")) {
276
- const expanded = decodedPath.replace(/^~(?=$|[\\/])/, homedir2());
151
+ const expanded = decodedPath.replace(/^~(?=$|[\\/])/, homedir());
277
152
  absolutePath = resolve(expanded);
278
153
  } else {
279
154
  absolutePath = resolve(WORKSPACE_ROOT, normalize(decodedPath));
@@ -285,7 +160,7 @@ function validatePath(inputPath, allowCreate = false) {
285
160
  inputPath
286
161
  );
287
162
  }
288
- const exists = existsSync2(absolutePath);
163
+ const exists = existsSync(absolutePath);
289
164
  if (!exists && !allowCreate) {
290
165
  throw new WorkspaceSecurityError(
291
166
  `File not found: '${inputPath}' does not exist in workspace.`,
@@ -349,7 +224,7 @@ function validateDirectory(inputPath) {
349
224
  }
350
225
 
351
226
  // src/memory/daily-logs.ts
352
- var log2 = createLogger("Memory");
227
+ var log = createLogger("Memory");
353
228
  var MEMORY_DIR = WORKSPACE_PATHS.MEMORY_DIR;
354
229
  function formatDate(date) {
355
230
  const year = date.getFullYear();
@@ -358,11 +233,11 @@ function formatDate(date) {
358
233
  return `${year}-${month}-${day}`;
359
234
  }
360
235
  function getDailyLogPath(date = /* @__PURE__ */ new Date()) {
361
- return join2(MEMORY_DIR, `${formatDate(date)}.md`);
236
+ return join(MEMORY_DIR, `${formatDate(date)}.md`);
362
237
  }
363
238
  function ensureMemoryDir() {
364
- if (!existsSync3(MEMORY_DIR)) {
365
- mkdirSync2(MEMORY_DIR, { recursive: true });
239
+ if (!existsSync2(MEMORY_DIR)) {
240
+ mkdirSync(MEMORY_DIR, { recursive: true });
366
241
  }
367
242
  }
368
243
  function appendToDailyLog(content, date = /* @__PURE__ */ new Date()) {
@@ -370,7 +245,7 @@ function appendToDailyLog(content, date = /* @__PURE__ */ new Date()) {
370
245
  ensureMemoryDir();
371
246
  const logPath = getDailyLogPath(date);
372
247
  const timestamp = date.toLocaleTimeString("en-US", { hour12: false });
373
- if (!existsSync3(logPath)) {
248
+ if (!existsSync2(logPath)) {
374
249
  const header = `# Daily Log - ${formatDate(date)}
375
250
 
376
251
  `;
@@ -384,16 +259,16 @@ ${content}
384
259
 
385
260
  `;
386
261
  appendFileSync(logPath, entry, "utf-8");
387
- log2.info(`Daily log updated: ${logPath}`);
262
+ log.info(`Daily log updated: ${logPath}`);
388
263
  } catch (error) {
389
- log2.error({ err: error }, "Failed to write daily log");
264
+ log.error({ err: error }, "Failed to write daily log");
390
265
  }
391
266
  }
392
267
  function readDailyLog(date = /* @__PURE__ */ new Date()) {
393
268
  try {
394
269
  const logPath = getDailyLogPath(date);
395
- if (!existsSync3(logPath)) return null;
396
- return readFileSync2(logPath, "utf-8");
270
+ if (!existsSync2(logPath)) return null;
271
+ return readFileSync(logPath, "utf-8");
397
272
  } catch {
398
273
  return null;
399
274
  }
@@ -474,7 +349,7 @@ function cachedReadFile(path) {
474
349
  if (cached && now < cached.expiry) return cached.content;
475
350
  let content = null;
476
351
  try {
477
- if (existsSync4(path)) content = readFileSync3(path, "utf-8");
352
+ if (existsSync3(path)) content = readFileSync2(path, "utf-8");
478
353
  } catch {
479
354
  }
480
355
  fileCache.set(path, { content, expiry: now + FILE_CACHE_TTL });
@@ -757,7 +632,7 @@ var DEFAULT_COMPACTION_CONFIG = {
757
632
  memoryFlushEnabled: true,
758
633
  softThresholdTokens: DEFAULT_SOFT_THRESHOLD_TOKENS
759
634
  };
760
- var log3 = createLogger("Memory");
635
+ var log2 = createLogger("Memory");
761
636
  function estimateContextTokens(context) {
762
637
  let charCount = 0;
763
638
  if (context.systemPrompt) {
@@ -789,7 +664,7 @@ function shouldFlushMemory(context, config, tokenCount) {
789
664
  const tokens = tokenCount ?? estimateContextTokens(context);
790
665
  const softThreshold = config.softThresholdTokens ?? FALLBACK_SOFT_THRESHOLD_TOKENS;
791
666
  if (tokens >= softThreshold) {
792
- log3.info(`Memory flush needed: ~${tokens} tokens (soft threshold: ${softThreshold})`);
667
+ log2.info(`Memory flush needed: ~${tokens} tokens (soft threshold: ${softThreshold})`);
793
668
  return true;
794
669
  }
795
670
  return false;
@@ -811,7 +686,7 @@ function flushMemoryToDailyLog(context) {
811
686
  }
812
687
  }
813
688
  writeSummaryToDailyLog(summary.join("\n"));
814
- log3.info(`Memory flushed to daily log`);
689
+ log2.info(`Memory flushed to daily log`);
815
690
  }
816
691
  function shouldCompact(context, config, tokenCount) {
817
692
  if (!config.enabled) {
@@ -819,13 +694,13 @@ function shouldCompact(context, config, tokenCount) {
819
694
  }
820
695
  const messageCount = context.messages.length;
821
696
  if (config.maxMessages && messageCount >= config.maxMessages) {
822
- log3.info(`Compaction needed: ${messageCount} messages (max: ${config.maxMessages})`);
697
+ log2.info(`Compaction needed: ${messageCount} messages (max: ${config.maxMessages})`);
823
698
  return true;
824
699
  }
825
700
  if (config.maxTokens) {
826
701
  const tokens = tokenCount ?? estimateContextTokens(context);
827
702
  if (tokens >= config.maxTokens) {
828
- log3.info(`Compaction needed: ~${tokens} tokens (max: ${config.maxTokens})`);
703
+ log2.info(`Compaction needed: ~${tokens} tokens (max: ${config.maxTokens})`);
829
704
  return true;
830
705
  }
831
706
  }
@@ -871,12 +746,12 @@ async function compactContext(context, config, apiKey, provider, utilityModel) {
871
746
  iterations++;
872
747
  }
873
748
  if (hasOrphanedToolResults(context.messages.slice(cutIndex))) {
874
- log3.warn(`Compaction: couldn't find clean cut point, keeping all messages`);
749
+ log2.warn(`Compaction: couldn't find clean cut point, keeping all messages`);
875
750
  return context;
876
751
  }
877
752
  const recentMessages = context.messages.slice(cutIndex);
878
753
  const oldMessages = context.messages.slice(0, cutIndex);
879
- log3.info(
754
+ log2.info(
880
755
  `Compacting ${oldMessages.length} old messages, keeping ${recentMessages.length} recent (cut at clean boundary)`
881
756
  );
882
757
  try {
@@ -906,7 +781,7 @@ Keep each section concise. Omit a section if empty. Preserve specific names, num
906
781
  provider,
907
782
  utilityModel
908
783
  });
909
- log3.info(`AI Summary: ${result.tokensUsed} tokens, ${result.chunksProcessed} chunks processed`);
784
+ log2.info(`AI Summary: ${result.tokensUsed} tokens, ${result.chunksProcessed} chunks processed`);
910
785
  const summaryText = `[Auto-compacted ${oldMessages.length} messages]
911
786
 
912
787
  ${result.summary}`;
@@ -920,7 +795,7 @@ ${result.summary}`;
920
795
  messages: [summaryMessage, ...recentMessages]
921
796
  };
922
797
  } catch (error) {
923
- log3.error({ err: error }, "AI summarization failed, using fallback");
798
+ log2.error({ err: error }, "AI summarization failed, using fallback");
924
799
  const summaryText = `[Auto-compacted: ${oldMessages.length} earlier messages from this conversation]`;
925
800
  const summaryMessage = {
926
801
  role: "user",
@@ -935,7 +810,7 @@ ${result.summary}`;
935
810
  }
936
811
  async function compactAndSaveTranscript(sessionId, context, config, apiKey, chatId, provider, utilityModel) {
937
812
  const newSessionId = randomUUID();
938
- log3.info(`Creating compacted transcript: ${sessionId} \u2192 ${newSessionId}`);
813
+ log2.info(`Creating compacted transcript: ${sessionId} \u2192 ${newSessionId}`);
939
814
  if (chatId) {
940
815
  await saveSessionMemory({
941
816
  oldSessionId: sessionId,
@@ -969,7 +844,7 @@ var CompactionManager = class {
969
844
  if (this.config.memoryFlushEnabled) {
970
845
  flushMemoryToDailyLog(context);
971
846
  }
972
- log3.info(`Auto-compacting session ${sessionId}`);
847
+ log2.info(`Auto-compacting session ${sessionId}`);
973
848
  const newSessionId = await compactAndSaveTranscript(
974
849
  sessionId,
975
850
  context,
@@ -979,7 +854,7 @@ var CompactionManager = class {
979
854
  provider,
980
855
  utilityModel
981
856
  );
982
- log3.info(`Compaction complete: ${newSessionId}`);
857
+ log2.info(`Compaction complete: ${newSessionId}`);
983
858
  return newSessionId;
984
859
  }
985
860
  updateConfig(config) {
@@ -1111,7 +986,7 @@ function maskOldToolResults(messages, options) {
1111
986
  }
1112
987
 
1113
988
  // src/agent/runtime.ts
1114
- var log4 = createLogger("Agent");
989
+ var log3 = createLogger("Agent");
1115
990
  var globalTokenUsage = { totalTokens: 0, totalCost: 0 };
1116
991
  function getTokenUsage() {
1117
992
  return { ...globalTokenUsage };
@@ -1224,7 +1099,7 @@ var AgentRuntime = class {
1224
1099
  if (this.userHookEvaluator) {
1225
1100
  const hookResult = this.userHookEvaluator.evaluate(userMessage);
1226
1101
  if (hookResult.blocked) {
1227
- log4.info("Message blocked by keyword filter");
1102
+ log3.info("Message blocked by keyword filter");
1228
1103
  return { content: hookResult.blockMessage ?? "", toolCalls: [] };
1229
1104
  }
1230
1105
  if (hookResult.additionalContext) {
@@ -1250,7 +1125,7 @@ var AgentRuntime = class {
1250
1125
  };
1251
1126
  await this.hookRunner.runModifyingHook("message:receive", msgEvent);
1252
1127
  if (msgEvent.block) {
1253
- log4.info(`\u{1F6AB} Message blocked by hook: ${msgEvent.blockReason || "no reason"}`);
1128
+ log3.info(`\u{1F6AB} Message blocked by hook: ${msgEvent.blockReason || "no reason"}`);
1254
1129
  return { content: "", toolCalls: [] };
1255
1130
  }
1256
1131
  effectiveMessage = sanitizeForContext(msgEvent.text);
@@ -1262,7 +1137,7 @@ var AgentRuntime = class {
1262
1137
  const now = timestamp ?? Date.now();
1263
1138
  const resetPolicy = this.config.agent.session_reset_policy;
1264
1139
  if (shouldResetSession(session, resetPolicy)) {
1265
- log4.info(`\u{1F504} Auto-resetting session based on policy`);
1140
+ log3.info(`\u{1F504} Auto-resetting session based on policy`);
1266
1141
  if (this.hookRunner) {
1267
1142
  await this.hookRunner.runObservingHook("session:end", {
1268
1143
  sessionId: session.sessionId,
@@ -1272,7 +1147,7 @@ var AgentRuntime = class {
1272
1147
  }
1273
1148
  if (transcriptExists(session.sessionId)) {
1274
1149
  try {
1275
- log4.info(`\u{1F4BE} Saving memory before daily reset...`);
1150
+ log3.info(`\u{1F4BE} Saving memory before daily reset...`);
1276
1151
  const oldContext = loadContextFromTranscript(session.sessionId);
1277
1152
  await saveSessionMemory({
1278
1153
  oldSessionId: session.sessionId,
@@ -1283,9 +1158,9 @@ var AgentRuntime = class {
1283
1158
  provider: this.config.agent.provider,
1284
1159
  utilityModel: this.config.agent.utility_model
1285
1160
  });
1286
- log4.info(`\u2705 Memory saved before reset`);
1161
+ log3.info(`\u2705 Memory saved before reset`);
1287
1162
  } catch (error) {
1288
- log4.warn({ err: error }, `\u26A0\uFE0F Failed to save memory before reset`);
1163
+ log3.warn({ err: error }, `\u26A0\uFE0F Failed to save memory before reset`);
1289
1164
  }
1290
1165
  }
1291
1166
  session = resetSessionWithPolicy(chatId, resetPolicy);
@@ -1293,9 +1168,9 @@ var AgentRuntime = class {
1293
1168
  let context = loadContextFromTranscript(session.sessionId);
1294
1169
  const isNewSession = context.messages.length === 0;
1295
1170
  if (!isNewSession) {
1296
- log4.info(`\u{1F4D6} Loading existing session: ${session.sessionId}`);
1171
+ log3.info(`\u{1F4D6} Loading existing session: ${session.sessionId}`);
1297
1172
  } else {
1298
- log4.info(`\u{1F195} Starting new session: ${session.sessionId}`);
1173
+ log3.info(`\u{1F195} Starting new session: ${session.sessionId}`);
1299
1174
  }
1300
1175
  if (this.hookRunner) {
1301
1176
  await this.hookRunner.runObservingHook("session:start", {
@@ -1324,13 +1199,13 @@ var AgentRuntime = class {
1324
1199
  formattedMessage = `${pendingContext}
1325
1200
 
1326
1201
  ${formattedMessage}`;
1327
- log4.debug(`\u{1F4CB} Including ${pendingContext.split("\n").length - 1} pending messages`);
1202
+ log3.debug(`\u{1F4CB} Including ${pendingContext.split("\n").length - 1} pending messages`);
1328
1203
  }
1329
- log4.debug(`\u{1F4E8} Formatted message: ${formattedMessage.substring(0, 100)}...`);
1204
+ log3.debug(`\u{1F4E8} Formatted message: ${formattedMessage.substring(0, 100)}...`);
1330
1205
  const preview = formattedMessage.slice(0, 50).replace(/\n/g, " ");
1331
1206
  const who = senderUsername ? `@${senderUsername}` : userName;
1332
1207
  const msgType = isGroup ? `Group ${chatId} ${who}` : `DM ${who}`;
1333
- log4.info(`\u{1F4E8} ${msgType}: "${preview}${formattedMessage.length > 50 ? "..." : ""}"`);
1208
+ log3.info(`\u{1F4E8} ${msgType}: "${preview}${formattedMessage.length > 50 ? "..." : ""}"`);
1334
1209
  let relevantContext = "";
1335
1210
  let queryEmbedding;
1336
1211
  const isNonTrivial = !isTrivialMessage(effectiveMessage);
@@ -1349,7 +1224,7 @@ ${formattedMessage}`;
1349
1224
  searchQuery.slice(0, EMBEDDING_QUERY_MAX_CHARS)
1350
1225
  );
1351
1226
  } catch (error) {
1352
- log4.warn({ err: error }, "Embedding computation failed");
1227
+ log3.warn({ err: error }, "Embedding computation failed");
1353
1228
  }
1354
1229
  }
1355
1230
  if (this.contextBuilder && isNonTrivial) {
@@ -1383,12 +1258,12 @@ ${sanitizedFeed.join("\n")}`
1383
1258
  }
1384
1259
  if (contextParts.length > 0) {
1385
1260
  relevantContext = contextParts.join("\n\n");
1386
- log4.debug(
1261
+ log3.debug(
1387
1262
  `\u{1F50D} Found ${dbContext.relevantKnowledge.length} knowledge chunks, ${dbContext.relevantFeed.length} feed messages`
1388
1263
  );
1389
1264
  }
1390
1265
  } catch (error) {
1391
- log4.warn({ err: error }, "Context building failed");
1266
+ log3.warn({ err: error }, "Context building failed");
1392
1267
  }
1393
1268
  }
1394
1269
  const memoryStats = this.getMemoryStats();
@@ -1456,7 +1331,7 @@ ${allHookContext}` : "");
1456
1331
  this.config.agent.utility_model
1457
1332
  );
1458
1333
  if (preemptiveCompaction) {
1459
- log4.info(`\u{1F5DC}\uFE0F Preemptive compaction triggered, reloading session...`);
1334
+ log3.info(`\u{1F5DC}\uFE0F Preemptive compaction triggered, reloading session...`);
1460
1335
  session = getSession(chatId);
1461
1336
  context = loadContextFromTranscript(session.sessionId);
1462
1337
  context.messages.push(userMsg);
@@ -1478,7 +1353,7 @@ ${allHookContext}` : "");
1478
1353
  chatId,
1479
1354
  isAdmin
1480
1355
  );
1481
- log4.info(`\u{1F50D} Tool RAG: ${tools.length}/${this.toolRegistry.count} tools selected`);
1356
+ log3.info(`\u{1F50D} Tool RAG: ${tools.length}/${this.toolRegistry.count} tools selected`);
1482
1357
  } else {
1483
1358
  tools = this.toolRegistry?.getForContext(
1484
1359
  effectiveIsGroup,
@@ -1500,7 +1375,7 @@ ${allHookContext}` : "");
1500
1375
  const seenToolSignatures = /* @__PURE__ */ new Set();
1501
1376
  while (iteration < maxIterations) {
1502
1377
  iteration++;
1503
- log4.debug(`\u{1F504} Agentic iteration ${iteration}/${maxIterations}`);
1378
+ log3.debug(`\u{1F504} Agentic iteration ${iteration}/${maxIterations}`);
1504
1379
  const iterationStartIndex = context.messages.length;
1505
1380
  const maskedMessages = maskOldToolResults(context.messages, {
1506
1381
  toolRegistry: this.toolRegistry ?? void 0,
@@ -1539,35 +1414,35 @@ ${allHookContext}` : "");
1539
1414
  "Context overflow persists after session reset. Message may be too large for the model's context window."
1540
1415
  );
1541
1416
  }
1542
- log4.error(`\u{1F6A8} Context overflow detected: ${errorMsg}`);
1543
- log4.info(`\u{1F4BE} Saving session memory before reset...`);
1417
+ log3.error(`\u{1F6A8} Context overflow detected: ${errorMsg}`);
1418
+ log3.info(`\u{1F4BE} Saving session memory before reset...`);
1544
1419
  const summary = extractContextSummary(context, CONTEXT_OVERFLOW_SUMMARY_MESSAGES);
1545
1420
  appendToDailyLog(summary);
1546
- log4.info(`\u2705 Memory saved to daily log`);
1421
+ log3.info(`\u2705 Memory saved to daily log`);
1547
1422
  const archived = archiveTranscript(session.sessionId);
1548
1423
  if (!archived) {
1549
- log4.error(
1424
+ log3.error(
1550
1425
  `\u26A0\uFE0F Failed to archive transcript ${session.sessionId}, proceeding with reset anyway`
1551
1426
  );
1552
1427
  }
1553
- log4.info(`\u{1F504} Resetting session due to context overflow...`);
1428
+ log3.info(`\u{1F504} Resetting session due to context overflow...`);
1554
1429
  session = resetSession(chatId);
1555
1430
  context = { messages: [userMsg] };
1556
1431
  appendToTranscript(session.sessionId, userMsg);
1557
- log4.info(`\u{1F504} Retrying with fresh context...`);
1432
+ log3.info(`\u{1F504} Retrying with fresh context...`);
1558
1433
  continue;
1559
1434
  } else if (errorMsg.toLowerCase().includes("rate") || errorMsg.includes("429")) {
1560
1435
  rateLimitRetries++;
1561
1436
  if (rateLimitRetries <= RATE_LIMIT_MAX_RETRIES) {
1562
1437
  const delay = 1e3 * Math.pow(2, rateLimitRetries - 1);
1563
- log4.warn(
1438
+ log3.warn(
1564
1439
  `\u{1F6AB} Rate limited, retrying in ${delay}ms (attempt ${rateLimitRetries}/${RATE_LIMIT_MAX_RETRIES})...`
1565
1440
  );
1566
1441
  await new Promise((r3) => setTimeout(r3, delay));
1567
1442
  iteration--;
1568
1443
  continue;
1569
1444
  }
1570
- log4.error(`\u{1F6AB} Rate limited after ${RATE_LIMIT_MAX_RETRIES} retries: ${errorMsg}`);
1445
+ log3.error(`\u{1F6AB} Rate limited after ${RATE_LIMIT_MAX_RETRIES} retries: ${errorMsg}`);
1571
1446
  throw new Error(
1572
1447
  `API rate limited after ${RATE_LIMIT_MAX_RETRIES} retries. Please try again later.`
1573
1448
  );
@@ -1575,19 +1450,19 @@ ${allHookContext}` : "");
1575
1450
  serverErrorRetries++;
1576
1451
  if (serverErrorRetries <= SERVER_ERROR_MAX_RETRIES) {
1577
1452
  const delay = 2e3 * Math.pow(2, serverErrorRetries - 1);
1578
- log4.warn(
1453
+ log3.warn(
1579
1454
  `\u{1F504} Server error, retrying in ${delay}ms (attempt ${serverErrorRetries}/${SERVER_ERROR_MAX_RETRIES})...`
1580
1455
  );
1581
1456
  await new Promise((r3) => setTimeout(r3, delay));
1582
1457
  iteration--;
1583
1458
  continue;
1584
1459
  }
1585
- log4.error(`\u{1F6A8} Server error after ${SERVER_ERROR_MAX_RETRIES} retries: ${errorMsg}`);
1460
+ log3.error(`\u{1F6A8} Server error after ${SERVER_ERROR_MAX_RETRIES} retries: ${errorMsg}`);
1586
1461
  throw new Error(
1587
1462
  `API server error after ${SERVER_ERROR_MAX_RETRIES} retries. The provider may be experiencing issues.`
1588
1463
  );
1589
1464
  } else {
1590
- log4.error(`\u{1F6A8} API error: ${errorMsg}`);
1465
+ log3.error(`\u{1F6A8} API error: ${errorMsg}`);
1591
1466
  throw new Error(`API error: ${errorMsg || "Unknown error"}`);
1592
1467
  }
1593
1468
  }
@@ -1604,15 +1479,15 @@ ${allHookContext}` : "");
1604
1479
  }
1605
1480
  const toolCalls = response2.message.content.filter((block) => block.type === "toolCall");
1606
1481
  if (toolCalls.length === 0) {
1607
- log4.info(`\u{1F504} ${iteration}/${maxIterations} \u2192 done`);
1482
+ log3.info(`\u{1F504} ${iteration}/${maxIterations} \u2192 done`);
1608
1483
  finalResponse = response2;
1609
1484
  break;
1610
1485
  }
1611
1486
  if (!this.toolRegistry || !toolContext) {
1612
- log4.error("\u26A0\uFE0F Cannot execute tools: registry or context missing");
1487
+ log3.error("\u26A0\uFE0F Cannot execute tools: registry or context missing");
1613
1488
  break;
1614
1489
  }
1615
- log4.debug(`\u{1F527} Executing ${toolCalls.length} tool call(s)`);
1490
+ log3.debug(`\u{1F527} Executing ${toolCalls.length} tool call(s)`);
1616
1491
  context.messages.push(response2.message);
1617
1492
  const iterationToolNames = [];
1618
1493
  const fullContext = {
@@ -1712,7 +1587,7 @@ ${allHookContext}` : "");
1712
1587
  };
1713
1588
  await this.hookRunner.runObservingHook("tool:after", afterEvent);
1714
1589
  }
1715
- log4.debug(`${block.name}: ${exec.result.success ? "\u2713" : "\u2717"} ${exec.result.error || ""}`);
1590
+ log3.debug(`${block.name}: ${exec.result.success ? "\u2713" : "\u2717"} ${exec.result.error || ""}`);
1716
1591
  iterationToolNames.push(`${block.name} ${exec.result.success ? "\u2713" : "\u2717"}`);
1717
1592
  totalToolCalls.push({
1718
1593
  name: block.name,
@@ -1720,7 +1595,7 @@ ${allHookContext}` : "");
1720
1595
  });
1721
1596
  let resultText = JSON.stringify(exec.result);
1722
1597
  if (resultText.length > MAX_TOOL_RESULT_SIZE) {
1723
- log4.warn(`\u26A0\uFE0F Tool result too large (${resultText.length} chars), truncating...`);
1598
+ log3.warn(`\u26A0\uFE0F Tool result too large (${resultText.length} chars), truncating...`);
1724
1599
  const data = exec.result.data;
1725
1600
  if (data?.summary || data?.message) {
1726
1601
  resultText = JSON.stringify({
@@ -1784,26 +1659,26 @@ ${allHookContext}` : "");
1784
1659
  appendToTranscript(session.sessionId, toolResultMsg);
1785
1660
  }
1786
1661
  }
1787
- log4.info(`\u{1F504} ${iteration}/${maxIterations} \u2192 ${iterationToolNames.join(", ")}`);
1662
+ log3.info(`\u{1F504} ${iteration}/${maxIterations} \u2192 ${iterationToolNames.join(", ")}`);
1788
1663
  const iterSignatures = toolPlans.map(
1789
1664
  (p2) => `${p2.block.name}:${JSON.stringify(p2.params, Object.keys(p2.params).sort())}`
1790
1665
  );
1791
1666
  const allDuplicates = iterSignatures.length > 0 && iterSignatures.every((sig) => seenToolSignatures.has(sig));
1792
1667
  for (const sig of iterSignatures) seenToolSignatures.add(sig);
1793
1668
  if (allDuplicates) {
1794
- log4.warn(
1669
+ log3.warn(
1795
1670
  `\u{1F501} Loop stall detected: all ${iterSignatures.length} tool call(s) are repeats \u2014 breaking early`
1796
1671
  );
1797
1672
  finalResponse = response2;
1798
1673
  break;
1799
1674
  }
1800
1675
  if (iteration === maxIterations) {
1801
- log4.info(`\u26A0\uFE0F Max iterations reached (${maxIterations})`);
1676
+ log3.info(`\u26A0\uFE0F Max iterations reached (${maxIterations})`);
1802
1677
  finalResponse = response2;
1803
1678
  }
1804
1679
  }
1805
1680
  if (!finalResponse) {
1806
- log4.error("\u26A0\uFE0F Agentic loop exited early without final response");
1681
+ log3.error("\u26A0\uFE0F Agentic loop exited early without final response");
1807
1682
  return {
1808
1683
  content: "Internal error: Agent loop failed to produce a response.",
1809
1684
  toolCalls: []
@@ -1831,20 +1706,20 @@ ${allHookContext}` : "");
1831
1706
  if (u.cacheRead) cacheParts.push(`${(u.cacheRead / 1e3).toFixed(1)}K cached`);
1832
1707
  if (u.cacheWrite) cacheParts.push(`${(u.cacheWrite / 1e3).toFixed(1)}K new`);
1833
1708
  const cacheInfo = cacheParts.length > 0 ? ` (${cacheParts.join(", ")})` : "";
1834
- log4.info(`\u{1F4B0} ${inK}K in${cacheInfo}, ${u.output} out | $${u.totalCost.toFixed(3)}`);
1709
+ log3.info(`\u{1F4B0} ${inK}K in${cacheInfo}, ${u.output} out | $${u.totalCost.toFixed(3)}`);
1835
1710
  globalTokenUsage.totalTokens += u.input + u.output + u.cacheRead + u.cacheWrite;
1836
1711
  globalTokenUsage.totalCost += u.totalCost;
1837
1712
  }
1838
1713
  let content = accumulatedTexts.join("\n").trim() || response.text;
1839
1714
  const usedTelegramSendTool = totalToolCalls.some((tc) => TELEGRAM_SEND_TOOLS.has(tc.name));
1840
1715
  if (!content && totalToolCalls.length > 0 && !usedTelegramSendTool) {
1841
- log4.warn("\u26A0\uFE0F Empty response after tool calls - generating fallback");
1716
+ log3.warn("\u26A0\uFE0F Empty response after tool calls - generating fallback");
1842
1717
  content = "I executed the requested action but couldn't generate a response. Please try again.";
1843
1718
  } else if (!content && usedTelegramSendTool) {
1844
- log4.info("\u2705 Response sent via Telegram tool - no additional text needed");
1719
+ log3.info("\u2705 Response sent via Telegram tool - no additional text needed");
1845
1720
  content = "";
1846
1721
  } else if (!content && accumulatedUsage.input === 0 && accumulatedUsage.output === 0) {
1847
- log4.warn("\u26A0\uFE0F Empty response with zero tokens - possible API issue");
1722
+ log3.warn("\u26A0\uFE0F Empty response with zero tokens - possible API issue");
1848
1723
  content = "I couldn't process your request. Please try again.";
1849
1724
  }
1850
1725
  let responseMetadata = {};
@@ -1861,7 +1736,7 @@ ${allHookContext}` : "");
1861
1736
  };
1862
1737
  await this.hookRunner.runModifyingHook("response:before", responseBeforeEvent);
1863
1738
  if (responseBeforeEvent.block) {
1864
- log4.info(
1739
+ log3.info(
1865
1740
  `\u{1F6AB} Response blocked by hook: ${responseBeforeEvent.blockReason || "no reason"}`
1866
1741
  );
1867
1742
  content = "";
@@ -1888,7 +1763,7 @@ ${allHookContext}` : "");
1888
1763
  toolCalls: totalToolCalls
1889
1764
  };
1890
1765
  } catch (error) {
1891
- log4.error({ err: error }, "Agent error");
1766
+ log3.error({ err: error }, "Agent error");
1892
1767
  throw error;
1893
1768
  }
1894
1769
  }
@@ -1901,7 +1776,7 @@ ${allHookContext}` : "");
1901
1776
  ).run(chatId);
1902
1777
  db.prepare(`DELETE FROM tg_messages WHERE chat_id = ?`).run(chatId);
1903
1778
  resetSession(chatId);
1904
- log4.info(`\u{1F5D1}\uFE0F Cleared history for chat ${chatId}`);
1779
+ log3.info(`\u{1F5D1}\uFE0F Cleared history for chat ${chatId}`);
1905
1780
  }
1906
1781
  getConfig() {
1907
1782
  return this.config;
@@ -1922,7 +1797,7 @@ ${allHookContext}` : "");
1922
1797
  }
1923
1798
  configureCompaction(config) {
1924
1799
  this.compactionManager.updateConfig(config);
1925
- log4.info({ config: this.compactionManager.getConfig() }, `\u{1F5DC}\uFE0F Compaction config updated`);
1800
+ log3.info({ config: this.compactionManager.getConfig() }, `\u{1F5DC}\uFE0F Compaction config updated`);
1926
1801
  }
1927
1802
  getCompactionConfig() {
1928
1803
  return this.compactionManager.getConfig();
@@ -2132,7 +2007,7 @@ function unescapeHtml(text) {
2132
2007
  }
2133
2008
 
2134
2009
  // src/bot/inline-router.ts
2135
- var log5 = createLogger("InlineRouter");
2010
+ var log4 = createLogger("InlineRouter");
2136
2011
  var INLINE_TIMEOUT_MS = 5e3;
2137
2012
  var CALLBACK_TIMEOUT_MS = 15e3;
2138
2013
  function compileGlob(pattern) {
@@ -2153,11 +2028,11 @@ var InlineRouter = class {
2153
2028
  }
2154
2029
  registerPlugin(name, handlers) {
2155
2030
  this.plugins.set(name, handlers);
2156
- log5.info(`Registered plugin "${name}" for inline routing`);
2031
+ log4.info(`Registered plugin "${name}" for inline routing`);
2157
2032
  }
2158
2033
  unregisterPlugin(name) {
2159
2034
  this.plugins.delete(name);
2160
- log5.info(`Unregistered plugin "${name}" from inline routing`);
2035
+ log4.info(`Unregistered plugin "${name}" from inline routing`);
2161
2036
  }
2162
2037
  hasPlugin(name) {
2163
2038
  return this.plugins.has(name);
@@ -2229,7 +2104,7 @@ var InlineRouter = class {
2229
2104
  is_personal: true
2230
2105
  });
2231
2106
  } catch (error) {
2232
- log5.error({ err: error }, `Plugin "${pluginName}" inline query handler failed`);
2107
+ log4.error({ err: error }, `Plugin "${pluginName}" inline query handler failed`);
2233
2108
  try {
2234
2109
  await ctx.answerInlineQuery([], { cache_time: 0, is_personal: true });
2235
2110
  } catch {
@@ -2289,7 +2164,7 @@ var InlineRouter = class {
2289
2164
  } catch (error) {
2290
2165
  const errMsg = error?.errorMessage;
2291
2166
  if (errMsg === "MESSAGE_NOT_MODIFIED") return;
2292
- log5.debug(`GramJS edit failed, falling back to Grammy: ${errMsg || error}`);
2167
+ log4.debug(`GramJS edit failed, falling back to Grammy: ${errMsg || error}`);
2293
2168
  }
2294
2169
  }
2295
2170
  const replyMarkup = styledButtons ? toGrammyKeyboard(styledButtons) : void 0;
@@ -2309,7 +2184,7 @@ var InlineRouter = class {
2309
2184
  await ctx.answerCallbackQuery();
2310
2185
  }
2311
2186
  } catch (error) {
2312
- log5.error({ err: error }, `Plugin "${pluginName}" callback handler failed`);
2187
+ log4.error({ err: error }, `Plugin "${pluginName}" callback handler failed`);
2313
2188
  if (!answered) {
2314
2189
  try {
2315
2190
  await ctx.answerCallbackQuery({ text: "Error processing action" });
@@ -2332,7 +2207,7 @@ var InlineRouter = class {
2332
2207
  };
2333
2208
  await plugin.onChosenResult(crCtx);
2334
2209
  } catch (error) {
2335
- log5.error({ err: error }, `Plugin "${pluginName}" chosen result handler failed`);
2210
+ log4.error({ err: error }, `Plugin "${pluginName}" chosen result handler failed`);
2336
2211
  }
2337
2212
  }
2338
2213
  /**
@@ -2410,8 +2285,8 @@ function withTimeout(promise, ms, message) {
2410
2285
  }
2411
2286
 
2412
2287
  // src/agent/tools/plugin-loader.ts
2413
- import { readdirSync as readdirSync2, readFileSync as readFileSync5, existsSync as existsSync6, statSync } from "fs";
2414
- import { join as join4 } from "path";
2288
+ import { readdirSync as readdirSync2, readFileSync as readFileSync4, existsSync as existsSync5, statSync } from "fs";
2289
+ import { join as join3 } from "path";
2415
2290
  import { pathToFileURL } from "url";
2416
2291
  import { execFile } from "child_process";
2417
2292
 
@@ -2442,7 +2317,7 @@ import { promisify } from "util";
2442
2317
 
2443
2318
  // src/agent/tools/plugin-validator.ts
2444
2319
  import { z } from "zod";
2445
- var log6 = createLogger("PluginValidator");
2320
+ var log5 = createLogger("PluginValidator");
2446
2321
  var ManifestSchema = z.object({
2447
2322
  name: z.string().min(1).max(64).regex(
2448
2323
  /^[a-z0-9][a-z0-9-]*$/,
@@ -2485,20 +2360,20 @@ function validateToolDefs(defs, pluginName) {
2485
2360
  const valid = [];
2486
2361
  for (const def of defs) {
2487
2362
  if (!def || typeof def !== "object") {
2488
- log6.warn(`[${pluginName}] tool is not an object, skipping`);
2363
+ log5.warn(`[${pluginName}] tool is not an object, skipping`);
2489
2364
  continue;
2490
2365
  }
2491
2366
  const t = def;
2492
2367
  if (!t.name || typeof t.name !== "string") {
2493
- log6.warn(`[${pluginName}] tool missing 'name', skipping`);
2368
+ log5.warn(`[${pluginName}] tool missing 'name', skipping`);
2494
2369
  continue;
2495
2370
  }
2496
2371
  if (!t.description || typeof t.description !== "string") {
2497
- log6.warn(`[${pluginName}] tool "${t.name}" missing 'description', skipping`);
2372
+ log5.warn(`[${pluginName}] tool "${t.name}" missing 'description', skipping`);
2498
2373
  continue;
2499
2374
  }
2500
2375
  if (!t.execute || typeof t.execute !== "function") {
2501
- log6.warn(`[${pluginName}] tool "${t.name}" missing 'execute' function, skipping`);
2376
+ log5.warn(`[${pluginName}] tool "${t.name}" missing 'execute' function, skipping`);
2502
2377
  continue;
2503
2378
  }
2504
2379
  valid.push(t);
@@ -2558,25 +2433,25 @@ function withTxLock(fn) {
2558
2433
  }
2559
2434
 
2560
2435
  // src/ton/transfer.ts
2561
- var log7 = createLogger("TON");
2436
+ var log6 = createLogger("TON");
2562
2437
  async function sendTon(params) {
2563
2438
  return withTxLock(async () => {
2564
2439
  try {
2565
2440
  const { toAddress: toAddress2, amount, comment = "", bounce = false } = params;
2566
2441
  if (!Number.isFinite(amount) || amount <= 0) {
2567
- log7.error({ amount }, "Invalid transfer amount");
2442
+ log6.error({ amount }, "Invalid transfer amount");
2568
2443
  return null;
2569
2444
  }
2570
2445
  let recipientAddress;
2571
2446
  try {
2572
2447
  recipientAddress = Address.parse(toAddress2);
2573
2448
  } catch (e) {
2574
- log7.error({ err: e }, `Invalid recipient address: ${toAddress2}`);
2449
+ log6.error({ err: e }, `Invalid recipient address: ${toAddress2}`);
2575
2450
  return null;
2576
2451
  }
2577
2452
  const keyPair = await getKeyPair();
2578
2453
  if (!keyPair) {
2579
- log7.error("Wallet not initialized");
2454
+ log6.error("Wallet not initialized");
2580
2455
  return null;
2581
2456
  }
2582
2457
  const wallet = WalletContractV5R1.create({
@@ -2600,7 +2475,7 @@ async function sendTon(params) {
2600
2475
  ]
2601
2476
  });
2602
2477
  const pseudoHash = `${seqno}_${Date.now()}_${amount.toFixed(2)}`;
2603
- log7.info(`Sent ${amount} TON to ${toAddress2.slice(0, 8)}... - seqno: ${seqno}`);
2478
+ log6.info(`Sent ${amount} TON to ${toAddress2.slice(0, 8)}... - seqno: ${seqno}`);
2604
2479
  return pseudoHash;
2605
2480
  } catch (error) {
2606
2481
  const err = error;
@@ -2608,14 +2483,14 @@ async function sendTon(params) {
2608
2483
  if (status === 429 || status !== void 0 && status >= 500) {
2609
2484
  invalidateTonClientCache();
2610
2485
  }
2611
- log7.error({ err: error }, "Error sending TON");
2486
+ log6.error({ err: error }, "Error sending TON");
2612
2487
  throw error;
2613
2488
  }
2614
2489
  });
2615
2490
  }
2616
2491
 
2617
2492
  // src/utils/retry.ts
2618
- var log8 = createLogger("Utils");
2493
+ var log7 = createLogger("Utils");
2619
2494
  var DEFAULT_OPTIONS = {
2620
2495
  maxAttempts: RETRY_DEFAULT_MAX_ATTEMPTS,
2621
2496
  baseDelayMs: RETRY_DEFAULT_BASE_DELAY_MS,
@@ -2639,7 +2514,7 @@ async function withRetry(fn, options = {}) {
2639
2514
  return result;
2640
2515
  } catch (error) {
2641
2516
  lastError = error instanceof Error ? error : new Error(String(error));
2642
- log8.warn(`Retry attempt ${attempt}/${opts.maxAttempts} failed: ${lastError.message}`);
2517
+ log7.warn(`Retry attempt ${attempt}/${opts.maxAttempts} failed: ${lastError.message}`);
2643
2518
  if (attempt < opts.maxAttempts) {
2644
2519
  const delay = Math.min(opts.baseDelayMs * Math.pow(2, attempt - 1), opts.maxDelayMs);
2645
2520
  await sleep(delay);
@@ -6117,7 +5992,7 @@ var DEDUST_GAS = {
6117
5992
  var NATIVE_TON_ADDRESS = "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c";
6118
5993
 
6119
5994
  // src/agent/tools/dedust/asset-cache.ts
6120
- var log9 = createLogger("Tools");
5995
+ var log8 = createLogger("Tools");
6121
5996
  var ASSET_LIST_URL = "https://assets.dedust.io/list.json";
6122
5997
  var CACHE_TTL_MS = 10 * 60 * 1e3;
6123
5998
  var cachedAssets = [];
@@ -6136,7 +6011,7 @@ async function getAssetList() {
6136
6011
  return cachedAssets;
6137
6012
  } catch (error) {
6138
6013
  if (cachedAssets.length > 0) {
6139
- log9.warn({ err: error }, "Asset list fetch failed, using stale cache");
6014
+ log8.warn({ err: error }, "Asset list fetch failed, using stale cache");
6140
6015
  return cachedAssets;
6141
6016
  }
6142
6017
  throw error;
@@ -6189,7 +6064,7 @@ var stonApiClient = new StonApiClient();
6189
6064
  function isTon(asset) {
6190
6065
  return asset.toLowerCase() === "ton";
6191
6066
  }
6192
- async function getStonfiQuote(fromAsset, toAsset, amount, slippage, log13) {
6067
+ async function getStonfiQuote(fromAsset, toAsset, amount, slippage, log12) {
6193
6068
  try {
6194
6069
  const isTonInput = isTon(fromAsset);
6195
6070
  const isTonOutput = isTon(toAsset);
@@ -6220,11 +6095,11 @@ async function getStonfiQuote(fromAsset, toAsset, amount, slippage, log13) {
6220
6095
  fee: feeAmount.toFixed(6)
6221
6096
  };
6222
6097
  } catch (err) {
6223
- log13.debug("dex.quoteSTONfi() failed:", err);
6098
+ log12.debug("dex.quoteSTONfi() failed:", err);
6224
6099
  return null;
6225
6100
  }
6226
6101
  }
6227
- async function getDedustQuote(fromAsset, toAsset, amount, slippage, log13) {
6102
+ async function getDedustQuote(fromAsset, toAsset, amount, slippage, log12) {
6228
6103
  try {
6229
6104
  const isTonInput = isTon(fromAsset);
6230
6105
  const isTonOutput = isTon(toAsset);
@@ -6258,7 +6133,7 @@ async function getDedustQuote(fromAsset, toAsset, amount, slippage, log13) {
6258
6133
  poolType
6259
6134
  };
6260
6135
  } catch (err) {
6261
- log13.debug("dex.quoteDeDust() failed:", err);
6136
+ log12.debug("dex.quoteDeDust() failed:", err);
6262
6137
  return null;
6263
6138
  }
6264
6139
  }
@@ -6430,14 +6305,14 @@ function validateDexParams(amount, slippage) {
6430
6305
  throw new PluginSDKError("Slippage must be between 0 and 1", "OPERATION_FAILED");
6431
6306
  }
6432
6307
  }
6433
- function createDexSDK(log13) {
6308
+ function createDexSDK(log12) {
6434
6309
  return {
6435
6310
  async quote(params) {
6436
6311
  validateDexParams(params.amount, params.slippage);
6437
6312
  const slippage = params.slippage ?? 0.01;
6438
6313
  const [stonfi, dedust] = await Promise.all([
6439
- getStonfiQuote(params.fromAsset, params.toAsset, params.amount, slippage, log13),
6440
- getDedustQuote(params.fromAsset, params.toAsset, params.amount, slippage, log13)
6314
+ getStonfiQuote(params.fromAsset, params.toAsset, params.amount, slippage, log12),
6315
+ getDedustQuote(params.fromAsset, params.toAsset, params.amount, slippage, log12)
6441
6316
  ]);
6442
6317
  if (!stonfi && !dedust) {
6443
6318
  throw new PluginSDKError("No DEX has liquidity for this pair", "OPERATION_FAILED");
@@ -6471,7 +6346,7 @@ function createDexSDK(log13) {
6471
6346
  params.toAsset,
6472
6347
  params.amount,
6473
6348
  params.slippage ?? 0.01,
6474
- log13
6349
+ log12
6475
6350
  );
6476
6351
  },
6477
6352
  async quoteDeDust(params) {
@@ -6480,25 +6355,25 @@ function createDexSDK(log13) {
6480
6355
  params.toAsset,
6481
6356
  params.amount,
6482
6357
  params.slippage ?? 0.01,
6483
- log13
6358
+ log12
6484
6359
  );
6485
6360
  },
6486
6361
  async swap(params) {
6487
6362
  validateDexParams(params.amount, params.slippage);
6488
6363
  if (params.dex === "stonfi") {
6489
- return executeSTONfiSwap(params, log13);
6364
+ return executeSTONfiSwap(params, log12);
6490
6365
  }
6491
6366
  if (params.dex === "dedust") {
6492
- return executeDedustSwap(params, log13);
6367
+ return executeDedustSwap(params, log12);
6493
6368
  }
6494
6369
  const quoteResult = await this.quote(params);
6495
- return quoteResult.recommended === "stonfi" ? executeSTONfiSwap(params, log13) : executeDedustSwap(params, log13);
6370
+ return quoteResult.recommended === "stonfi" ? executeSTONfiSwap(params, log12) : executeDedustSwap(params, log12);
6496
6371
  },
6497
6372
  async swapSTONfi(params) {
6498
- return executeSTONfiSwap(params, log13);
6373
+ return executeSTONfiSwap(params, log12);
6499
6374
  },
6500
6375
  async swapDeDust(params) {
6501
- return executeDedustSwap(params, log13);
6376
+ return executeDedustSwap(params, log12);
6502
6377
  }
6503
6378
  };
6504
6379
  }
@@ -6535,7 +6410,7 @@ function normalizeDomain(domain) {
6535
6410
  if (!d.endsWith(".ton")) d += ".ton";
6536
6411
  return d;
6537
6412
  }
6538
- function createDnsSDK(log13) {
6413
+ function createDnsSDK(log12) {
6539
6414
  return {
6540
6415
  async check(domain) {
6541
6416
  const normalized = normalizeDomain(domain);
@@ -6558,7 +6433,7 @@ function createDnsSDK(log13) {
6558
6433
  };
6559
6434
  } catch (err) {
6560
6435
  if (err instanceof PluginSDKError) throw err;
6561
- log13.debug("dns.check() failed:", err);
6436
+ log12.debug("dns.check() failed:", err);
6562
6437
  throw new PluginSDKError(
6563
6438
  `Failed to check domain: ${err instanceof Error ? err.message : String(err)}`,
6564
6439
  "OPERATION_FAILED"
@@ -6571,7 +6446,7 @@ function createDnsSDK(log13) {
6571
6446
  const response = await tonapiFetch(`/dns/${encodeURIComponent(normalized)}`);
6572
6447
  if (response.status === 404) return null;
6573
6448
  if (!response.ok) {
6574
- log13.debug(`dns.resolve() TonAPI error: ${response.status}`);
6449
+ log12.debug(`dns.resolve() TonAPI error: ${response.status}`);
6575
6450
  return null;
6576
6451
  }
6577
6452
  const data = await response.json();
@@ -6583,7 +6458,7 @@ function createDnsSDK(log13) {
6583
6458
  expirationDate: data.expiring_at || void 0
6584
6459
  };
6585
6460
  } catch (err) {
6586
- log13.debug("dns.resolve() failed:", err);
6461
+ log12.debug("dns.resolve() failed:", err);
6587
6462
  return null;
6588
6463
  }
6589
6464
  },
@@ -6593,7 +6468,7 @@ function createDnsSDK(log13) {
6593
6468
  `/dns/auctions?tld=ton&limit=${Math.min(limit ?? 20, 100)}`
6594
6469
  );
6595
6470
  if (!response.ok) {
6596
- log13.debug(`dns.getAuctions() TonAPI error: ${response.status}`);
6471
+ log12.debug(`dns.getAuctions() TonAPI error: ${response.status}`);
6597
6472
  return [];
6598
6473
  }
6599
6474
  const data = await response.json();
@@ -6606,7 +6481,7 @@ function createDnsSDK(log13) {
6606
6481
  bids: a.bids || 0
6607
6482
  }));
6608
6483
  } catch (err) {
6609
- log13.debug("dns.getAuctions() failed:", err);
6484
+ log12.debug("dns.getAuctions() failed:", err);
6610
6485
  return [];
6611
6486
  }
6612
6487
  },
@@ -6920,25 +6795,25 @@ function findJettonBalance(balances, jettonAddress) {
6920
6795
  }
6921
6796
  });
6922
6797
  }
6923
- function cleanupOldTransactions(db, retentionDays, log13) {
6798
+ function cleanupOldTransactions(db, retentionDays, log12) {
6924
6799
  if (Math.random() > CLEANUP_PROBABILITY) return;
6925
6800
  try {
6926
6801
  const cutoff = Math.floor(Date.now() / 1e3) - retentionDays * 24 * 60 * 60;
6927
6802
  const result = db.prepare("DELETE FROM used_transactions WHERE used_at < ?").run(cutoff);
6928
6803
  if (result.changes > 0) {
6929
- log13.debug(`Cleaned up ${result.changes} old transaction records (>${retentionDays}d)`);
6804
+ log12.debug(`Cleaned up ${result.changes} old transaction records (>${retentionDays}d)`);
6930
6805
  }
6931
6806
  } catch (err) {
6932
- log13.error("Transaction cleanup failed:", err);
6807
+ log12.error("Transaction cleanup failed:", err);
6933
6808
  }
6934
6809
  }
6935
- function createTonSDK(log13, db) {
6810
+ function createTonSDK(log12, db) {
6936
6811
  return {
6937
6812
  getAddress() {
6938
6813
  try {
6939
6814
  return getWalletAddress();
6940
6815
  } catch (err) {
6941
- log13.error("ton.getAddress() failed:", err);
6816
+ log12.error("ton.getAddress() failed:", err);
6942
6817
  return null;
6943
6818
  }
6944
6819
  },
@@ -6948,7 +6823,7 @@ function createTonSDK(log13, db) {
6948
6823
  if (!addr) return null;
6949
6824
  return await getWalletBalance(addr);
6950
6825
  } catch (err) {
6951
- log13.error("ton.getBalance() failed:", err);
6826
+ log12.error("ton.getBalance() failed:", err);
6952
6827
  return null;
6953
6828
  }
6954
6829
  },
@@ -6956,7 +6831,7 @@ function createTonSDK(log13, db) {
6956
6831
  try {
6957
6832
  return await getTonPrice();
6958
6833
  } catch (err) {
6959
- log13.error("ton.getPrice() failed:", err);
6834
+ log12.error("ton.getPrice() failed:", err);
6960
6835
  return null;
6961
6836
  }
6962
6837
  },
@@ -7007,7 +6882,7 @@ function createTonSDK(log13, db) {
7007
6882
  );
7008
6883
  return formatTransactions(transactions);
7009
6884
  } catch (err) {
7010
- log13.error("ton.getTransactions() failed:", err);
6885
+ log12.error("ton.getTransactions() failed:", err);
7011
6886
  return [];
7012
6887
  }
7013
6888
  },
@@ -7030,7 +6905,7 @@ function createTonSDK(log13, db) {
7030
6905
  throw new PluginSDKError("Wallet not initialized", "WALLET_NOT_INITIALIZED");
7031
6906
  }
7032
6907
  const maxAgeMinutes = params.maxAgeMinutes ?? DEFAULT_MAX_AGE_MINUTES;
7033
- cleanupOldTransactions(db, DEFAULT_TX_RETENTION_DAYS, log13);
6908
+ cleanupOldTransactions(db, DEFAULT_TX_RETENTION_DAYS, log12);
7034
6909
  try {
7035
6910
  const txs = await this.getTransactions(address4, 20);
7036
6911
  for (const tx of txs) {
@@ -7064,7 +6939,7 @@ function createTonSDK(log13, db) {
7064
6939
  };
7065
6940
  } catch (err) {
7066
6941
  if (err instanceof PluginSDKError) throw err;
7067
- log13.error("ton.verifyPayment() failed:", err);
6942
+ log12.error("ton.verifyPayment() failed:", err);
7068
6943
  return {
7069
6944
  verified: false,
7070
6945
  error: `Verification failed: ${err instanceof Error ? err.message : String(err)}`
@@ -7078,7 +6953,7 @@ function createTonSDK(log13, db) {
7078
6953
  if (!addr) return [];
7079
6954
  const response = await tonapiFetch(`/accounts/${encodeURIComponent(addr)}/jettons`);
7080
6955
  if (!response.ok) {
7081
- log13.error(`ton.getJettonBalances() TonAPI error: ${response.status}`);
6956
+ log12.error(`ton.getJettonBalances() TonAPI error: ${response.status}`);
7082
6957
  return [];
7083
6958
  }
7084
6959
  const data = await response.json();
@@ -7102,7 +6977,7 @@ function createTonSDK(log13, db) {
7102
6977
  }
7103
6978
  return balances;
7104
6979
  } catch (err) {
7105
- log13.error("ton.getJettonBalances() failed:", err);
6980
+ log12.error("ton.getJettonBalances() failed:", err);
7106
6981
  return [];
7107
6982
  }
7108
6983
  },
@@ -7111,7 +6986,7 @@ function createTonSDK(log13, db) {
7111
6986
  const response = await tonapiFetch(`/jettons/${encodeURIComponent(jettonAddress)}`);
7112
6987
  if (response.status === 404) return null;
7113
6988
  if (!response.ok) {
7114
- log13.error(`ton.getJettonInfo() TonAPI error: ${response.status}`);
6989
+ log12.error(`ton.getJettonInfo() TonAPI error: ${response.status}`);
7115
6990
  return null;
7116
6991
  }
7117
6992
  const data = await response.json();
@@ -7129,7 +7004,7 @@ function createTonSDK(log13, db) {
7129
7004
  image: data.preview || metadata.image || void 0
7130
7005
  };
7131
7006
  } catch (err) {
7132
- log13.error("ton.getJettonInfo() failed:", err);
7007
+ log12.error("ton.getJettonInfo() failed:", err);
7133
7008
  return null;
7134
7009
  }
7135
7010
  },
@@ -7222,7 +7097,7 @@ function createTonSDK(log13, db) {
7222
7097
  if (status === 429 || status && status >= 500) {
7223
7098
  invalidateTonClientCache();
7224
7099
  if (attempt < MAX_SEND_ATTEMPTS) {
7225
- log13.warn(
7100
+ log12.warn(
7226
7101
  `sendJetton attempt ${attempt} failed (${status}): ${JSON.stringify(respData ?? err.message)}, retrying...`
7227
7102
  );
7228
7103
  await new Promise((r3) => setTimeout(r3, 1e3 * attempt));
@@ -7252,14 +7127,14 @@ function createTonSDK(log13, db) {
7252
7127
  try {
7253
7128
  const response = await tonapiFetch(`/accounts/${encodeURIComponent(ownerAddress)}/jettons`);
7254
7129
  if (!response.ok) {
7255
- log13.error(`ton.getJettonWalletAddress() TonAPI error: ${response.status}`);
7130
+ log12.error(`ton.getJettonWalletAddress() TonAPI error: ${response.status}`);
7256
7131
  return null;
7257
7132
  }
7258
7133
  const data = await response.json();
7259
7134
  const match = findJettonBalance(data.balances ?? [], jettonAddress);
7260
7135
  return match ? match.wallet_address.address : null;
7261
7136
  } catch (err) {
7262
- log13.error("ton.getJettonWalletAddress() failed:", err);
7137
+ log12.error("ton.getJettonWalletAddress() failed:", err);
7263
7138
  return null;
7264
7139
  }
7265
7140
  },
@@ -7436,7 +7311,7 @@ function createTonSDK(log13, db) {
7436
7311
  const wallet = loadWallet();
7437
7312
  return wallet?.publicKey ?? null;
7438
7313
  } catch (err) {
7439
- log13.error("ton.getPublicKey() failed:", err);
7314
+ log12.error("ton.getPublicKey() failed:", err);
7440
7315
  return null;
7441
7316
  }
7442
7317
  },
@@ -7452,14 +7327,14 @@ function createTonSDK(log13, db) {
7452
7327
  `/accounts/${encodeURIComponent(addr)}/nfts?limit=100&indirect_ownership=true`
7453
7328
  );
7454
7329
  if (!response.ok) {
7455
- log13.error(`ton.getNftItems() TonAPI error: ${response.status}`);
7330
+ log12.error(`ton.getNftItems() TonAPI error: ${response.status}`);
7456
7331
  return [];
7457
7332
  }
7458
7333
  const data = await response.json();
7459
7334
  if (!Array.isArray(data.nft_items)) return [];
7460
7335
  return data.nft_items.filter((item) => item.trust !== "blacklist").map((item) => mapNftItem(item));
7461
7336
  } catch (err) {
7462
- log13.error("ton.getNftItems() failed:", err);
7337
+ log12.error("ton.getNftItems() failed:", err);
7463
7338
  return [];
7464
7339
  }
7465
7340
  },
@@ -7468,13 +7343,13 @@ function createTonSDK(log13, db) {
7468
7343
  const response = await tonapiFetch(`/nfts/${encodeURIComponent(nftAddress)}`);
7469
7344
  if (response.status === 404) return null;
7470
7345
  if (!response.ok) {
7471
- log13.error(`ton.getNftInfo() TonAPI error: ${response.status}`);
7346
+ log12.error(`ton.getNftInfo() TonAPI error: ${response.status}`);
7472
7347
  return null;
7473
7348
  }
7474
7349
  const item = await response.json();
7475
7350
  return mapNftItem(item);
7476
7351
  } catch (err) {
7477
- log13.error("ton.getNftInfo() failed:", err);
7352
+ log12.error("ton.getNftInfo() failed:", err);
7478
7353
  return null;
7479
7354
  }
7480
7355
  },
@@ -7507,7 +7382,7 @@ function createTonSDK(log13, db) {
7507
7382
  `/rates?tokens=${encodeURIComponent(jettonAddress)}&currencies=usd,ton`
7508
7383
  );
7509
7384
  if (!response.ok) {
7510
- log13.debug(`ton.getJettonPrice() TonAPI error: ${response.status}`);
7385
+ log12.debug(`ton.getJettonPrice() TonAPI error: ${response.status}`);
7511
7386
  return null;
7512
7387
  }
7513
7388
  const data = await response.json();
@@ -7521,7 +7396,7 @@ function createTonSDK(log13, db) {
7521
7396
  change30d: rateData.diff_30d?.USD ?? null
7522
7397
  };
7523
7398
  } catch (err) {
7524
- log13.debug("ton.getJettonPrice() failed:", err);
7399
+ log12.debug("ton.getJettonPrice() failed:", err);
7525
7400
  return null;
7526
7401
  }
7527
7402
  },
@@ -7535,7 +7410,7 @@ function createTonSDK(log13, db) {
7535
7410
  tonapiFetch(`/jettons/${encodeURIComponent(jettonAddress)}`)
7536
7411
  ]);
7537
7412
  if (!holdersResponse.ok) {
7538
- log13.debug(`ton.getJettonHolders() TonAPI error: ${holdersResponse.status}`);
7413
+ log12.debug(`ton.getJettonHolders() TonAPI error: ${holdersResponse.status}`);
7539
7414
  return [];
7540
7415
  }
7541
7416
  const data = await holdersResponse.json();
@@ -7555,7 +7430,7 @@ function createTonSDK(log13, db) {
7555
7430
  };
7556
7431
  });
7557
7432
  } catch (err) {
7558
- log13.debug("ton.getJettonHolders() failed:", err);
7433
+ log12.debug("ton.getJettonHolders() failed:", err);
7559
7434
  return [];
7560
7435
  }
7561
7436
  },
@@ -7627,13 +7502,13 @@ function createTonSDK(log13, db) {
7627
7502
  holders: holdersCount
7628
7503
  };
7629
7504
  } catch (err) {
7630
- log13.debug("ton.getJettonHistory() failed:", err);
7505
+ log12.debug("ton.getJettonHistory() failed:", err);
7631
7506
  return null;
7632
7507
  }
7633
7508
  },
7634
7509
  // ─── Sub-namespaces ───────────────────────────────────────────
7635
- dex: Object.freeze(createDexSDK(log13)),
7636
- dns: Object.freeze(createDnsSDK(log13))
7510
+ dex: Object.freeze(createDexSDK(log12)),
7511
+ dns: Object.freeze(createDnsSDK(log12))
7637
7512
  };
7638
7513
  }
7639
7514
  function mapNftItem(item) {
@@ -7686,7 +7561,7 @@ async function getApi() {
7686
7561
  }
7687
7562
 
7688
7563
  // src/sdk/telegram-messages.ts
7689
- function createTelegramMessagesSDK(bridge, log13) {
7564
+ function createTelegramMessagesSDK(bridge, log12) {
7690
7565
  function requireBridge2() {
7691
7566
  requireBridge(bridge);
7692
7567
  }
@@ -7793,7 +7668,7 @@ function createTelegramMessagesSDK(bridge, log13) {
7793
7668
  return (resultData.messages ?? []).map(toSimpleMessage);
7794
7669
  } catch (err) {
7795
7670
  if (err instanceof PluginSDKError) throw err;
7796
- log13.error("telegram.searchMessages() failed:", err);
7671
+ log12.error("telegram.searchMessages() failed:", err);
7797
7672
  return [];
7798
7673
  }
7799
7674
  },
@@ -8036,7 +7911,7 @@ function createTelegramMessagesSDK(bridge, log13) {
8036
7911
  return messages;
8037
7912
  } catch (err) {
8038
7913
  if (err instanceof PluginSDKError) throw err;
8039
- log13.error("telegram.getScheduledMessages() failed:", err);
7914
+ log12.error("telegram.getScheduledMessages() failed:", err);
8040
7915
  return [];
8041
7916
  }
8042
7917
  },
@@ -8097,7 +7972,7 @@ function createTelegramMessagesSDK(bridge, log13) {
8097
7972
  }
8098
7973
 
8099
7974
  // src/sdk/telegram-social.ts
8100
- function createTelegramSocialSDK(bridge, log13) {
7975
+ function createTelegramSocialSDK(bridge, log12) {
8101
7976
  function requireBridge2() {
8102
7977
  requireBridge(bridge);
8103
7978
  }
@@ -8172,7 +8047,7 @@ function createTelegramSocialSDK(bridge, log13) {
8172
8047
  return null;
8173
8048
  } catch (err) {
8174
8049
  if (err instanceof PluginSDKError) throw err;
8175
- log13.error("telegram.getChatInfo() failed:", err);
8050
+ log12.error("telegram.getChatInfo() failed:", err);
8176
8051
  return null;
8177
8052
  }
8178
8053
  },
@@ -8286,7 +8161,7 @@ function createTelegramSocialSDK(bridge, log13) {
8286
8161
  });
8287
8162
  } catch (err) {
8288
8163
  if (err instanceof PluginSDKError) throw err;
8289
- log13.error("telegram.getParticipants() failed:", err);
8164
+ log12.error("telegram.getParticipants() failed:", err);
8290
8165
  return [];
8291
8166
  }
8292
8167
  },
@@ -8648,7 +8523,7 @@ function createTelegramSocialSDK(bridge, log13) {
8648
8523
  }));
8649
8524
  } catch (err) {
8650
8525
  if (err instanceof PluginSDKError) throw err;
8651
- log13.error("telegram.getDialogs() failed:", err);
8526
+ log12.error("telegram.getDialogs() failed:", err);
8652
8527
  return [];
8653
8528
  }
8654
8529
  },
@@ -8662,7 +8537,7 @@ function createTelegramSocialSDK(bridge, log13) {
8662
8537
  return messages.map(toSimpleMessage);
8663
8538
  } catch (err) {
8664
8539
  if (err instanceof PluginSDKError) throw err;
8665
- log13.error("telegram.getHistory() failed:", err);
8540
+ log12.error("telegram.getHistory() failed:", err);
8666
8541
  return [];
8667
8542
  }
8668
8543
  },
@@ -8693,7 +8568,7 @@ function createTelegramSocialSDK(bridge, log13) {
8693
8568
  }));
8694
8569
  } catch (err) {
8695
8570
  if (err instanceof PluginSDKError) throw err;
8696
- log13.error("telegram.getStarsTransactions() failed:", err);
8571
+ log12.error("telegram.getStarsTransactions() failed:", err);
8697
8572
  return [];
8698
8573
  }
8699
8574
  },
@@ -8798,7 +8673,7 @@ function createTelegramSocialSDK(bridge, log13) {
8798
8673
  };
8799
8674
  } catch (err) {
8800
8675
  if (err instanceof PluginSDKError) throw err;
8801
- log13.error("telegram.getCollectibleInfo() failed:", err);
8676
+ log12.error("telegram.getCollectibleInfo() failed:", err);
8802
8677
  return null;
8803
8678
  }
8804
8679
  },
@@ -8836,7 +8711,7 @@ function createTelegramSocialSDK(bridge, log13) {
8836
8711
  } catch (err) {
8837
8712
  if (err.errorMessage === "STARGIFT_SLUG_INVALID") return null;
8838
8713
  if (err instanceof PluginSDKError) throw err;
8839
- log13.error("telegram.getUniqueGift() failed:", err);
8714
+ log12.error("telegram.getUniqueGift() failed:", err);
8840
8715
  return null;
8841
8716
  }
8842
8717
  },
@@ -8862,7 +8737,7 @@ function createTelegramSocialSDK(bridge, log13) {
8862
8737
  } catch (err) {
8863
8738
  if (err.errorMessage === "STARGIFT_SLUG_INVALID") return null;
8864
8739
  if (err instanceof PluginSDKError) throw err;
8865
- log13.error("telegram.getUniqueGiftValue() failed:", err);
8740
+ log12.error("telegram.getUniqueGiftValue() failed:", err);
8866
8741
  return null;
8867
8742
  }
8868
8743
  },
@@ -8897,13 +8772,13 @@ function createTelegramSocialSDK(bridge, log13) {
8897
8772
  const client = getClient2();
8898
8773
  const { Api: Api4, helpers } = await import("telegram");
8899
8774
  const { CustomFile } = await import("telegram/client/uploads.js");
8900
- const { readFileSync: readFileSync8, statSync: statSync2 } = await import("fs");
8775
+ const { readFileSync: readFileSync6, statSync: statSync2 } = await import("fs");
8901
8776
  const { basename: basename2 } = await import("path");
8902
8777
  const { resolve: resolve2, normalize: normalize2 } = await import("path");
8903
- const { homedir: homedir3 } = await import("os");
8778
+ const { homedir: homedir2 } = await import("os");
8904
8779
  const { realpathSync } = await import("fs");
8905
8780
  const filePath = realpathSync(resolve2(normalize2(mediaPath)));
8906
- const home = homedir3();
8781
+ const home = homedir2();
8907
8782
  const teletonWorkspace = `${home}/.teleton/workspace/`;
8908
8783
  const allowedPrefixes = [
8909
8784
  "/tmp/",
@@ -8922,7 +8797,7 @@ function createTelegramSocialSDK(bridge, log13) {
8922
8797
  }
8923
8798
  const fileName = basename2(filePath);
8924
8799
  const fileSize = statSync2(filePath).size;
8925
- const fileBuffer = readFileSync8(filePath);
8800
+ const fileBuffer = readFileSync6(filePath);
8926
8801
  const isVideo = filePath.toLowerCase().match(/\.(mp4|mov|avi|webm|mkv|m4v)$/);
8927
8802
  const customFile = new CustomFile(fileName, fileSize, filePath, fileBuffer);
8928
8803
  const uploadedFile = await client.uploadFile({
@@ -8973,7 +8848,7 @@ function createTelegramSocialSDK(bridge, log13) {
8973
8848
  }
8974
8849
 
8975
8850
  // src/sdk/telegram.ts
8976
- function createTelegramSDK(bridge, log13) {
8851
+ function createTelegramSDK(bridge, log12) {
8977
8852
  function requireBridge2() {
8978
8853
  requireBridge(bridge);
8979
8854
  }
@@ -9077,7 +8952,7 @@ function createTelegramSDK(bridge, log13) {
9077
8952
  timestamp: m.timestamp
9078
8953
  }));
9079
8954
  } catch (err) {
9080
- log13.error("telegram.getMessages() failed:", err);
8955
+ log12.error("telegram.getMessages() failed:", err);
9081
8956
  return [];
9082
8957
  }
9083
8958
  },
@@ -9099,7 +8974,7 @@ function createTelegramSDK(bridge, log13) {
9099
8974
  return bridge.isAvailable();
9100
8975
  },
9101
8976
  getRawClient() {
9102
- log13.warn("getRawClient() called \u2014 this bypasses SDK sandbox guarantees");
8977
+ log12.warn("getRawClient() called \u2014 this bypasses SDK sandbox guarantees");
9103
8978
  if (!bridge.isAvailable()) return null;
9104
8979
  try {
9105
8980
  return bridge.getClient().getClient();
@@ -9108,23 +8983,23 @@ function createTelegramSDK(bridge, log13) {
9108
8983
  }
9109
8984
  },
9110
8985
  // Spread extended methods from sub-modules
9111
- ...createTelegramMessagesSDK(bridge, log13),
9112
- ...createTelegramSocialSDK(bridge, log13)
8986
+ ...createTelegramMessagesSDK(bridge, log12),
8987
+ ...createTelegramSocialSDK(bridge, log12)
9113
8988
  };
9114
8989
  }
9115
8990
 
9116
8991
  // src/sdk/secrets.ts
9117
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, existsSync as existsSync5 } from "fs";
9118
- import { join as join3 } from "path";
9119
- var SECRETS_DIR = join3(TELETON_ROOT, "plugins", "data");
8992
+ import { readFileSync as readFileSync3, writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync4 } from "fs";
8993
+ import { join as join2 } from "path";
8994
+ var SECRETS_DIR = join2(TELETON_ROOT, "plugins", "data");
9120
8995
  function getSecretsPath(pluginName) {
9121
- return join3(SECRETS_DIR, `${pluginName}.secrets.json`);
8996
+ return join2(SECRETS_DIR, `${pluginName}.secrets.json`);
9122
8997
  }
9123
8998
  function readSecretsFile(pluginName) {
9124
8999
  const filePath = getSecretsPath(pluginName);
9125
9000
  try {
9126
- if (!existsSync5(filePath)) return {};
9127
- const raw = readFileSync4(filePath, "utf-8");
9001
+ if (!existsSync4(filePath)) return {};
9002
+ const raw = readFileSync3(filePath, "utf-8");
9128
9003
  const parsed = JSON.parse(raw);
9129
9004
  if (typeof parsed !== "object" || parsed === null) return {};
9130
9005
  return parsed;
@@ -9133,40 +9008,40 @@ function readSecretsFile(pluginName) {
9133
9008
  }
9134
9009
  }
9135
9010
  function writePluginSecret(pluginName, key, value) {
9136
- mkdirSync3(SECRETS_DIR, { recursive: true, mode: 448 });
9011
+ mkdirSync2(SECRETS_DIR, { recursive: true, mode: 448 });
9137
9012
  const filePath = getSecretsPath(pluginName);
9138
9013
  const existing = readSecretsFile(pluginName);
9139
9014
  existing[key] = value;
9140
- writeFileSync2(filePath, JSON.stringify(existing, null, 2), { mode: 384 });
9015
+ writeFileSync(filePath, JSON.stringify(existing, null, 2), { mode: 384 });
9141
9016
  }
9142
9017
  function deletePluginSecret(pluginName, key) {
9143
9018
  const existing = readSecretsFile(pluginName);
9144
9019
  if (!(key in existing)) return false;
9145
9020
  delete existing[key];
9146
9021
  const filePath = getSecretsPath(pluginName);
9147
- writeFileSync2(filePath, JSON.stringify(existing, null, 2), { mode: 384 });
9022
+ writeFileSync(filePath, JSON.stringify(existing, null, 2), { mode: 384 });
9148
9023
  return true;
9149
9024
  }
9150
9025
  function listPluginSecretKeys(pluginName) {
9151
9026
  return Object.keys(readSecretsFile(pluginName));
9152
9027
  }
9153
- function createSecretsSDK(pluginName, pluginConfig, log13) {
9028
+ function createSecretsSDK(pluginName, pluginConfig, log12) {
9154
9029
  const envPrefix = pluginName.replace(/-/g, "_").toUpperCase();
9155
9030
  function get(key) {
9156
9031
  const envKey = `${envPrefix}_${key.toUpperCase()}`;
9157
9032
  const envValue = process.env[envKey];
9158
9033
  if (envValue) {
9159
- log13.debug(`Secret "${key}" resolved from env var ${envKey}`);
9034
+ log12.debug(`Secret "${key}" resolved from env var ${envKey}`);
9160
9035
  return envValue;
9161
9036
  }
9162
9037
  const stored = readSecretsFile(pluginName);
9163
9038
  if (key in stored && stored[key]) {
9164
- log13.debug(`Secret "${key}" resolved from secrets store`);
9039
+ log12.debug(`Secret "${key}" resolved from secrets store`);
9165
9040
  return stored[key];
9166
9041
  }
9167
9042
  const configValue = pluginConfig[key];
9168
9043
  if (configValue !== void 0 && configValue !== null) {
9169
- log13.debug(`Secret "${key}" resolved from pluginConfig`);
9044
+ log12.debug(`Secret "${key}" resolved from pluginConfig`);
9170
9045
  return String(configValue);
9171
9046
  }
9172
9047
  return void 0;
@@ -9268,7 +9143,7 @@ function createStorageSDK(db) {
9268
9143
  }
9269
9144
 
9270
9145
  // src/sdk/bot.ts
9271
- function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLimiter, log13) {
9146
+ function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLimiter, log12) {
9272
9147
  if (!router || !manifest || !manifest.inline && !manifest.callbacks) {
9273
9148
  return null;
9274
9149
  }
@@ -9291,7 +9166,7 @@ function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLi
9291
9166
  },
9292
9167
  onInlineQuery(handler) {
9293
9168
  if (handlers.onInlineQuery) {
9294
- log13.warn("onInlineQuery called again \u2014 overwriting previous handler");
9169
+ log12.warn("onInlineQuery called again \u2014 overwriting previous handler");
9295
9170
  }
9296
9171
  handlers.onInlineQuery = async (ctx) => {
9297
9172
  if (rateLimiter) {
@@ -9337,7 +9212,7 @@ function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLi
9337
9212
  return;
9338
9213
  } catch (error) {
9339
9214
  if (error?.errorMessage === "MESSAGE_NOT_MODIFIED") return;
9340
- log13.warn(`GramJS edit failed, falling back to Grammy: ${error?.errorMessage || error}`);
9215
+ log12.warn(`GramJS edit failed, falling back to Grammy: ${error?.errorMessage || error}`);
9341
9216
  }
9342
9217
  }
9343
9218
  if (grammyBot) {
@@ -9350,7 +9225,7 @@ function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLi
9350
9225
  });
9351
9226
  } catch (error) {
9352
9227
  if (error?.description?.includes("message is not modified")) return;
9353
- log13.error(`Failed to edit inline message: ${error?.description || error}`);
9228
+ log12.error(`Failed to edit inline message: ${error?.description || error}`);
9354
9229
  }
9355
9230
  }
9356
9231
  },
@@ -9409,13 +9284,13 @@ function createSafeDb(db) {
9409
9284
  });
9410
9285
  }
9411
9286
  function createPluginSDK(deps, opts) {
9412
- const log13 = createLogger2(opts.pluginName);
9287
+ const log12 = createLogger2(opts.pluginName);
9413
9288
  const safeDb = opts.db ? createSafeDb(opts.db) : null;
9414
- const ton = Object.freeze(createTonSDK(log13, safeDb));
9415
- const telegram = Object.freeze(createTelegramSDK(deps.bridge, log13));
9416
- const secrets = Object.freeze(createSecretsSDK(opts.pluginName, opts.pluginConfig, log13));
9289
+ const ton = Object.freeze(createTonSDK(log12, safeDb));
9290
+ const telegram = Object.freeze(createTelegramSDK(deps.bridge, log12));
9291
+ const secrets = Object.freeze(createSecretsSDK(opts.pluginName, opts.pluginConfig, log12));
9417
9292
  const storage = safeDb ? Object.freeze(createStorageSDK(safeDb)) : null;
9418
- const frozenLog = Object.freeze(log13);
9293
+ const frozenLog = Object.freeze(log12);
9419
9294
  const frozenConfig = Object.freeze(JSON.parse(JSON.stringify(opts.sanitizedConfig ?? {})));
9420
9295
  const frozenPluginConfig = Object.freeze(JSON.parse(JSON.stringify(opts.pluginConfig ?? {})));
9421
9296
  let cachedBot;
@@ -9446,20 +9321,20 @@ function createPluginSDK(deps, opts) {
9446
9321
  },
9447
9322
  on(hookName, handler, onOpts) {
9448
9323
  if (!opts.hookRegistry) {
9449
- log13.warn(`Hook registration unavailable \u2014 sdk.on() ignored`);
9324
+ log12.warn(`Hook registration unavailable \u2014 sdk.on() ignored`);
9450
9325
  return;
9451
9326
  }
9452
9327
  if (opts.declaredHooks) {
9453
9328
  const declared = opts.declaredHooks.some((h2) => h2.name === hookName);
9454
9329
  if (!declared) {
9455
- log13.warn(`Hook "${hookName}" not declared in manifest \u2014 registration rejected`);
9330
+ log12.warn(`Hook "${hookName}" not declared in manifest \u2014 registration rejected`);
9456
9331
  return;
9457
9332
  }
9458
9333
  }
9459
9334
  const rawPriority = Number(onOpts?.priority) || 0;
9460
9335
  const clampedPriority = Math.max(-1e3, Math.min(1e3, rawPriority));
9461
9336
  if (rawPriority !== clampedPriority) {
9462
- log13.debug(`Hook "${hookName}" priority ${rawPriority} clamped to ${clampedPriority}`);
9337
+ log12.debug(`Hook "${hookName}" priority ${rawPriority} clamped to ${clampedPriority}`);
9463
9338
  }
9464
9339
  const registered = opts.hookRegistry.register({
9465
9340
  pluginId: opts.pluginName,
@@ -9469,7 +9344,7 @@ function createPluginSDK(deps, opts) {
9469
9344
  globalPriority: opts.globalPriority ?? 0
9470
9345
  });
9471
9346
  if (!registered) {
9472
- log13.warn(
9347
+ log12.warn(
9473
9348
  `Hook registration limit reached for plugin "${opts.pluginName}" \u2014 "${hookName}" rejected`
9474
9349
  );
9475
9350
  }
@@ -9588,24 +9463,24 @@ var HookRegistry = class {
9588
9463
 
9589
9464
  // src/agent/tools/plugin-loader.ts
9590
9465
  var execFileAsync = promisify(execFile);
9591
- var log10 = createLogger("PluginLoader");
9592
- var PLUGIN_DATA_DIR = join4(TELETON_ROOT, "plugins", "data");
9466
+ var log9 = createLogger("PluginLoader");
9467
+ var PLUGIN_DATA_DIR = join3(TELETON_ROOT, "plugins", "data");
9593
9468
  function adaptPlugin(raw, entryName, config, loadedModuleNames, sdkDeps, hookRegistry, pluginPriorities) {
9594
9469
  let manifest = null;
9595
9470
  if (raw.manifest) {
9596
9471
  try {
9597
9472
  manifest = validateManifest(raw.manifest);
9598
9473
  } catch (err) {
9599
- log10.warn(
9474
+ log9.warn(
9600
9475
  `[${entryName}] invalid manifest, ignoring: ${err instanceof Error ? err.message : err}`
9601
9476
  );
9602
9477
  }
9603
9478
  }
9604
9479
  if (!manifest) {
9605
- const manifestPath = join4(WORKSPACE_PATHS.PLUGINS_DIR, entryName, "manifest.json");
9480
+ const manifestPath = join3(WORKSPACE_PATHS.PLUGINS_DIR, entryName, "manifest.json");
9606
9481
  try {
9607
- if (existsSync6(manifestPath)) {
9608
- const diskManifest = JSON.parse(readFileSync5(manifestPath, "utf-8"));
9482
+ if (existsSync5(manifestPath)) {
9483
+ const diskManifest = JSON.parse(readFileSync4(manifestPath, "utf-8"));
9609
9484
  if (diskManifest && typeof diskManifest.version === "string") {
9610
9485
  manifest = {
9611
9486
  name: entryName,
@@ -9680,7 +9555,7 @@ function adaptPlugin(raw, entryName, config, loadedModuleNames, sdkDeps, hookReg
9680
9555
  },
9681
9556
  migrate() {
9682
9557
  try {
9683
- const dbPath = join4(PLUGIN_DATA_DIR, `${pluginName}.db`);
9558
+ const dbPath = join3(PLUGIN_DATA_DIR, `${pluginName}.db`);
9684
9559
  pluginDb = openModuleDb(dbPath);
9685
9560
  if (hasMigrate) {
9686
9561
  raw.migrate?.(pluginDb);
@@ -9785,36 +9660,36 @@ function adaptPlugin(raw, entryName, config, loadedModuleNames, sdkDeps, hookReg
9785
9660
  return module;
9786
9661
  }
9787
9662
  async function ensurePluginDeps(pluginDir, pluginEntry) {
9788
- const pkgJson = join4(pluginDir, "package.json");
9789
- const lockfile = join4(pluginDir, "package-lock.json");
9790
- const nodeModules = join4(pluginDir, "node_modules");
9791
- if (!existsSync6(pkgJson)) return;
9792
- if (!existsSync6(lockfile)) {
9793
- log10.warn(
9663
+ const pkgJson = join3(pluginDir, "package.json");
9664
+ const lockfile = join3(pluginDir, "package-lock.json");
9665
+ const nodeModules = join3(pluginDir, "node_modules");
9666
+ if (!existsSync5(pkgJson)) return;
9667
+ if (!existsSync5(lockfile)) {
9668
+ log9.warn(
9794
9669
  `[${pluginEntry}] package.json without package-lock.json \u2014 skipping (lockfile required)`
9795
9670
  );
9796
9671
  return;
9797
9672
  }
9798
- if (existsSync6(nodeModules)) {
9799
- const marker = join4(nodeModules, ".package-lock.json");
9800
- if (existsSync6(marker) && statSync(marker).mtimeMs >= statSync(lockfile).mtimeMs) return;
9673
+ if (existsSync5(nodeModules)) {
9674
+ const marker = join3(nodeModules, ".package-lock.json");
9675
+ if (existsSync5(marker) && statSync(marker).mtimeMs >= statSync(lockfile).mtimeMs) return;
9801
9676
  }
9802
- log10.info(`[${pluginEntry}] Installing dependencies...`);
9677
+ log9.info(`[${pluginEntry}] Installing dependencies...`);
9803
9678
  try {
9804
9679
  await execFileAsync("npm", ["ci", "--ignore-scripts", "--no-audit", "--no-fund"], {
9805
9680
  cwd: pluginDir,
9806
9681
  timeout: 6e4,
9807
9682
  env: { ...process.env, NODE_ENV: "production" }
9808
9683
  });
9809
- log10.info(`[${pluginEntry}] Dependencies installed`);
9684
+ log9.info(`[${pluginEntry}] Dependencies installed`);
9810
9685
  } catch (err) {
9811
- log10.error(`[${pluginEntry}] Failed to install deps: ${String(err).slice(0, 300)}`);
9686
+ log9.error(`[${pluginEntry}] Failed to install deps: ${String(err).slice(0, 300)}`);
9812
9687
  }
9813
9688
  }
9814
9689
  async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
9815
9690
  const hookRegistry = new HookRegistry();
9816
9691
  const pluginsDir = WORKSPACE_PATHS.PLUGINS_DIR;
9817
- if (!existsSync6(pluginsDir)) {
9692
+ if (!existsSync5(pluginsDir)) {
9818
9693
  return { modules: [], hookRegistry };
9819
9694
  }
9820
9695
  let pluginPriorities = /* @__PURE__ */ new Map();
@@ -9830,15 +9705,15 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
9830
9705
  const pluginPaths = [];
9831
9706
  for (const entry of entries) {
9832
9707
  if (entry === "data") continue;
9833
- const entryPath = join4(pluginsDir, entry);
9708
+ const entryPath = join3(pluginsDir, entry);
9834
9709
  let modulePath = null;
9835
9710
  try {
9836
9711
  const stat = statSync(entryPath);
9837
9712
  if (stat.isFile() && entry.endsWith(".js")) {
9838
9713
  modulePath = entryPath;
9839
9714
  } else if (stat.isDirectory()) {
9840
- const indexPath = join4(entryPath, "index.js");
9841
- if (existsSync6(indexPath)) {
9715
+ const indexPath = join3(entryPath, "index.js");
9716
+ if (existsSync5(indexPath)) {
9842
9717
  modulePath = indexPath;
9843
9718
  }
9844
9719
  }
@@ -9850,7 +9725,7 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
9850
9725
  }
9851
9726
  }
9852
9727
  await Promise.allSettled(
9853
- pluginPaths.filter(({ path }) => path.endsWith("index.js")).map(({ entry }) => ensurePluginDeps(join4(pluginsDir, entry), entry))
9728
+ pluginPaths.filter(({ path }) => path.endsWith("index.js")).map(({ entry }) => ensurePluginDeps(join3(pluginsDir, entry), entry))
9854
9729
  );
9855
9730
  const loadResults = await Promise.allSettled(
9856
9731
  pluginPaths.map(async ({ entry, path }) => {
@@ -9861,7 +9736,7 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
9861
9736
  );
9862
9737
  for (const result of loadResults) {
9863
9738
  if (result.status === "rejected") {
9864
- log10.error(
9739
+ log9.error(
9865
9740
  `Plugin failed to load: ${result.reason instanceof Error ? result.reason.message : result.reason}`
9866
9741
  );
9867
9742
  continue;
@@ -9869,7 +9744,7 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
9869
9744
  const { entry, mod } = result.value;
9870
9745
  try {
9871
9746
  if (!mod.tools || typeof mod.tools !== "function" && !Array.isArray(mod.tools)) {
9872
- log10.warn(`Plugin "${entry}": no 'tools' array or function exported, skipping`);
9747
+ log9.warn(`Plugin "${entry}": no 'tools' array or function exported, skipping`);
9873
9748
  continue;
9874
9749
  }
9875
9750
  const adapted = adaptPlugin(
@@ -9882,679 +9757,35 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
9882
9757
  pluginPriorities
9883
9758
  );
9884
9759
  if (loadedNames.has(adapted.name)) {
9885
- log10.warn(`Plugin "${adapted.name}" already loaded, skipping duplicate from "${entry}"`);
9760
+ log9.warn(`Plugin "${adapted.name}" already loaded, skipping duplicate from "${entry}"`);
9886
9761
  continue;
9887
9762
  }
9888
9763
  loadedNames.add(adapted.name);
9889
9764
  modules.push(adapted);
9890
9765
  } catch (err) {
9891
- log10.error(`Plugin "${entry}" failed to adapt: ${err instanceof Error ? err.message : err}`);
9766
+ log9.error(`Plugin "${entry}" failed to adapt: ${err instanceof Error ? err.message : err}`);
9892
9767
  }
9893
9768
  }
9894
9769
  return { modules, hookRegistry };
9895
9770
  }
9896
9771
 
9897
- // src/config/configurable-keys.ts
9898
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync3, existsSync as existsSync7 } from "fs";
9899
- import { parse as parse2, stringify as stringify2 } from "yaml";
9900
- var noValidation = () => void 0;
9901
- var identity = (v) => v;
9902
- var nonEmpty = (v) => v.length > 0 ? void 0 : "Must not be empty";
9903
- function numberInRange(min, max) {
9904
- return (v) => {
9905
- const n2 = Number(v);
9906
- if (isNaN(n2)) return "Must be a number";
9907
- if (n2 < min || n2 > max) return `Must be between ${min} and ${max}`;
9908
- return void 0;
9909
- };
9910
- }
9911
- function enumValidator(options) {
9912
- return (v) => options.includes(v) ? void 0 : `Must be one of: ${options.join(", ")}`;
9913
- }
9914
- function positiveInteger(v) {
9915
- const n2 = Number(v);
9916
- if (!Number.isInteger(n2) || n2 <= 0) return "Must be a positive integer";
9917
- return void 0;
9918
- }
9919
- function validateUrl(v) {
9920
- if (v === "") return void 0;
9921
- if (v.startsWith("http://") || v.startsWith("https://")) return void 0;
9922
- return "Must be empty or start with http:// or https://";
9923
- }
9924
- var CONFIGURABLE_KEYS = {
9925
- // ─── API Keys ──────────────────────────────────────────────────────
9926
- "agent.api_key": {
9927
- type: "string",
9928
- category: "API Keys",
9929
- label: "LLM API Key",
9930
- description: "LLM provider API key",
9931
- sensitive: true,
9932
- hotReload: "instant",
9933
- validate: (v) => v.length >= 10 ? void 0 : "Must be at least 10 characters",
9934
- mask: (v) => v.slice(0, 8) + "****",
9935
- parse: identity
9936
- },
9937
- tavily_api_key: {
9938
- type: "string",
9939
- category: "API Keys",
9940
- label: "Tavily API Key",
9941
- description: "Tavily API key for web search",
9942
- sensitive: true,
9943
- hotReload: "instant",
9944
- validate: (v) => v.startsWith("tvly-") ? void 0 : "Must start with 'tvly-'",
9945
- mask: (v) => v.slice(0, 9) + "****",
9946
- parse: identity
9947
- },
9948
- tonapi_key: {
9949
- type: "string",
9950
- category: "API Keys",
9951
- label: "TonAPI Key",
9952
- description: "TonAPI key for higher rate limits",
9953
- sensitive: true,
9954
- hotReload: "instant",
9955
- validate: (v) => v.length >= 10 ? void 0 : "Must be at least 10 characters",
9956
- mask: (v) => v.slice(0, 10) + "****",
9957
- parse: identity
9958
- },
9959
- toncenter_api_key: {
9960
- type: "string",
9961
- category: "API Keys",
9962
- label: "TonCenter API Key",
9963
- description: "TonCenter API key for dedicated RPC endpoint (free at toncenter.com)",
9964
- sensitive: true,
9965
- hotReload: "instant",
9966
- validate: (v) => v.length >= 10 ? void 0 : "Must be at least 10 characters",
9967
- mask: (v) => v.slice(0, 10) + "****",
9968
- parse: identity
9969
- },
9970
- "telegram.bot_token": {
9971
- type: "string",
9972
- category: "API Keys",
9973
- label: "Bot Token",
9974
- description: "Bot token from @BotFather",
9975
- sensitive: true,
9976
- hotReload: "instant",
9977
- validate: (v) => v.includes(":") ? void 0 : "Must contain ':' (e.g., 123456:ABC...)",
9978
- mask: (v) => v.split(":")[0] + ":****",
9979
- parse: identity
9980
- },
9981
- // ─── Agent ─────────────────────────────────────────────────────────
9982
- "agent.provider": {
9983
- type: "enum",
9984
- category: "Agent",
9985
- label: "Provider",
9986
- description: "LLM provider",
9987
- sensitive: false,
9988
- hotReload: "instant",
9989
- options: getSupportedProviders().map((p2) => p2.id),
9990
- validate: enumValidator(getSupportedProviders().map((p2) => p2.id)),
9991
- mask: identity,
9992
- parse: identity
9993
- },
9994
- "agent.model": {
9995
- type: "string",
9996
- category: "Agent",
9997
- label: "Model",
9998
- description: "Main LLM model ID",
9999
- sensitive: false,
10000
- hotReload: "instant",
10001
- validate: nonEmpty,
10002
- mask: identity,
10003
- parse: identity
10004
- },
10005
- "agent.utility_model": {
10006
- type: "string",
10007
- category: "Agent",
10008
- label: "Utility Model",
10009
- description: "Cheap model for summarization (auto-detected if empty)",
10010
- sensitive: false,
10011
- hotReload: "instant",
10012
- validate: noValidation,
10013
- mask: identity,
10014
- parse: identity
10015
- },
10016
- "agent.temperature": {
10017
- type: "number",
10018
- category: "Agent",
10019
- label: "Temperature",
10020
- description: "Response creativity (0.0 = deterministic, 2.0 = max)",
10021
- sensitive: false,
10022
- hotReload: "instant",
10023
- validate: numberInRange(0, 2),
10024
- mask: identity,
10025
- parse: (v) => Number(v)
10026
- },
10027
- "agent.max_tokens": {
10028
- type: "number",
10029
- category: "Agent",
10030
- label: "Max Tokens",
10031
- description: "Maximum response length in tokens",
10032
- sensitive: false,
10033
- hotReload: "instant",
10034
- validate: numberInRange(256, 128e3),
10035
- mask: identity,
10036
- parse: (v) => Number(v)
10037
- },
10038
- "agent.max_agentic_iterations": {
10039
- type: "number",
10040
- category: "Agent",
10041
- label: "Max Iterations",
10042
- description: "Max tool-call loop iterations per message",
10043
- sensitive: false,
10044
- hotReload: "instant",
10045
- validate: numberInRange(1, 20),
10046
- mask: identity,
10047
- parse: (v) => Number(v)
10048
- },
10049
- "agent.base_url": {
10050
- type: "string",
10051
- category: "Agent",
10052
- label: "API Base URL",
10053
- description: "Base URL for local LLM server (requires restart)",
10054
- sensitive: false,
10055
- hotReload: "restart",
10056
- validate: validateUrl,
10057
- mask: identity,
10058
- parse: identity
10059
- },
10060
- "cocoon.port": {
10061
- type: "number",
10062
- category: "Agent",
10063
- label: "Cocoon Port",
10064
- description: "Cocoon proxy port (requires restart)",
10065
- sensitive: false,
10066
- hotReload: "restart",
10067
- validate: numberInRange(1, 65535),
10068
- mask: identity,
10069
- parse: (v) => Number(v)
10070
- },
10071
- // ─── Session ───────────────────────────────────────────────────
10072
- "agent.session_reset_policy.daily_reset_enabled": {
10073
- type: "boolean",
10074
- category: "Session",
10075
- label: "Daily Reset",
10076
- description: "Enable daily session reset at specified hour",
10077
- sensitive: false,
10078
- hotReload: "instant",
10079
- validate: enumValidator(["true", "false"]),
10080
- mask: identity,
10081
- parse: (v) => v === "true"
10082
- },
10083
- "agent.session_reset_policy.daily_reset_hour": {
10084
- type: "number",
10085
- category: "Session",
10086
- label: "Reset Hour",
10087
- description: "Hour (0-23 UTC) for daily session reset",
10088
- sensitive: false,
10089
- hotReload: "instant",
10090
- validate: numberInRange(0, 23),
10091
- mask: identity,
10092
- parse: (v) => Number(v)
10093
- },
10094
- "agent.session_reset_policy.idle_expiry_enabled": {
10095
- type: "boolean",
10096
- category: "Session",
10097
- label: "Idle Expiry",
10098
- description: "Enable automatic session expiry after idle period",
10099
- sensitive: false,
10100
- hotReload: "instant",
10101
- validate: enumValidator(["true", "false"]),
10102
- mask: identity,
10103
- parse: (v) => v === "true"
10104
- },
10105
- "agent.session_reset_policy.idle_expiry_minutes": {
10106
- type: "number",
10107
- category: "Session",
10108
- label: "Idle Minutes",
10109
- description: "Idle minutes before session expires (minimum 1)",
10110
- sensitive: false,
10111
- hotReload: "instant",
10112
- validate: numberInRange(1, Number.MAX_SAFE_INTEGER),
10113
- mask: identity,
10114
- parse: (v) => Number(v)
10115
- },
10116
- // ─── Telegram ──────────────────────────────────────────────────────
10117
- "telegram.bot_username": {
10118
- type: "string",
10119
- category: "Telegram",
10120
- label: "Bot Username",
10121
- description: "Bot username without @",
10122
- sensitive: false,
10123
- hotReload: "instant",
10124
- validate: (v) => v.length >= 3 ? void 0 : "Must be at least 3 characters",
10125
- mask: identity,
10126
- parse: identity
10127
- },
10128
- "telegram.dm_policy": {
10129
- type: "enum",
10130
- category: "Telegram",
10131
- label: "DM Policy",
10132
- description: "Who can message the bot in private",
10133
- sensitive: false,
10134
- hotReload: "instant",
10135
- options: ["admin-only", "allowlist", "open", "disabled"],
10136
- optionLabels: {
10137
- "admin-only": "Admin Only",
10138
- allowlist: "Allow Users",
10139
- open: "Open",
10140
- disabled: "Disabled"
10141
- },
10142
- validate: enumValidator(["open", "allowlist", "admin-only", "disabled"]),
10143
- mask: identity,
10144
- parse: identity
10145
- },
10146
- "telegram.group_policy": {
10147
- type: "enum",
10148
- category: "Telegram",
10149
- label: "Group Policy",
10150
- description: "Which groups the bot can respond in",
10151
- sensitive: false,
10152
- hotReload: "instant",
10153
- options: ["open", "allowlist", "admin-only", "disabled"],
10154
- optionLabels: {
10155
- open: "Open",
10156
- allowlist: "Allow Groups",
10157
- "admin-only": "Admin Only",
10158
- disabled: "Disabled"
10159
- },
10160
- validate: enumValidator(["open", "allowlist", "admin-only", "disabled"]),
10161
- mask: identity,
10162
- parse: identity
10163
- },
10164
- "telegram.require_mention": {
10165
- type: "boolean",
10166
- category: "Telegram",
10167
- label: "Require Mention",
10168
- description: "Require @mention in groups to respond",
10169
- sensitive: false,
10170
- hotReload: "instant",
10171
- validate: enumValidator(["true", "false"]),
10172
- mask: identity,
10173
- parse: (v) => v === "true"
10174
- },
10175
- "telegram.owner_name": {
10176
- type: "string",
10177
- category: "Telegram",
10178
- label: "Owner Name",
10179
- description: "Owner's first name (used in system prompt)",
10180
- sensitive: false,
10181
- hotReload: "instant",
10182
- validate: noValidation,
10183
- mask: identity,
10184
- parse: identity
10185
- },
10186
- "telegram.owner_username": {
10187
- type: "string",
10188
- category: "Telegram",
10189
- label: "Owner Username",
10190
- description: "Owner's Telegram username (without @)",
10191
- sensitive: false,
10192
- hotReload: "instant",
10193
- validate: noValidation,
10194
- mask: identity,
10195
- parse: identity
10196
- },
10197
- "telegram.debounce_ms": {
10198
- type: "number",
10199
- category: "Telegram",
10200
- label: "Debounce (ms)",
10201
- description: "Group message debounce delay in ms (0 = disabled)",
10202
- sensitive: false,
10203
- hotReload: "instant",
10204
- validate: numberInRange(0, 1e4),
10205
- mask: identity,
10206
- parse: (v) => Number(v)
10207
- },
10208
- "telegram.agent_channel": {
10209
- type: "string",
10210
- category: "Telegram",
10211
- label: "Agent Channel",
10212
- description: "Channel username for auto-publishing",
10213
- sensitive: false,
10214
- hotReload: "instant",
10215
- validate: noValidation,
10216
- mask: identity,
10217
- parse: identity
10218
- },
10219
- "telegram.typing_simulation": {
10220
- type: "boolean",
10221
- category: "Telegram",
10222
- label: "Typing Simulation",
10223
- description: "Simulate typing indicator before sending replies",
10224
- sensitive: false,
10225
- hotReload: "instant",
10226
- validate: enumValidator(["true", "false"]),
10227
- mask: identity,
10228
- parse: (v) => v === "true"
10229
- },
10230
- "telegram.owner_id": {
10231
- type: "number",
10232
- category: "Telegram",
10233
- label: "Admin ID",
10234
- description: "Primary admin Telegram user ID (auto-added to Admin IDs)",
10235
- sensitive: false,
10236
- hotReload: "instant",
10237
- validate: positiveInteger,
10238
- mask: identity,
10239
- parse: (v) => Number(v)
10240
- },
10241
- "telegram.max_message_length": {
10242
- type: "number",
10243
- category: "Telegram",
10244
- label: "Max Message Length",
10245
- description: "Maximum message length in characters",
10246
- sensitive: false,
10247
- hotReload: "instant",
10248
- validate: numberInRange(1, 32768),
10249
- mask: identity,
10250
- parse: (v) => Number(v)
10251
- },
10252
- "telegram.rate_limit_messages_per_second": {
10253
- type: "number",
10254
- category: "Telegram",
10255
- label: "Rate Limit \u2014 Messages/sec",
10256
- description: "Rate limit: messages per second (requires restart)",
10257
- sensitive: false,
10258
- hotReload: "restart",
10259
- validate: numberInRange(0.1, 10),
10260
- mask: identity,
10261
- parse: (v) => Number(v)
10262
- },
10263
- "telegram.rate_limit_groups_per_minute": {
10264
- type: "number",
10265
- category: "Telegram",
10266
- label: "Rate Limit \u2014 Groups/min",
10267
- description: "Rate limit: groups per minute (requires restart)",
10268
- sensitive: false,
10269
- hotReload: "restart",
10270
- validate: numberInRange(1, 60),
10271
- mask: identity,
10272
- parse: (v) => Number(v)
10273
- },
10274
- "telegram.admin_ids": {
10275
- type: "array",
10276
- itemType: "number",
10277
- category: "Telegram",
10278
- label: "Admin IDs",
10279
- description: "Admin user IDs with elevated access",
10280
- sensitive: false,
10281
- hotReload: "instant",
10282
- validate: positiveInteger,
10283
- mask: identity,
10284
- parse: (v) => Number(v)
10285
- },
10286
- "telegram.allow_from": {
10287
- type: "array",
10288
- itemType: "number",
10289
- category: "Telegram",
10290
- label: "Allowed Users",
10291
- description: "User IDs allowed for DM access",
10292
- sensitive: false,
10293
- hotReload: "instant",
10294
- validate: positiveInteger,
10295
- mask: identity,
10296
- parse: (v) => Number(v)
10297
- },
10298
- "telegram.group_allow_from": {
10299
- type: "array",
10300
- itemType: "number",
10301
- category: "Telegram",
10302
- label: "Allowed Groups",
10303
- description: "Group IDs allowed for group access",
10304
- sensitive: false,
10305
- hotReload: "instant",
10306
- validate: positiveInteger,
10307
- mask: identity,
10308
- parse: (v) => Number(v)
10309
- },
10310
- // ─── Embedding ─────────────────────────────────────────────────────
10311
- "embedding.provider": {
10312
- type: "enum",
10313
- category: "Embedding",
10314
- label: "Embedding Provider",
10315
- description: "Embedding provider for RAG",
10316
- sensitive: false,
10317
- hotReload: "instant",
10318
- options: ["local", "anthropic", "none"],
10319
- validate: enumValidator(["local", "anthropic", "none"]),
10320
- mask: identity,
10321
- parse: identity
10322
- },
10323
- "embedding.model": {
10324
- type: "string",
10325
- category: "Embedding",
10326
- label: "Embedding Model",
10327
- description: "Embedding model ID (requires restart)",
10328
- sensitive: false,
10329
- hotReload: "restart",
10330
- validate: noValidation,
10331
- mask: identity,
10332
- parse: identity
10333
- },
10334
- // ─── WebUI ─────────────────────────────────────────────────────────
10335
- "webui.port": {
10336
- type: "number",
10337
- category: "WebUI",
10338
- label: "WebUI Port",
10339
- description: "HTTP server port (requires restart)",
10340
- sensitive: false,
10341
- hotReload: "restart",
10342
- validate: numberInRange(1024, 65535),
10343
- mask: identity,
10344
- parse: (v) => Number(v)
10345
- },
10346
- "webui.log_requests": {
10347
- type: "boolean",
10348
- category: "WebUI",
10349
- label: "Log HTTP Requests",
10350
- description: "Log all HTTP requests to console",
10351
- sensitive: false,
10352
- hotReload: "instant",
10353
- validate: enumValidator(["true", "false"]),
10354
- mask: identity,
10355
- parse: (v) => v === "true"
10356
- },
10357
- // ─── Deals ─────────────────────────────────────────────────────────
10358
- "deals.enabled": {
10359
- type: "boolean",
10360
- category: "Deals",
10361
- label: "Deals Enabled",
10362
- description: "Enable the deals/escrow module",
10363
- sensitive: false,
10364
- hotReload: "instant",
10365
- validate: enumValidator(["true", "false"]),
10366
- mask: identity,
10367
- parse: (v) => v === "true"
10368
- },
10369
- "deals.expiry_seconds": {
10370
- type: "number",
10371
- category: "Deals",
10372
- label: "Deal Expiry",
10373
- description: "Deal expiry timeout in seconds",
10374
- sensitive: false,
10375
- hotReload: "instant",
10376
- validate: numberInRange(10, 3600),
10377
- mask: identity,
10378
- parse: (v) => Number(v)
10379
- },
10380
- "deals.buy_max_floor_percent": {
10381
- type: "number",
10382
- category: "Deals",
10383
- label: "Buy Max Floor %",
10384
- description: "Maximum floor % for buy deals",
10385
- sensitive: false,
10386
- hotReload: "instant",
10387
- validate: numberInRange(1, 100),
10388
- mask: identity,
10389
- parse: (v) => Number(v)
10390
- },
10391
- "deals.sell_min_floor_percent": {
10392
- type: "number",
10393
- category: "Deals",
10394
- label: "Sell Min Floor %",
10395
- description: "Minimum floor % for sell deals",
10396
- sensitive: false,
10397
- hotReload: "instant",
10398
- validate: numberInRange(100, 500),
10399
- mask: identity,
10400
- parse: (v) => Number(v)
10401
- },
10402
- // ─── TON Proxy ────────────────────────────────────────────────────
10403
- "ton_proxy.enabled": {
10404
- type: "boolean",
10405
- category: "TON Proxy",
10406
- label: "TON Proxy Enabled",
10407
- description: "Enable Tonutils-Proxy for .ton site access (auto-downloads binary on first run)",
10408
- sensitive: false,
10409
- hotReload: "instant",
10410
- validate: enumValidator(["true", "false"]),
10411
- mask: identity,
10412
- parse: (v) => v === "true"
10413
- },
10414
- "ton_proxy.port": {
10415
- type: "number",
10416
- category: "TON Proxy",
10417
- label: "Proxy Port",
10418
- description: "HTTP proxy port for .ton sites (default: 8080)",
10419
- sensitive: false,
10420
- hotReload: "restart",
10421
- validate: numberInRange(1, 65535),
10422
- mask: identity,
10423
- parse: (v) => Number(v)
10424
- },
10425
- "ton_proxy.binary_path": {
10426
- type: "string",
10427
- category: "TON Proxy",
10428
- label: "Binary Path",
10429
- description: "Custom path to tonutils-proxy-cli (leave empty for auto-download)",
10430
- sensitive: false,
10431
- hotReload: "restart",
10432
- validate: noValidation,
10433
- mask: identity,
10434
- parse: identity
10435
- },
10436
- // ─── Capabilities ──────────────────────────────────────────────────
10437
- "capabilities.exec.mode": {
10438
- type: "enum",
10439
- category: "Coding Agent",
10440
- label: "Exec Mode",
10441
- description: "System execution: off (disabled) or yolo (full system access)",
10442
- sensitive: false,
10443
- hotReload: "restart",
10444
- options: ["off", "yolo"],
10445
- optionLabels: { off: "Disabled", yolo: "YOLO" },
10446
- validate: enumValidator(["off", "yolo"]),
10447
- mask: identity,
10448
- parse: identity
10449
- },
10450
- "capabilities.exec.scope": {
10451
- type: "enum",
10452
- category: "Coding Agent",
10453
- label: "Exec Scope",
10454
- description: "Who can trigger exec tools",
10455
- sensitive: false,
10456
- hotReload: "restart",
10457
- options: ["admin-only", "allowlist", "all"],
10458
- optionLabels: { "admin-only": "Admin Only", allowlist: "Allowlist", all: "Everyone" },
10459
- validate: enumValidator(["admin-only", "allowlist", "all"]),
10460
- mask: identity,
10461
- parse: identity
10462
- },
10463
- // ─── Developer ─────────────────────────────────────────────────────
10464
- "dev.hot_reload": {
10465
- type: "boolean",
10466
- category: "Developer",
10467
- label: "Hot Reload",
10468
- description: "Watch ~/.teleton/plugins/ for live changes",
10469
- sensitive: false,
10470
- hotReload: "instant",
10471
- validate: enumValidator(["true", "false"]),
10472
- mask: identity,
10473
- parse: (v) => v === "true"
10474
- }
10475
- };
10476
- var FORBIDDEN_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
10477
- function assertSafePath(parts) {
10478
- if (parts.some((p2) => FORBIDDEN_SEGMENTS.has(p2))) {
10479
- throw new Error("Invalid config path: forbidden segment");
10480
- }
10481
- }
10482
- function getNestedValue(obj, path) {
10483
- const parts = path.split(".");
10484
- assertSafePath(parts);
10485
- let current = obj;
10486
- for (const part of parts) {
10487
- if (current == null || typeof current !== "object") return void 0;
10488
- current = current[part];
10489
- }
10490
- return current;
10491
- }
10492
- function setNestedValue(obj, path, value) {
10493
- const parts = path.split(".");
10494
- assertSafePath(parts);
10495
- let current = obj;
10496
- for (let i = 0; i < parts.length - 1; i++) {
10497
- if (current[parts[i]] == null || typeof current[parts[i]] !== "object") {
10498
- current[parts[i]] = {};
10499
- }
10500
- current = current[parts[i]];
10501
- }
10502
- current[parts[parts.length - 1]] = value;
10503
- }
10504
- function deleteNestedValue(obj, path) {
10505
- const parts = path.split(".");
10506
- assertSafePath(parts);
10507
- let current = obj;
10508
- for (let i = 0; i < parts.length - 1; i++) {
10509
- if (current == null || typeof current !== "object") return;
10510
- current = current[parts[i]];
10511
- }
10512
- if (current != null && typeof current === "object") {
10513
- delete current[parts[parts.length - 1]];
10514
- }
10515
- }
10516
- function readRawConfig(configPath) {
10517
- const fullPath = expandPath(configPath);
10518
- if (!existsSync7(fullPath)) {
10519
- throw new Error(`Config file not found: ${fullPath}
10520
- Run 'teleton setup' to create one.`);
10521
- }
10522
- const raw = parse2(readFileSync6(fullPath, "utf-8"));
10523
- if (!raw || typeof raw !== "object") {
10524
- throw new Error(`Invalid config file: ${fullPath}`);
10525
- }
10526
- return raw;
10527
- }
10528
- function writeRawConfig(raw, configPath) {
10529
- const clone = { ...raw };
10530
- delete clone.market;
10531
- const result = ConfigSchema.safeParse(clone);
10532
- if (!result.success) {
10533
- throw new Error(`Refusing to save invalid config: ${result.error.message}`);
10534
- }
10535
- raw.meta = raw.meta ?? {};
10536
- raw.meta.last_modified_at = (/* @__PURE__ */ new Date()).toISOString();
10537
- const fullPath = expandPath(configPath);
10538
- writeFileSync3(fullPath, stringify2(raw), { encoding: "utf-8", mode: 384 });
10539
- }
10540
-
10541
9772
  // src/ton-proxy/manager.ts
10542
9773
  import { spawn, execSync } from "child_process";
10543
9774
  import {
10544
- existsSync as existsSync8,
9775
+ existsSync as existsSync6,
10545
9776
  chmodSync,
10546
9777
  createWriteStream,
10547
- readFileSync as readFileSync7,
10548
- writeFileSync as writeFileSync4,
9778
+ readFileSync as readFileSync5,
9779
+ writeFileSync as writeFileSync2,
10549
9780
  unlinkSync
10550
9781
  } from "fs";
10551
9782
  import { mkdir } from "fs/promises";
10552
- import { join as join5 } from "path";
9783
+ import { join as join4 } from "path";
10553
9784
  import { pipeline } from "stream/promises";
10554
- var log11 = createLogger("TonProxy");
9785
+ var log10 = createLogger("TonProxy");
10555
9786
  var GITHUB_REPO = "xssnick/Tonutils-Proxy";
10556
- var BINARY_DIR = join5(TELETON_ROOT, "bin");
10557
- var PID_FILE = join5(TELETON_ROOT, "ton-proxy.pid");
9787
+ var BINARY_DIR = join4(TELETON_ROOT, "bin");
9788
+ var PID_FILE = join4(TELETON_ROOT, "ton-proxy.pid");
10558
9789
  var HEALTH_CHECK_INTERVAL_MS = 3e4;
10559
9790
  var HEALTH_CHECK_TIMEOUT_MS = 5e3;
10560
9791
  var KILL_GRACE_MS = 5e3;
@@ -10570,11 +9801,11 @@ var TonProxyManager = class {
10570
9801
  /** Resolve the binary path — user-specified or auto-detected */
10571
9802
  getBinaryPath() {
10572
9803
  if (this.config.binary_path) return this.config.binary_path;
10573
- return join5(BINARY_DIR, getBinaryName());
9804
+ return join4(BINARY_DIR, getBinaryName());
10574
9805
  }
10575
9806
  /** Check if the binary exists on disk */
10576
9807
  isInstalled() {
10577
- return existsSync8(this.getBinaryPath());
9808
+ return existsSync6(this.getBinaryPath());
10578
9809
  }
10579
9810
  /** Whether the proxy process is currently running */
10580
9811
  isRunning() {
@@ -10586,7 +9817,7 @@ var TonProxyManager = class {
10586
9817
  */
10587
9818
  async install() {
10588
9819
  const binaryName = getBinaryName();
10589
- log11.info(`Downloading TON Proxy binary (${binaryName})...`);
9820
+ log10.info(`Downloading TON Proxy binary (${binaryName})...`);
10590
9821
  await mkdir(BINARY_DIR, { recursive: true });
10591
9822
  const releaseUrl = `https://api.github.com/repos/${GITHUB_REPO}/releases/latest`;
10592
9823
  const releaseRes = await fetch(releaseUrl, {
@@ -10598,7 +9829,7 @@ var TonProxyManager = class {
10598
9829
  const release = await releaseRes.json();
10599
9830
  const tag = release.tag_name;
10600
9831
  const downloadUrl = `https://github.com/${GITHUB_REPO}/releases/download/${tag}/${binaryName}`;
10601
- log11.info(`Downloading ${downloadUrl}`);
9832
+ log10.info(`Downloading ${downloadUrl}`);
10602
9833
  const res = await fetch(downloadUrl);
10603
9834
  if (!res.ok || !res.body) {
10604
9835
  throw new Error(`Download failed: ${res.status} ${res.statusText}`);
@@ -10607,17 +9838,17 @@ var TonProxyManager = class {
10607
9838
  const fileStream = createWriteStream(dest);
10608
9839
  await pipeline(res.body, fileStream);
10609
9840
  chmodSync(dest, 493);
10610
- log11.info(`TON Proxy installed: ${dest} (${tag})`);
9841
+ log10.info(`TON Proxy installed: ${dest} (${tag})`);
10611
9842
  }
10612
9843
  /** Kill any orphan proxy process from a previous session */
10613
9844
  killOrphan() {
10614
- if (existsSync8(PID_FILE)) {
9845
+ if (existsSync6(PID_FILE)) {
10615
9846
  try {
10616
- const pid = parseInt(readFileSync7(PID_FILE, "utf-8").trim(), 10);
9847
+ const pid = parseInt(readFileSync5(PID_FILE, "utf-8").trim(), 10);
10617
9848
  if (pid && !isNaN(pid)) {
10618
9849
  try {
10619
9850
  process.kill(pid, 0);
10620
- log11.warn(`Killing orphan TON Proxy (PID ${pid}) from previous session`);
9851
+ log10.warn(`Killing orphan TON Proxy (PID ${pid}) from previous session`);
10621
9852
  process.kill(pid, "SIGTERM");
10622
9853
  } catch {
10623
9854
  }
@@ -10634,7 +9865,7 @@ var TonProxyManager = class {
10634
9865
  const pidMatch = out.match(/pid=(\d+)/);
10635
9866
  if (pidMatch) {
10636
9867
  const pid = parseInt(pidMatch[1], 10);
10637
- log11.warn(`Port ${this.config.port} occupied by PID ${pid}, killing it`);
9868
+ log10.warn(`Port ${this.config.port} occupied by PID ${pid}, killing it`);
10638
9869
  try {
10639
9870
  process.kill(pid, "SIGTERM");
10640
9871
  } catch {
@@ -10647,22 +9878,22 @@ var TonProxyManager = class {
10647
9878
  /** Write PID to file for orphan detection */
10648
9879
  writePidFile(pid) {
10649
9880
  try {
10650
- writeFileSync4(PID_FILE, String(pid), { mode: 384 });
9881
+ writeFileSync2(PID_FILE, String(pid), { mode: 384 });
10651
9882
  } catch {
10652
- log11.warn("Failed to write TON Proxy PID file");
9883
+ log10.warn("Failed to write TON Proxy PID file");
10653
9884
  }
10654
9885
  }
10655
9886
  /** Remove PID file */
10656
9887
  removePidFile() {
10657
9888
  try {
10658
- if (existsSync8(PID_FILE)) unlinkSync(PID_FILE);
9889
+ if (existsSync6(PID_FILE)) unlinkSync(PID_FILE);
10659
9890
  } catch {
10660
9891
  }
10661
9892
  }
10662
9893
  /** Start the proxy process */
10663
9894
  async start() {
10664
9895
  if (this.isRunning()) {
10665
- log11.warn("TON Proxy is already running");
9896
+ log10.warn("TON Proxy is already running");
10666
9897
  return;
10667
9898
  }
10668
9899
  this.restartCount = 0;
@@ -10673,7 +9904,7 @@ var TonProxyManager = class {
10673
9904
  }
10674
9905
  const binaryPath = this.getBinaryPath();
10675
9906
  const port = String(this.config.port);
10676
- log11.info(`Starting TON Proxy on 127.0.0.1:${port}`);
9907
+ log10.info(`Starting TON Proxy on 127.0.0.1:${port}`);
10677
9908
  this.process = spawn(binaryPath, ["-addr", `127.0.0.1:${port}`], {
10678
9909
  cwd: BINARY_DIR,
10679
9910
  stdio: ["ignore", "pipe", "pipe"],
@@ -10681,24 +9912,24 @@ var TonProxyManager = class {
10681
9912
  });
10682
9913
  this.process.stdout?.on("data", (chunk) => {
10683
9914
  const line = chunk.toString().trim();
10684
- if (line) log11.debug(`[proxy] ${line}`);
9915
+ if (line) log10.debug(`[proxy] ${line}`);
10685
9916
  });
10686
9917
  this.process.stderr?.on("data", (chunk) => {
10687
9918
  const line = chunk.toString().trim();
10688
- if (line) log11.warn(`[proxy:err] ${line}`);
9919
+ if (line) log10.warn(`[proxy:err] ${line}`);
10689
9920
  });
10690
9921
  this.process.on("exit", (code, signal) => {
10691
- log11.info(`TON Proxy exited (code=${code}, signal=${signal})`);
9922
+ log10.info(`TON Proxy exited (code=${code}, signal=${signal})`);
10692
9923
  this.process = null;
10693
9924
  this.removePidFile();
10694
9925
  if (code !== 0 && code !== null && this.restartCount < this.maxRestarts) {
10695
9926
  this.restartCount++;
10696
- log11.warn(`Auto-restarting TON Proxy (attempt ${this.restartCount}/${this.maxRestarts})`);
10697
- this.start().catch((err) => log11.error({ err }, "Failed to auto-restart TON Proxy"));
9927
+ log10.warn(`Auto-restarting TON Proxy (attempt ${this.restartCount}/${this.maxRestarts})`);
9928
+ this.start().catch((err) => log10.error({ err }, "Failed to auto-restart TON Proxy"));
10698
9929
  }
10699
9930
  });
10700
9931
  this.process.on("error", (err) => {
10701
- log11.error({ err }, "TON Proxy process error");
9932
+ log10.error({ err }, "TON Proxy process error");
10702
9933
  this.process = null;
10703
9934
  });
10704
9935
  this.startHealthCheck();
@@ -10716,14 +9947,14 @@ var TonProxyManager = class {
10716
9947
  });
10717
9948
  });
10718
9949
  if (this.process?.pid) this.writePidFile(this.process.pid);
10719
- log11.info(`TON Proxy running on 127.0.0.1:${port} (PID ${this.process?.pid})`);
9950
+ log10.info(`TON Proxy running on 127.0.0.1:${port} (PID ${this.process?.pid})`);
10720
9951
  }
10721
9952
  /** Stop the proxy process gracefully */
10722
9953
  async stop() {
10723
9954
  this.stopHealthCheck();
10724
9955
  if (!this.process) return;
10725
9956
  this.maxRestarts = 0;
10726
- log11.info("Stopping TON Proxy...");
9957
+ log10.info("Stopping TON Proxy...");
10727
9958
  return new Promise((resolve2) => {
10728
9959
  if (!this.process) {
10729
9960
  resolve2();
@@ -10731,7 +9962,7 @@ var TonProxyManager = class {
10731
9962
  }
10732
9963
  const forceKill = setTimeout(() => {
10733
9964
  if (this.process) {
10734
- log11.warn("TON Proxy did not exit gracefully, sending SIGKILL");
9965
+ log10.warn("TON Proxy did not exit gracefully, sending SIGKILL");
10735
9966
  this.process.kill("SIGKILL");
10736
9967
  }
10737
9968
  }, KILL_GRACE_MS);
@@ -10750,10 +9981,10 @@ var TonProxyManager = class {
10750
9981
  await this.stop();
10751
9982
  }
10752
9983
  const binaryPath = this.getBinaryPath();
10753
- if (existsSync8(binaryPath)) {
9984
+ if (existsSync6(binaryPath)) {
10754
9985
  const { unlink } = await import("fs/promises");
10755
9986
  await unlink(binaryPath);
10756
- log11.info(`TON Proxy binary removed: ${binaryPath}`);
9987
+ log10.info(`TON Proxy binary removed: ${binaryPath}`);
10757
9988
  }
10758
9989
  }
10759
9990
  /** Get proxy status for WebUI / tools */
@@ -10787,7 +10018,7 @@ var TonProxyManager = class {
10787
10018
  }).catch(() => null);
10788
10019
  clearTimeout(timeout);
10789
10020
  if (!res) {
10790
- log11.warn("TON Proxy health check failed (no response)");
10021
+ log10.warn("TON Proxy health check failed (no response)");
10791
10022
  }
10792
10023
  } catch {
10793
10024
  }
@@ -10844,7 +10075,7 @@ var tonProxyStatusExecutor = async () => {
10844
10075
  };
10845
10076
 
10846
10077
  // src/ton-proxy/module.ts
10847
- var log12 = createLogger("TonProxyModule");
10078
+ var log11 = createLogger("TonProxyModule");
10848
10079
  var manager = null;
10849
10080
  function getTonProxyManager() {
10850
10081
  return manager;
@@ -10871,9 +10102,9 @@ var tonProxyModule = {
10871
10102
  setProxyManager(manager);
10872
10103
  try {
10873
10104
  await manager.start();
10874
- log12.info(`TON Proxy started on port ${proxyConfig.port}`);
10105
+ log11.info(`TON Proxy started on port ${proxyConfig.port}`);
10875
10106
  } catch (err) {
10876
- log12.error({ err }, "Failed to start TON Proxy");
10107
+ log11.error({ err }, "Failed to start TON Proxy");
10877
10108
  manager = null;
10878
10109
  }
10879
10110
  },
@@ -10925,9 +10156,6 @@ function setTriggersConfig(db, triggers) {
10925
10156
  }
10926
10157
 
10927
10158
  export {
10928
- loadConfig,
10929
- configExists,
10930
- getDefaultConfigPath,
10931
10159
  WorkspaceSecurityError,
10932
10160
  validatePath,
10933
10161
  validateReadPath,
@@ -10972,12 +10200,6 @@ export {
10972
10200
  adaptPlugin,
10973
10201
  ensurePluginDeps,
10974
10202
  loadEnhancedPlugins,
10975
- CONFIGURABLE_KEYS,
10976
- getNestedValue,
10977
- setNestedValue,
10978
- deleteNestedValue,
10979
- readRawConfig,
10980
- writeRawConfig,
10981
10203
  TonProxyManager,
10982
10204
  getTonProxyManager,
10983
10205
  setTonProxyManager,