teleton 0.8.1 → 0.8.2

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 (36) hide show
  1. package/dist/{chunk-5FNWBZ5K.js → chunk-2IZU3REP.js} +147 -82
  2. package/dist/chunk-3UFPFWYP.js +12 -0
  3. package/dist/{chunk-KVXV7EF7.js → chunk-55SKE6YH.js} +2 -2
  4. package/dist/{setup-server-32XGDPE6.js → chunk-57URFK6M.js} +7 -206
  5. package/dist/chunk-5SEMA47R.js +75 -0
  6. package/dist/{chunk-S6PHGKOC.js → chunk-7YKSXOQQ.js} +10 -2
  7. package/dist/{chunk-UP55PXFH.js → chunk-C4NKJT2Z.js} +8 -0
  8. package/dist/{chunk-CGOXE4WP.js → chunk-GGXJLMOH.js} +404 -730
  9. package/dist/{chunk-QBHRXLZS.js → chunk-H7MFXJZK.js} +2 -2
  10. package/dist/{chunk-3S4GGLLR.js → chunk-HEDJCLA6.js} +58 -19
  11. package/dist/{chunk-AYWEJCDB.js → chunk-J73TA3UM.js} +7 -7
  12. package/dist/{chunk-QV2GLOTK.js → chunk-LC4TV3KL.js} +1 -1
  13. package/dist/{chunk-RCMD3U65.js → chunk-NQ6FZKCE.js} +13 -0
  14. package/dist/{chunk-7U7BOHCL.js → chunk-VYKW7FMV.js} +147 -63
  15. package/dist/chunk-W25Z7CM6.js +487 -0
  16. package/dist/{chunk-OJCLKU5Z.js → chunk-WFTC3JJW.js} +16 -0
  17. package/dist/{server-3FHI2SEB.js → chunk-XBSCYMKM.js} +23 -369
  18. package/dist/{chunk-PHSAHTK4.js → chunk-YOSUPUAJ.js} +75 -7
  19. package/dist/cli/index.js +61 -17
  20. package/dist/{client-MPHPIZB6.js → client-YOOHI776.js} +4 -4
  21. package/dist/{get-my-gifts-CC6HAVWB.js → get-my-gifts-Y7EN7RK4.js} +3 -3
  22. package/dist/index.js +14 -13
  23. package/dist/{memory-UBHM7ILG.js → memory-Q6EWGK2S.js} +6 -4
  24. package/dist/memory-hook-WUXJNVT5.js +18 -0
  25. package/dist/{migrate-UBBEJ5BL.js → migrate-WFU6COBN.js} +4 -4
  26. package/dist/server-GYZXKIKU.js +787 -0
  27. package/dist/server-YODFBZKG.js +392 -0
  28. package/dist/setup-server-IZBUOJRU.js +215 -0
  29. package/dist/{store-M5IMUQCL.js → store-7M4XV6M5.js} +5 -5
  30. package/dist/{task-dependency-resolver-RR2O5S7B.js → task-dependency-resolver-L6UUMTHK.js} +2 -2
  31. package/dist/{task-executor-6W5HRX5C.js → task-executor-XBNJLUCS.js} +2 -2
  32. package/dist/{tool-adapter-IH5VGBOO.js → tool-adapter-IVX2XQJE.js} +1 -1
  33. package/dist/{tool-index-PMAOXWUA.js → tool-index-NYH57UWP.js} +3 -3
  34. package/dist/{transcript-NGDPSNIH.js → transcript-IM7G25OS.js} +2 -2
  35. package/package.json +4 -2
  36. package/dist/chunk-XBE4JB7C.js +0 -8
@@ -7,7 +7,7 @@ import {
7
7
  getWalletBalance,
8
8
  invalidateTonClientCache,
9
9
  loadWallet
10
- } from "./chunk-S6PHGKOC.js";
10
+ } from "./chunk-7YKSXOQQ.js";
11
11
  import {
12
12
  getOrCreateSession,
13
13
  getSession,
@@ -15,7 +15,15 @@ import {
15
15
  resetSessionWithPolicy,
16
16
  shouldResetSession,
17
17
  updateSession
18
- } from "./chunk-KVXV7EF7.js";
18
+ } from "./chunk-55SKE6YH.js";
19
+ import {
20
+ saveSessionMemory,
21
+ summarizeWithFallback
22
+ } from "./chunk-W25Z7CM6.js";
23
+ import {
24
+ getErrorMessage,
25
+ isHttpError
26
+ } from "./chunk-3UFPFWYP.js";
19
27
  import {
20
28
  Mi,
21
29
  Mn,
@@ -26,41 +34,33 @@ import {
26
34
  ut,
27
35
  ye
28
36
  } from "./chunk-7TECSLJ4.js";
29
- import {
30
- getErrorMessage
31
- } from "./chunk-XBE4JB7C.js";
32
37
  import {
33
38
  chatWithContext,
34
39
  getEffectiveApiKey,
35
40
  getProviderModel,
36
- getUtilityModel,
37
41
  loadContextFromTranscript
38
- } from "./chunk-AYWEJCDB.js";
42
+ } from "./chunk-J73TA3UM.js";
39
43
  import {
40
44
  getProviderMetadata,
41
45
  getSupportedProviders
42
- } from "./chunk-PHSAHTK4.js";
46
+ } from "./chunk-YOSUPUAJ.js";
43
47
  import {
44
48
  appendToTranscript,
45
49
  archiveTranscript,
46
50
  transcriptExists
47
- } from "./chunk-QV2GLOTK.js";
51
+ } from "./chunk-LC4TV3KL.js";
48
52
  import {
49
53
  ContextBuilder,
50
54
  createDbWrapper,
51
55
  getDatabase,
52
56
  migrateFromMainDb,
53
57
  openModuleDb
54
- } from "./chunk-7U7BOHCL.js";
58
+ } from "./chunk-VYKW7FMV.js";
55
59
  import {
56
60
  GECKOTERMINAL_API_URL,
57
61
  tonapiFetch
58
62
  } from "./chunk-VFA7QMCZ.js";
59
63
  import {
60
- ADAPTIVE_CHUNK_RATIO_BASE,
61
- ADAPTIVE_CHUNK_RATIO_MIN,
62
- ADAPTIVE_CHUNK_RATIO_TRIGGER,
63
- CHARS_PER_TOKEN_ESTIMATE,
64
64
  COMPACTION_KEEP_RECENT,
65
65
  COMPACTION_MAX_MESSAGES,
66
66
  COMPACTION_MAX_TOKENS_RATIO,
@@ -72,21 +72,18 @@ import {
72
72
  DEFAULT_MAX_SUMMARY_TOKENS,
73
73
  DEFAULT_MAX_TOKENS,
74
74
  DEFAULT_SOFT_THRESHOLD_TOKENS,
75
- DEFAULT_SUMMARY_FALLBACK_TOKENS,
75
+ EMBEDDING_QUERY_MAX_CHARS,
76
76
  FALLBACK_SOFT_THRESHOLD_TOKENS,
77
77
  MASKING_KEEP_RECENT_COUNT,
78
78
  MAX_TOOL_RESULT_SIZE,
79
79
  MEMORY_FLUSH_RECENT_MESSAGES,
80
- OVERSIZED_MESSAGE_RATIO,
81
80
  PAYMENT_TOLERANCE_RATIO,
82
81
  RATE_LIMIT_MAX_RETRIES,
83
82
  RESULT_TRUNCATION_KEEP_CHARS,
84
83
  RESULT_TRUNCATION_THRESHOLD,
85
84
  SERVER_ERROR_MAX_RETRIES,
86
- SESSION_SLUG_MAX_TOKENS,
87
- SESSION_SLUG_RECENT_MESSAGES,
88
- TOKEN_ESTIMATE_SAFETY_MARGIN
89
- } from "./chunk-UP55PXFH.js";
85
+ TOOL_CONCURRENCY_LIMIT
86
+ } from "./chunk-C4NKJT2Z.js";
90
87
  import {
91
88
  fetchWithTimeout
92
89
  } from "./chunk-XQUHC3JZ.js";
@@ -107,7 +104,7 @@ import {
107
104
  } from "./chunk-EYWNOHMJ.js";
108
105
  import {
109
106
  createLogger
110
- } from "./chunk-RCMD3U65.js";
107
+ } from "./chunk-NQ6FZKCE.js";
111
108
 
112
109
  // src/config/loader.ts
113
110
  import { readFileSync, existsSync, writeFileSync, mkdirSync } from "fs";
@@ -193,6 +190,17 @@ Run 'teleton setup' to create one.`);
193
190
  );
194
191
  }
195
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
+ }
196
204
  if (process.env.TELETON_BASE_URL) {
197
205
  try {
198
206
  new URL(process.env.TELETON_BASE_URL);
@@ -366,7 +374,7 @@ function appendToDailyLog(content, date = /* @__PURE__ */ new Date()) {
366
374
  const header = `# Daily Log - ${formatDate(date)}
367
375
 
368
376
  `;
369
- appendFileSync(logPath, header, "utf-8");
377
+ appendFileSync(logPath, header, { encoding: "utf-8", mode: 384 });
370
378
  }
371
379
  const entry = `## ${timestamp}
372
380
 
@@ -741,397 +749,6 @@ ${body}`;
741
749
 
742
750
  // src/memory/compaction.ts
743
751
  import { randomUUID } from "crypto";
744
-
745
- // src/memory/ai-summarization.ts
746
- import {
747
- complete
748
- } from "@mariozechner/pi-ai";
749
- var log3 = createLogger("Memory");
750
- function estimateMessageTokens(content) {
751
- return Math.ceil(content.length / CHARS_PER_TOKEN_ESTIMATE * TOKEN_ESTIMATE_SAFETY_MARGIN);
752
- }
753
- function splitMessagesByTokens(messages, maxChunkTokens) {
754
- if (messages.length === 0) {
755
- return [];
756
- }
757
- const chunks = [];
758
- let currentChunk = [];
759
- let currentTokens = 0;
760
- for (const message of messages) {
761
- const content = extractMessageContent(message);
762
- const messageTokens = estimateMessageTokens(content);
763
- if (currentChunk.length > 0 && currentTokens + messageTokens > maxChunkTokens) {
764
- chunks.push(currentChunk);
765
- currentChunk = [];
766
- currentTokens = 0;
767
- }
768
- currentChunk.push(message);
769
- currentTokens += messageTokens;
770
- if (messageTokens > maxChunkTokens && currentChunk.length === 1) {
771
- chunks.push(currentChunk);
772
- currentChunk = [];
773
- currentTokens = 0;
774
- }
775
- }
776
- if (currentChunk.length > 0) {
777
- chunks.push(currentChunk);
778
- }
779
- return chunks;
780
- }
781
- function extractMessageContent(message) {
782
- if (message.role === "user") {
783
- return typeof message.content === "string" ? message.content : "[complex content]";
784
- } else if (message.role === "assistant") {
785
- return message.content.filter((block) => block.type === "text").map((block) => block.text).join("\n");
786
- }
787
- return "";
788
- }
789
- function formatMessagesForSummary(messages) {
790
- const formatted = [];
791
- for (const msg of messages) {
792
- if (msg.role === "user") {
793
- const content = typeof msg.content === "string" ? msg.content : "[complex]";
794
- const bodyMatch = content.match(/\] (.+)/s);
795
- const body = bodyMatch ? bodyMatch[1] : content;
796
- formatted.push(`User: ${body}`);
797
- } else if (msg.role === "assistant") {
798
- const textBlocks = msg.content.filter((b) => b.type === "text");
799
- if (textBlocks.length > 0) {
800
- const text = textBlocks.map((b) => b.text).join("\n");
801
- formatted.push(`Assistant: ${text}`);
802
- }
803
- const toolCalls = msg.content.filter((b) => b.type === "toolCall");
804
- if (toolCalls.length > 0) {
805
- const toolNames = toolCalls.map((b) => b.name).join(", ");
806
- formatted.push(`[Used tools: ${toolNames}]`);
807
- }
808
- } else if (msg.role === "toolResult") {
809
- formatted.push(`[Tool result: ${msg.toolName}]`);
810
- }
811
- }
812
- return formatted.join("\n\n");
813
- }
814
- function isOversizedForSummary(message, contextWindow) {
815
- const content = extractMessageContent(message);
816
- const tokens = estimateMessageTokens(content);
817
- return tokens > contextWindow * OVERSIZED_MESSAGE_RATIO;
818
- }
819
- function computeAdaptiveChunkRatio(messages, contextWindow) {
820
- const BASE_CHUNK_RATIO = ADAPTIVE_CHUNK_RATIO_BASE;
821
- const MIN_CHUNK_RATIO = ADAPTIVE_CHUNK_RATIO_MIN;
822
- if (messages.length === 0) {
823
- return BASE_CHUNK_RATIO;
824
- }
825
- let totalTokens = 0;
826
- for (const msg of messages) {
827
- const content = extractMessageContent(msg);
828
- totalTokens += estimateMessageTokens(content);
829
- }
830
- const avgTokens = totalTokens / messages.length;
831
- const avgRatio = avgTokens / contextWindow;
832
- if (avgRatio > ADAPTIVE_CHUNK_RATIO_TRIGGER) {
833
- const reduction = Math.min(avgRatio * 2, BASE_CHUNK_RATIO - MIN_CHUNK_RATIO);
834
- return Math.max(MIN_CHUNK_RATIO, BASE_CHUNK_RATIO - reduction);
835
- }
836
- return BASE_CHUNK_RATIO;
837
- }
838
- async function summarizeViaClaude(params) {
839
- const provider = params.provider || "anthropic";
840
- const model = getUtilityModel(provider, params.utilityModel);
841
- const maxTokens = params.maxSummaryTokens ?? DEFAULT_SUMMARY_FALLBACK_TOKENS;
842
- const formatted = formatMessagesForSummary(params.messages);
843
- if (!formatted.trim()) {
844
- return "No conversation content to summarize.";
845
- }
846
- const defaultInstructions = `Summarize this conversation concisely. Focus on:
847
- - Key decisions made
848
- - Action items and TODOs
849
- - Open questions
850
- - Important context and constraints
851
- - Technical details that matter
852
-
853
- Be specific but concise. Preserve critical information.`;
854
- const instructions = params.customInstructions ? `${defaultInstructions}
855
-
856
- Additional focus:
857
- ${params.customInstructions}` : defaultInstructions;
858
- try {
859
- const context = {
860
- messages: [
861
- {
862
- role: "user",
863
- content: `${instructions}
864
-
865
- Conversation:
866
- ${formatted}`,
867
- timestamp: Date.now()
868
- }
869
- ]
870
- };
871
- const response = await complete(model, context, {
872
- apiKey: params.apiKey,
873
- maxTokens
874
- });
875
- const textContent = response.content.find((block) => block.type === "text");
876
- const summary = textContent?.type === "text" ? textContent.text : "";
877
- return summary.trim() || "Unable to generate summary.";
878
- } catch (error) {
879
- log3.error({ err: error }, "Summarization error");
880
- throw new Error(`Summarization failed: ${getErrorMessage(error)}`);
881
- }
882
- }
883
- async function summarizeInChunks(params) {
884
- if (params.messages.length === 0) {
885
- return {
886
- summary: "No messages to summarize.",
887
- tokensUsed: 0,
888
- chunksProcessed: 0
889
- };
890
- }
891
- const chunks = splitMessagesByTokens(params.messages, params.maxChunkTokens);
892
- log3.info(`Splitting into ${chunks.length} chunks for summarization`);
893
- if (chunks.length === 1) {
894
- const summary = await summarizeViaClaude({
895
- messages: chunks[0],
896
- apiKey: params.apiKey,
897
- maxSummaryTokens: params.maxSummaryTokens,
898
- customInstructions: params.customInstructions,
899
- provider: params.provider,
900
- utilityModel: params.utilityModel
901
- });
902
- return {
903
- summary,
904
- tokensUsed: estimateMessageTokens(summary),
905
- chunksProcessed: 1
906
- };
907
- }
908
- const partialSummaries = [];
909
- for (let i = 0; i < chunks.length; i++) {
910
- log3.info(`Summarizing chunk ${i + 1}/${chunks.length} (${chunks[i].length} messages)`);
911
- const partial = await summarizeViaClaude({
912
- messages: chunks[i],
913
- apiKey: params.apiKey,
914
- maxSummaryTokens: Math.floor(
915
- (params.maxSummaryTokens ?? DEFAULT_SUMMARY_FALLBACK_TOKENS) / 2
916
- ),
917
- customInstructions: params.customInstructions,
918
- provider: params.provider,
919
- utilityModel: params.utilityModel
920
- });
921
- partialSummaries.push(partial);
922
- }
923
- log3.info(`Merging ${partialSummaries.length} partial summaries`);
924
- const provider = params.provider || "anthropic";
925
- const model = getUtilityModel(provider, params.utilityModel);
926
- const mergeContext = {
927
- messages: [
928
- {
929
- role: "user",
930
- content: `Merge these partial conversation summaries into one cohesive summary.
931
- Preserve all key decisions, action items, open questions, and important context.
932
- Do not add new information - only synthesize what's provided.
933
-
934
- Partial summaries:
935
-
936
- ${partialSummaries.map((s, i) => `Part ${i + 1}:
937
- ${s}`).join("\n\n---\n\n")}`,
938
- timestamp: Date.now()
939
- }
940
- ]
941
- };
942
- const mergeResponse = await complete(model, mergeContext, {
943
- apiKey: params.apiKey,
944
- maxTokens: params.maxSummaryTokens ?? DEFAULT_SUMMARY_FALLBACK_TOKENS
945
- });
946
- const textContent = mergeResponse.content.find((block) => block.type === "text");
947
- const merged = textContent?.type === "text" ? textContent.text : "";
948
- return {
949
- summary: merged.trim() || "Unable to merge summaries.",
950
- tokensUsed: estimateMessageTokens(merged),
951
- chunksProcessed: chunks.length
952
- };
953
- }
954
- async function summarizeWithFallback(params) {
955
- if (params.messages.length === 0) {
956
- return {
957
- summary: "No messages to summarize.",
958
- tokensUsed: 0,
959
- chunksProcessed: 0
960
- };
961
- }
962
- const chunkRatio = computeAdaptiveChunkRatio(params.messages, params.contextWindow);
963
- const maxChunkTokens = Math.floor(params.contextWindow * chunkRatio);
964
- log3.info(
965
- `AI Summarization: ${params.messages.length} messages, chunk ratio: ${(chunkRatio * 100).toFixed(0)}%`
966
- );
967
- try {
968
- return await summarizeInChunks({
969
- messages: params.messages,
970
- apiKey: params.apiKey,
971
- maxChunkTokens,
972
- maxSummaryTokens: params.maxSummaryTokens,
973
- customInstructions: params.customInstructions,
974
- provider: params.provider,
975
- utilityModel: params.utilityModel
976
- });
977
- } catch (fullError) {
978
- log3.warn(
979
- `Full summarization failed: ${fullError instanceof Error ? fullError.message : String(fullError)}`
980
- );
981
- }
982
- const smallMessages = [];
983
- const oversizedNotes = [];
984
- for (const msg of params.messages) {
985
- if (isOversizedForSummary(msg, params.contextWindow)) {
986
- const content = extractMessageContent(msg);
987
- const tokens = estimateMessageTokens(content);
988
- oversizedNotes.push(
989
- `[Large ${msg.role} message (~${Math.round(tokens / 1e3)}K tokens) omitted from summary]`
990
- );
991
- } else {
992
- smallMessages.push(msg);
993
- }
994
- }
995
- log3.info(
996
- `Fallback: Processing ${smallMessages.length} messages, skipping ${oversizedNotes.length} oversized`
997
- );
998
- if (smallMessages.length > 0) {
999
- try {
1000
- const result = await summarizeInChunks({
1001
- messages: smallMessages,
1002
- apiKey: params.apiKey,
1003
- maxChunkTokens,
1004
- maxSummaryTokens: params.maxSummaryTokens,
1005
- customInstructions: params.customInstructions,
1006
- provider: params.provider,
1007
- utilityModel: params.utilityModel
1008
- });
1009
- const notes = oversizedNotes.length > 0 ? `
1010
-
1011
- ${oversizedNotes.join("\n")}` : "";
1012
- return {
1013
- summary: result.summary + notes,
1014
- tokensUsed: result.tokensUsed,
1015
- chunksProcessed: result.chunksProcessed
1016
- };
1017
- } catch (partialError) {
1018
- log3.warn(
1019
- `Partial summarization also failed: ${partialError instanceof Error ? partialError.message : String(partialError)}`
1020
- );
1021
- }
1022
- }
1023
- const note = `Context contained ${params.messages.length} messages (${oversizedNotes.length} were oversized). AI summarization unavailable due to size constraints. Recent conversation history was preserved.`;
1024
- return {
1025
- summary: note,
1026
- tokensUsed: estimateMessageTokens(note),
1027
- chunksProcessed: 0
1028
- };
1029
- }
1030
-
1031
- // src/session/memory-hook.ts
1032
- import { writeFile, mkdir } from "fs/promises";
1033
- import { join as join3 } from "path";
1034
- import { complete as complete2 } from "@mariozechner/pi-ai";
1035
- var log4 = createLogger("Session");
1036
- async function generateSlugViaClaude(params) {
1037
- const provider = params.provider || "anthropic";
1038
- const model = getUtilityModel(provider, params.utilityModel);
1039
- const formatted = formatMessagesForSummary(params.messages.slice(-SESSION_SLUG_RECENT_MESSAGES));
1040
- if (!formatted.trim()) {
1041
- return "empty-session";
1042
- }
1043
- try {
1044
- const context = {
1045
- messages: [
1046
- {
1047
- role: "user",
1048
- content: `Generate a short, descriptive slug (2-4 words, kebab-case) for this conversation.
1049
- Examples: "gift-transfer-fix", "context-overflow-debug", "telegram-integration"
1050
-
1051
- Conversation:
1052
- ${formatted}
1053
-
1054
- Slug:`,
1055
- timestamp: Date.now()
1056
- }
1057
- ]
1058
- };
1059
- const response = await complete2(model, context, {
1060
- apiKey: params.apiKey,
1061
- maxTokens: SESSION_SLUG_MAX_TOKENS
1062
- });
1063
- const textContent = response.content.find((block) => block.type === "text");
1064
- const slug = textContent?.type === "text" ? textContent.text.trim() : "";
1065
- return slug.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").slice(0, 50) || "session";
1066
- } catch (error) {
1067
- log4.warn({ err: error }, "Slug generation failed, using fallback");
1068
- const now = /* @__PURE__ */ new Date();
1069
- return `session-${now.getHours().toString().padStart(2, "0")}${now.getMinutes().toString().padStart(2, "0")}`;
1070
- }
1071
- }
1072
- async function saveSessionMemory(params) {
1073
- try {
1074
- const { TELETON_ROOT: TELETON_ROOT2 } = await import("./paths-XA2RJH4S.js");
1075
- const memoryDir = join3(TELETON_ROOT2, "memory");
1076
- await mkdir(memoryDir, { recursive: true });
1077
- const now = /* @__PURE__ */ new Date();
1078
- const dateStr = now.toISOString().split("T")[0];
1079
- log4.info("Generating semantic slug for session memory...");
1080
- const slug = await generateSlugViaClaude({
1081
- messages: params.context.messages,
1082
- apiKey: params.apiKey,
1083
- provider: params.provider,
1084
- utilityModel: params.utilityModel
1085
- });
1086
- const filename = `${dateStr}-${slug}.md`;
1087
- const filepath = join3(memoryDir, filename);
1088
- const timeStr = now.toISOString().split("T")[1].split(".")[0];
1089
- log4.info("Generating session summary...");
1090
- let summary;
1091
- try {
1092
- summary = await summarizeViaClaude({
1093
- messages: params.context.messages,
1094
- apiKey: params.apiKey,
1095
- maxSummaryTokens: DEFAULT_MAX_SUMMARY_TOKENS,
1096
- customInstructions: "Summarize this session comprehensively. Include key topics, decisions made, problems solved, and important context.",
1097
- provider: params.provider,
1098
- utilityModel: params.utilityModel
1099
- });
1100
- } catch (error) {
1101
- log4.warn({ err: error }, "Session summary generation failed");
1102
- summary = `Session contained ${params.context.messages.length} messages. Summary generation failed.`;
1103
- }
1104
- const content = `# Session Memory: ${dateStr} ${timeStr} UTC
1105
-
1106
- ## Metadata
1107
-
1108
- - **Old Session ID**: \`${params.oldSessionId}\`
1109
- - **New Session ID**: \`${params.newSessionId}\`
1110
- - **Chat ID**: \`${params.chatId}\`
1111
- - **Timestamp**: ${now.toISOString()}
1112
- - **Message Count**: ${params.context.messages.length}
1113
-
1114
- ## Session Summary
1115
-
1116
- ${summary}
1117
-
1118
- ## Context
1119
-
1120
- This session was compacted and migrated to a new session ID. The summary above preserves key information for continuity.
1121
-
1122
- ---
1123
-
1124
- *Generated automatically by Teleton-AI session memory hook*
1125
- `;
1126
- await writeFile(filepath, content, "utf-8");
1127
- const relPath = filepath.replace(TELETON_ROOT2, "~/.teleton");
1128
- log4.info(`Session memory saved: ${relPath}`);
1129
- } catch (error) {
1130
- log4.error({ err: error }, "Failed to save session memory");
1131
- }
1132
- }
1133
-
1134
- // src/memory/compaction.ts
1135
752
  var DEFAULT_COMPACTION_CONFIG = {
1136
753
  enabled: true,
1137
754
  maxMessages: COMPACTION_MAX_MESSAGES,
@@ -1140,7 +757,7 @@ var DEFAULT_COMPACTION_CONFIG = {
1140
757
  memoryFlushEnabled: true,
1141
758
  softThresholdTokens: DEFAULT_SOFT_THRESHOLD_TOKENS
1142
759
  };
1143
- var log5 = createLogger("Memory");
760
+ var log3 = createLogger("Memory");
1144
761
  function estimateContextTokens(context) {
1145
762
  let charCount = 0;
1146
763
  if (context.systemPrompt) {
@@ -1172,7 +789,7 @@ function shouldFlushMemory(context, config, tokenCount) {
1172
789
  const tokens = tokenCount ?? estimateContextTokens(context);
1173
790
  const softThreshold = config.softThresholdTokens ?? FALLBACK_SOFT_THRESHOLD_TOKENS;
1174
791
  if (tokens >= softThreshold) {
1175
- log5.info(`Memory flush needed: ~${tokens} tokens (soft threshold: ${softThreshold})`);
792
+ log3.info(`Memory flush needed: ~${tokens} tokens (soft threshold: ${softThreshold})`);
1176
793
  return true;
1177
794
  }
1178
795
  return false;
@@ -1194,7 +811,7 @@ function flushMemoryToDailyLog(context) {
1194
811
  }
1195
812
  }
1196
813
  writeSummaryToDailyLog(summary.join("\n"));
1197
- log5.info(`Memory flushed to daily log`);
814
+ log3.info(`Memory flushed to daily log`);
1198
815
  }
1199
816
  function shouldCompact(context, config, tokenCount) {
1200
817
  if (!config.enabled) {
@@ -1202,13 +819,13 @@ function shouldCompact(context, config, tokenCount) {
1202
819
  }
1203
820
  const messageCount = context.messages.length;
1204
821
  if (config.maxMessages && messageCount >= config.maxMessages) {
1205
- log5.info(`Compaction needed: ${messageCount} messages (max: ${config.maxMessages})`);
822
+ log3.info(`Compaction needed: ${messageCount} messages (max: ${config.maxMessages})`);
1206
823
  return true;
1207
824
  }
1208
825
  if (config.maxTokens) {
1209
826
  const tokens = tokenCount ?? estimateContextTokens(context);
1210
827
  if (tokens >= config.maxTokens) {
1211
- log5.info(`Compaction needed: ~${tokens} tokens (max: ${config.maxTokens})`);
828
+ log3.info(`Compaction needed: ~${tokens} tokens (max: ${config.maxTokens})`);
1212
829
  return true;
1213
830
  }
1214
831
  }
@@ -1254,12 +871,12 @@ async function compactContext(context, config, apiKey, provider, utilityModel) {
1254
871
  iterations++;
1255
872
  }
1256
873
  if (hasOrphanedToolResults(context.messages.slice(cutIndex))) {
1257
- log5.warn(`Compaction: couldn't find clean cut point, keeping all messages`);
874
+ log3.warn(`Compaction: couldn't find clean cut point, keeping all messages`);
1258
875
  return context;
1259
876
  }
1260
877
  const recentMessages = context.messages.slice(cutIndex);
1261
878
  const oldMessages = context.messages.slice(0, cutIndex);
1262
- log5.info(
879
+ log3.info(
1263
880
  `Compacting ${oldMessages.length} old messages, keeping ${recentMessages.length} recent (cut at clean boundary)`
1264
881
  );
1265
882
  try {
@@ -1289,7 +906,7 @@ Keep each section concise. Omit a section if empty. Preserve specific names, num
1289
906
  provider,
1290
907
  utilityModel
1291
908
  });
1292
- log5.info(`AI Summary: ${result.tokensUsed} tokens, ${result.chunksProcessed} chunks processed`);
909
+ log3.info(`AI Summary: ${result.tokensUsed} tokens, ${result.chunksProcessed} chunks processed`);
1293
910
  const summaryText = `[Auto-compacted ${oldMessages.length} messages]
1294
911
 
1295
912
  ${result.summary}`;
@@ -1303,7 +920,7 @@ ${result.summary}`;
1303
920
  messages: [summaryMessage, ...recentMessages]
1304
921
  };
1305
922
  } catch (error) {
1306
- log5.error({ err: error }, "AI summarization failed, using fallback");
923
+ log3.error({ err: error }, "AI summarization failed, using fallback");
1307
924
  const summaryText = `[Auto-compacted: ${oldMessages.length} earlier messages from this conversation]`;
1308
925
  const summaryMessage = {
1309
926
  role: "user",
@@ -1318,7 +935,7 @@ ${result.summary}`;
1318
935
  }
1319
936
  async function compactAndSaveTranscript(sessionId, context, config, apiKey, chatId, provider, utilityModel) {
1320
937
  const newSessionId = randomUUID();
1321
- log5.info(`Creating compacted transcript: ${sessionId} \u2192 ${newSessionId}`);
938
+ log3.info(`Creating compacted transcript: ${sessionId} \u2192 ${newSessionId}`);
1322
939
  if (chatId) {
1323
940
  await saveSessionMemory({
1324
941
  oldSessionId: sessionId,
@@ -1352,7 +969,7 @@ var CompactionManager = class {
1352
969
  if (this.config.memoryFlushEnabled) {
1353
970
  flushMemoryToDailyLog(context);
1354
971
  }
1355
- log5.info(`Auto-compacting session ${sessionId}`);
972
+ log3.info(`Auto-compacting session ${sessionId}`);
1356
973
  const newSessionId = await compactAndSaveTranscript(
1357
974
  sessionId,
1358
975
  context,
@@ -1362,7 +979,7 @@ var CompactionManager = class {
1362
979
  provider,
1363
980
  utilityModel
1364
981
  );
1365
- log5.info(`Compaction complete: ${newSessionId}`);
982
+ log3.info(`Compaction complete: ${newSessionId}`);
1366
983
  return newSessionId;
1367
984
  }
1368
985
  updateConfig(config) {
@@ -1494,7 +1111,7 @@ function maskOldToolResults(messages, options) {
1494
1111
  }
1495
1112
 
1496
1113
  // src/agent/runtime.ts
1497
- var log6 = createLogger("Agent");
1114
+ var log4 = createLogger("Agent");
1498
1115
  var globalTokenUsage = { totalTokens: 0, totalCost: 0 };
1499
1116
  function getTokenUsage() {
1500
1117
  return { ...globalTokenUsage };
@@ -1607,7 +1224,7 @@ var AgentRuntime = class {
1607
1224
  if (this.userHookEvaluator) {
1608
1225
  const hookResult = this.userHookEvaluator.evaluate(userMessage);
1609
1226
  if (hookResult.blocked) {
1610
- log6.info("Message blocked by keyword filter");
1227
+ log4.info("Message blocked by keyword filter");
1611
1228
  return { content: hookResult.blockMessage ?? "", toolCalls: [] };
1612
1229
  }
1613
1230
  if (hookResult.additionalContext) {
@@ -1633,7 +1250,7 @@ var AgentRuntime = class {
1633
1250
  };
1634
1251
  await this.hookRunner.runModifyingHook("message:receive", msgEvent);
1635
1252
  if (msgEvent.block) {
1636
- log6.info(`\u{1F6AB} Message blocked by hook: ${msgEvent.blockReason || "no reason"}`);
1253
+ log4.info(`\u{1F6AB} Message blocked by hook: ${msgEvent.blockReason || "no reason"}`);
1637
1254
  return { content: "", toolCalls: [] };
1638
1255
  }
1639
1256
  effectiveMessage = sanitizeForContext(msgEvent.text);
@@ -1645,7 +1262,7 @@ var AgentRuntime = class {
1645
1262
  const now = timestamp ?? Date.now();
1646
1263
  const resetPolicy = this.config.agent.session_reset_policy;
1647
1264
  if (shouldResetSession(session, resetPolicy)) {
1648
- log6.info(`\u{1F504} Auto-resetting session based on policy`);
1265
+ log4.info(`\u{1F504} Auto-resetting session based on policy`);
1649
1266
  if (this.hookRunner) {
1650
1267
  await this.hookRunner.runObservingHook("session:end", {
1651
1268
  sessionId: session.sessionId,
@@ -1655,7 +1272,7 @@ var AgentRuntime = class {
1655
1272
  }
1656
1273
  if (transcriptExists(session.sessionId)) {
1657
1274
  try {
1658
- log6.info(`\u{1F4BE} Saving memory before daily reset...`);
1275
+ log4.info(`\u{1F4BE} Saving memory before daily reset...`);
1659
1276
  const oldContext = loadContextFromTranscript(session.sessionId);
1660
1277
  await saveSessionMemory({
1661
1278
  oldSessionId: session.sessionId,
@@ -1666,9 +1283,9 @@ var AgentRuntime = class {
1666
1283
  provider: this.config.agent.provider,
1667
1284
  utilityModel: this.config.agent.utility_model
1668
1285
  });
1669
- log6.info(`\u2705 Memory saved before reset`);
1286
+ log4.info(`\u2705 Memory saved before reset`);
1670
1287
  } catch (error) {
1671
- log6.warn({ err: error }, `\u26A0\uFE0F Failed to save memory before reset`);
1288
+ log4.warn({ err: error }, `\u26A0\uFE0F Failed to save memory before reset`);
1672
1289
  }
1673
1290
  }
1674
1291
  session = resetSessionWithPolicy(chatId, resetPolicy);
@@ -1676,9 +1293,9 @@ var AgentRuntime = class {
1676
1293
  let context = loadContextFromTranscript(session.sessionId);
1677
1294
  const isNewSession = context.messages.length === 0;
1678
1295
  if (!isNewSession) {
1679
- log6.info(`\u{1F4D6} Loading existing session: ${session.sessionId}`);
1296
+ log4.info(`\u{1F4D6} Loading existing session: ${session.sessionId}`);
1680
1297
  } else {
1681
- log6.info(`\u{1F195} Starting new session: ${session.sessionId}`);
1298
+ log4.info(`\u{1F195} Starting new session: ${session.sessionId}`);
1682
1299
  }
1683
1300
  if (this.hookRunner) {
1684
1301
  await this.hookRunner.runObservingHook("session:start", {
@@ -1707,21 +1324,32 @@ var AgentRuntime = class {
1707
1324
  formattedMessage = `${pendingContext}
1708
1325
 
1709
1326
  ${formattedMessage}`;
1710
- log6.debug(`\u{1F4CB} Including ${pendingContext.split("\n").length - 1} pending messages`);
1327
+ log4.debug(`\u{1F4CB} Including ${pendingContext.split("\n").length - 1} pending messages`);
1711
1328
  }
1712
- log6.debug(`\u{1F4E8} Formatted message: ${formattedMessage.substring(0, 100)}...`);
1329
+ log4.debug(`\u{1F4E8} Formatted message: ${formattedMessage.substring(0, 100)}...`);
1713
1330
  const preview = formattedMessage.slice(0, 50).replace(/\n/g, " ");
1714
1331
  const who = senderUsername ? `@${senderUsername}` : userName;
1715
1332
  const msgType = isGroup ? `Group ${chatId} ${who}` : `DM ${who}`;
1716
- log6.info(`\u{1F4E8} ${msgType}: "${preview}${formattedMessage.length > 50 ? "..." : ""}"`);
1333
+ log4.info(`\u{1F4E8} ${msgType}: "${preview}${formattedMessage.length > 50 ? "..." : ""}"`);
1717
1334
  let relevantContext = "";
1718
1335
  let queryEmbedding;
1719
1336
  const isNonTrivial = !isTrivialMessage(effectiveMessage);
1720
1337
  if (this.embedder && isNonTrivial) {
1721
1338
  try {
1722
- queryEmbedding = await this.embedder.embedQuery(effectiveMessage);
1339
+ let searchQuery = effectiveMessage;
1340
+ const recentUserMsgs = context.messages.filter((m) => m.role === "user" && typeof m.content === "string").slice(-3).map((m) => {
1341
+ const text = m.content;
1342
+ const bodyMatch = text.match(/\] (.+)/s);
1343
+ return (bodyMatch ? bodyMatch[1] : text).trim();
1344
+ }).filter((t) => t.length > 0);
1345
+ if (recentUserMsgs.length > 0) {
1346
+ searchQuery = recentUserMsgs.join(" ") + " " + effectiveMessage;
1347
+ }
1348
+ queryEmbedding = await this.embedder.embedQuery(
1349
+ searchQuery.slice(0, EMBEDDING_QUERY_MAX_CHARS)
1350
+ );
1723
1351
  } catch (error) {
1724
- log6.warn({ err: error }, "Embedding computation failed");
1352
+ log4.warn({ err: error }, "Embedding computation failed");
1725
1353
  }
1726
1354
  }
1727
1355
  if (this.contextBuilder && isNonTrivial) {
@@ -1755,12 +1383,12 @@ ${sanitizedFeed.join("\n")}`
1755
1383
  }
1756
1384
  if (contextParts.length > 0) {
1757
1385
  relevantContext = contextParts.join("\n\n");
1758
- log6.debug(
1386
+ log4.debug(
1759
1387
  `\u{1F50D} Found ${dbContext.relevantKnowledge.length} knowledge chunks, ${dbContext.relevantFeed.length} feed messages`
1760
1388
  );
1761
1389
  }
1762
1390
  } catch (error) {
1763
- log6.warn({ err: error }, "Context building failed");
1391
+ log4.warn({ err: error }, "Context building failed");
1764
1392
  }
1765
1393
  }
1766
1394
  const memoryStats = this.getMemoryStats();
@@ -1828,7 +1456,7 @@ ${allHookContext}` : "");
1828
1456
  this.config.agent.utility_model
1829
1457
  );
1830
1458
  if (preemptiveCompaction) {
1831
- log6.info(`\u{1F5DC}\uFE0F Preemptive compaction triggered, reloading session...`);
1459
+ log4.info(`\u{1F5DC}\uFE0F Preemptive compaction triggered, reloading session...`);
1832
1460
  session = getSession(chatId);
1833
1461
  context = loadContextFromTranscript(session.sessionId);
1834
1462
  context.messages.push(userMsg);
@@ -1850,7 +1478,7 @@ ${allHookContext}` : "");
1850
1478
  chatId,
1851
1479
  isAdmin
1852
1480
  );
1853
- log6.info(`\u{1F50D} Tool RAG: ${tools.length}/${this.toolRegistry.count} tools selected`);
1481
+ log4.info(`\u{1F50D} Tool RAG: ${tools.length}/${this.toolRegistry.count} tools selected`);
1854
1482
  } else {
1855
1483
  tools = this.toolRegistry?.getForContext(
1856
1484
  effectiveIsGroup,
@@ -1869,9 +1497,10 @@ ${allHookContext}` : "");
1869
1497
  const totalToolCalls = [];
1870
1498
  const accumulatedTexts = [];
1871
1499
  const accumulatedUsage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalCost: 0 };
1500
+ const seenToolSignatures = /* @__PURE__ */ new Set();
1872
1501
  while (iteration < maxIterations) {
1873
1502
  iteration++;
1874
- log6.debug(`\u{1F504} Agentic iteration ${iteration}/${maxIterations}`);
1503
+ log4.debug(`\u{1F504} Agentic iteration ${iteration}/${maxIterations}`);
1875
1504
  const iterationStartIndex = context.messages.length;
1876
1505
  const maskedMessages = maskOldToolResults(context.messages, {
1877
1506
  toolRegistry: this.toolRegistry ?? void 0,
@@ -1910,35 +1539,35 @@ ${allHookContext}` : "");
1910
1539
  "Context overflow persists after session reset. Message may be too large for the model's context window."
1911
1540
  );
1912
1541
  }
1913
- log6.error(`\u{1F6A8} Context overflow detected: ${errorMsg}`);
1914
- log6.info(`\u{1F4BE} Saving session memory before reset...`);
1542
+ log4.error(`\u{1F6A8} Context overflow detected: ${errorMsg}`);
1543
+ log4.info(`\u{1F4BE} Saving session memory before reset...`);
1915
1544
  const summary = extractContextSummary(context, CONTEXT_OVERFLOW_SUMMARY_MESSAGES);
1916
1545
  appendToDailyLog(summary);
1917
- log6.info(`\u2705 Memory saved to daily log`);
1546
+ log4.info(`\u2705 Memory saved to daily log`);
1918
1547
  const archived = archiveTranscript(session.sessionId);
1919
1548
  if (!archived) {
1920
- log6.error(
1549
+ log4.error(
1921
1550
  `\u26A0\uFE0F Failed to archive transcript ${session.sessionId}, proceeding with reset anyway`
1922
1551
  );
1923
1552
  }
1924
- log6.info(`\u{1F504} Resetting session due to context overflow...`);
1553
+ log4.info(`\u{1F504} Resetting session due to context overflow...`);
1925
1554
  session = resetSession(chatId);
1926
1555
  context = { messages: [userMsg] };
1927
1556
  appendToTranscript(session.sessionId, userMsg);
1928
- log6.info(`\u{1F504} Retrying with fresh context...`);
1557
+ log4.info(`\u{1F504} Retrying with fresh context...`);
1929
1558
  continue;
1930
1559
  } else if (errorMsg.toLowerCase().includes("rate") || errorMsg.includes("429")) {
1931
1560
  rateLimitRetries++;
1932
1561
  if (rateLimitRetries <= RATE_LIMIT_MAX_RETRIES) {
1933
1562
  const delay = 1e3 * Math.pow(2, rateLimitRetries - 1);
1934
- log6.warn(
1563
+ log4.warn(
1935
1564
  `\u{1F6AB} Rate limited, retrying in ${delay}ms (attempt ${rateLimitRetries}/${RATE_LIMIT_MAX_RETRIES})...`
1936
1565
  );
1937
1566
  await new Promise((r3) => setTimeout(r3, delay));
1938
1567
  iteration--;
1939
1568
  continue;
1940
1569
  }
1941
- log6.error(`\u{1F6AB} Rate limited after ${RATE_LIMIT_MAX_RETRIES} retries: ${errorMsg}`);
1570
+ log4.error(`\u{1F6AB} Rate limited after ${RATE_LIMIT_MAX_RETRIES} retries: ${errorMsg}`);
1942
1571
  throw new Error(
1943
1572
  `API rate limited after ${RATE_LIMIT_MAX_RETRIES} retries. Please try again later.`
1944
1573
  );
@@ -1946,19 +1575,19 @@ ${allHookContext}` : "");
1946
1575
  serverErrorRetries++;
1947
1576
  if (serverErrorRetries <= SERVER_ERROR_MAX_RETRIES) {
1948
1577
  const delay = 2e3 * Math.pow(2, serverErrorRetries - 1);
1949
- log6.warn(
1578
+ log4.warn(
1950
1579
  `\u{1F504} Server error, retrying in ${delay}ms (attempt ${serverErrorRetries}/${SERVER_ERROR_MAX_RETRIES})...`
1951
1580
  );
1952
1581
  await new Promise((r3) => setTimeout(r3, delay));
1953
1582
  iteration--;
1954
1583
  continue;
1955
1584
  }
1956
- log6.error(`\u{1F6A8} Server error after ${SERVER_ERROR_MAX_RETRIES} retries: ${errorMsg}`);
1585
+ log4.error(`\u{1F6A8} Server error after ${SERVER_ERROR_MAX_RETRIES} retries: ${errorMsg}`);
1957
1586
  throw new Error(
1958
1587
  `API server error after ${SERVER_ERROR_MAX_RETRIES} retries. The provider may be experiencing issues.`
1959
1588
  );
1960
1589
  } else {
1961
- log6.error(`\u{1F6A8} API error: ${errorMsg}`);
1590
+ log4.error(`\u{1F6A8} API error: ${errorMsg}`);
1962
1591
  throw new Error(`API error: ${errorMsg || "Unknown error"}`);
1963
1592
  }
1964
1593
  }
@@ -1975,24 +1604,25 @@ ${allHookContext}` : "");
1975
1604
  }
1976
1605
  const toolCalls = response2.message.content.filter((block) => block.type === "toolCall");
1977
1606
  if (toolCalls.length === 0) {
1978
- log6.info(`\u{1F504} ${iteration}/${maxIterations} \u2192 done`);
1607
+ log4.info(`\u{1F504} ${iteration}/${maxIterations} \u2192 done`);
1979
1608
  finalResponse = response2;
1980
1609
  break;
1981
1610
  }
1982
1611
  if (!this.toolRegistry || !toolContext) {
1983
- log6.error("\u26A0\uFE0F Cannot execute tools: registry or context missing");
1612
+ log4.error("\u26A0\uFE0F Cannot execute tools: registry or context missing");
1984
1613
  break;
1985
1614
  }
1986
- log6.debug(`\u{1F527} Executing ${toolCalls.length} tool call(s)`);
1615
+ log4.debug(`\u{1F527} Executing ${toolCalls.length} tool call(s)`);
1987
1616
  context.messages.push(response2.message);
1988
1617
  const iterationToolNames = [];
1618
+ const fullContext = {
1619
+ ...toolContext,
1620
+ chatId,
1621
+ isGroup: effectiveIsGroup
1622
+ };
1623
+ const toolPlans = [];
1989
1624
  for (const block of toolCalls) {
1990
1625
  if (block.type !== "toolCall") continue;
1991
- const fullContext = {
1992
- ...toolContext,
1993
- chatId,
1994
- isGroup: effectiveIsGroup
1995
- };
1996
1626
  let toolParams = block.arguments ?? {};
1997
1627
  let blocked = false;
1998
1628
  let blockReason = "";
@@ -2013,74 +1643,88 @@ ${allHookContext}` : "");
2013
1643
  toolParams = structuredClone(beforeEvent.params);
2014
1644
  }
2015
1645
  }
2016
- let result;
2017
- if (blocked) {
2018
- result = { success: false, error: blockReason };
2019
- if (this.hookRunner) {
2020
- const afterEvent = {
2021
- toolName: block.name,
2022
- params: structuredClone(toolParams),
2023
- result: { success: false, error: blockReason },
2024
- durationMs: 0,
2025
- chatId,
2026
- isGroup: effectiveIsGroup,
2027
- blocked: true,
2028
- blockReason
2029
- };
2030
- await this.hookRunner.runObservingHook("tool:after", afterEvent);
2031
- }
2032
- } else {
2033
- const startTime = Date.now();
2034
- try {
2035
- result = await this.toolRegistry.execute(
2036
- { ...block, arguments: toolParams },
2037
- fullContext
2038
- );
2039
- } catch (execErr) {
2040
- const durationMs2 = Date.now() - startTime;
2041
- const errMsg = execErr instanceof Error ? execErr.message : String(execErr);
2042
- const errStack = execErr instanceof Error ? execErr.stack : void 0;
2043
- result = { success: false, error: errMsg };
2044
- if (this.hookRunner) {
2045
- const errorEvent = {
2046
- toolName: block.name,
2047
- params: structuredClone(toolParams),
2048
- error: errMsg,
2049
- // Note: stack traces are exposed to plugins for debugging — accepted tradeoff
2050
- stack: errStack,
2051
- chatId,
2052
- isGroup: effectiveIsGroup,
2053
- durationMs: durationMs2
1646
+ toolPlans.push({ block, blocked, blockReason, params: toolParams });
1647
+ }
1648
+ const execResults = new Array(toolPlans.length);
1649
+ {
1650
+ let cursor = 0;
1651
+ const runWorker = async () => {
1652
+ while (cursor < toolPlans.length) {
1653
+ const idx = cursor++;
1654
+ const plan = toolPlans[idx];
1655
+ if (plan.blocked) {
1656
+ execResults[idx] = {
1657
+ result: { success: false, error: plan.blockReason },
1658
+ durationMs: 0
1659
+ };
1660
+ continue;
1661
+ }
1662
+ const startTime = Date.now();
1663
+ try {
1664
+ const result = await this.toolRegistry.execute(
1665
+ { ...plan.block, arguments: plan.params },
1666
+ fullContext
1667
+ );
1668
+ execResults[idx] = { result, durationMs: Date.now() - startTime };
1669
+ } catch (execErr) {
1670
+ const errMsg = execErr instanceof Error ? execErr.message : String(execErr);
1671
+ const errStack = execErr instanceof Error ? execErr.stack : void 0;
1672
+ execResults[idx] = {
1673
+ result: { success: false, error: errMsg },
1674
+ durationMs: Date.now() - startTime,
1675
+ execError: { message: errMsg, stack: errStack }
2054
1676
  };
2055
- await this.hookRunner.runObservingHook("tool:error", errorEvent);
2056
1677
  }
2057
1678
  }
2058
- const durationMs = Date.now() - startTime;
2059
- if (this.hookRunner) {
2060
- const afterEvent = {
2061
- toolName: block.name,
2062
- params: structuredClone(toolParams),
2063
- result: { success: result.success, data: result.data, error: result.error },
2064
- durationMs,
2065
- chatId,
2066
- isGroup: effectiveIsGroup
2067
- };
2068
- await this.hookRunner.runObservingHook("tool:after", afterEvent);
2069
- }
1679
+ };
1680
+ const workers = Math.min(TOOL_CONCURRENCY_LIMIT, toolPlans.length);
1681
+ await Promise.all(Array.from({ length: workers }, () => runWorker()));
1682
+ }
1683
+ for (let i = 0; i < toolPlans.length; i++) {
1684
+ const plan = toolPlans[i];
1685
+ const { block } = plan;
1686
+ const exec = execResults[i];
1687
+ if (exec.execError && this.hookRunner) {
1688
+ const errorEvent = {
1689
+ toolName: block.name,
1690
+ params: structuredClone(plan.params),
1691
+ error: exec.execError.message,
1692
+ stack: exec.execError.stack,
1693
+ chatId,
1694
+ isGroup: effectiveIsGroup,
1695
+ durationMs: exec.durationMs
1696
+ };
1697
+ await this.hookRunner.runObservingHook("tool:error", errorEvent);
1698
+ }
1699
+ if (this.hookRunner) {
1700
+ const afterEvent = {
1701
+ toolName: block.name,
1702
+ params: structuredClone(plan.params),
1703
+ result: {
1704
+ success: exec.result.success,
1705
+ data: exec.result.data,
1706
+ error: exec.result.error
1707
+ },
1708
+ durationMs: exec.durationMs,
1709
+ chatId,
1710
+ isGroup: effectiveIsGroup,
1711
+ ...plan.blocked ? { blocked: true, blockReason: plan.blockReason } : {}
1712
+ };
1713
+ await this.hookRunner.runObservingHook("tool:after", afterEvent);
2070
1714
  }
2071
- log6.debug(`${block.name}: ${result.success ? "\u2713" : "\u2717"} ${result.error || ""}`);
2072
- iterationToolNames.push(`${block.name} ${result.success ? "\u2713" : "\u2717"}`);
1715
+ log4.debug(`${block.name}: ${exec.result.success ? "\u2713" : "\u2717"} ${exec.result.error || ""}`);
1716
+ iterationToolNames.push(`${block.name} ${exec.result.success ? "\u2713" : "\u2717"}`);
2073
1717
  totalToolCalls.push({
2074
1718
  name: block.name,
2075
1719
  input: block.arguments
2076
1720
  });
2077
- let resultText = JSON.stringify(result);
1721
+ let resultText = JSON.stringify(exec.result);
2078
1722
  if (resultText.length > MAX_TOOL_RESULT_SIZE) {
2079
- log6.warn(`\u26A0\uFE0F Tool result too large (${resultText.length} chars), truncating...`);
2080
- const data = result.data;
1723
+ log4.warn(`\u26A0\uFE0F Tool result too large (${resultText.length} chars), truncating...`);
1724
+ const data = exec.result.data;
2081
1725
  if (data?.summary || data?.message) {
2082
1726
  resultText = JSON.stringify({
2083
- success: result.success,
1727
+ success: exec.result.success,
2084
1728
  data: {
2085
1729
  summary: data.summary || data.message,
2086
1730
  _truncated: true,
@@ -2089,11 +1733,27 @@ ${allHookContext}` : "");
2089
1733
  }
2090
1734
  });
2091
1735
  } else {
2092
- resultText = resultText.slice(0, MAX_TOOL_RESULT_SIZE) + "\n...[TRUNCATED]";
1736
+ const summarized = {
1737
+ _truncated: true,
1738
+ _originalSize: resultText.length,
1739
+ _message: "Full data truncated. Use limit parameter for smaller results."
1740
+ };
1741
+ if (data && typeof data === "object") {
1742
+ for (const [key, value] of Object.entries(data)) {
1743
+ if (Array.isArray(value)) {
1744
+ summarized[key] = `[${value.length} items]`;
1745
+ } else if (typeof value === "string" && value.length > 500) {
1746
+ summarized[key] = value.slice(0, 500) + "...[truncated]";
1747
+ } else {
1748
+ summarized[key] = value;
1749
+ }
1750
+ }
1751
+ }
1752
+ resultText = JSON.stringify({ success: exec.result.success, data: summarized });
2093
1753
  }
2094
1754
  }
2095
1755
  if (provider === "cocoon") {
2096
- const { wrapToolResult } = await import("./tool-adapter-IH5VGBOO.js");
1756
+ const { wrapToolResult } = await import("./tool-adapter-IVX2XQJE.js");
2097
1757
  const cocoonResultMsg = {
2098
1758
  role: "user",
2099
1759
  content: [
@@ -2117,21 +1777,33 @@ ${allHookContext}` : "");
2117
1777
  text: resultText
2118
1778
  }
2119
1779
  ],
2120
- isError: !result.success,
1780
+ isError: !exec.result.success,
2121
1781
  timestamp: Date.now()
2122
1782
  };
2123
1783
  context.messages.push(toolResultMsg);
2124
1784
  appendToTranscript(session.sessionId, toolResultMsg);
2125
1785
  }
2126
1786
  }
2127
- log6.info(`\u{1F504} ${iteration}/${maxIterations} \u2192 ${iterationToolNames.join(", ")}`);
1787
+ log4.info(`\u{1F504} ${iteration}/${maxIterations} \u2192 ${iterationToolNames.join(", ")}`);
1788
+ const iterSignatures = toolPlans.map(
1789
+ (p2) => `${p2.block.name}:${JSON.stringify(p2.params, Object.keys(p2.params).sort())}`
1790
+ );
1791
+ const allDuplicates = iterSignatures.length > 0 && iterSignatures.every((sig) => seenToolSignatures.has(sig));
1792
+ for (const sig of iterSignatures) seenToolSignatures.add(sig);
1793
+ if (allDuplicates) {
1794
+ log4.warn(
1795
+ `\u{1F501} Loop stall detected: all ${iterSignatures.length} tool call(s) are repeats \u2014 breaking early`
1796
+ );
1797
+ finalResponse = response2;
1798
+ break;
1799
+ }
2128
1800
  if (iteration === maxIterations) {
2129
- log6.info(`\u26A0\uFE0F Max iterations reached (${maxIterations})`);
1801
+ log4.info(`\u26A0\uFE0F Max iterations reached (${maxIterations})`);
2130
1802
  finalResponse = response2;
2131
1803
  }
2132
1804
  }
2133
1805
  if (!finalResponse) {
2134
- log6.error("\u26A0\uFE0F Agentic loop exited early without final response");
1806
+ log4.error("\u26A0\uFE0F Agentic loop exited early without final response");
2135
1807
  return {
2136
1808
  content: "Internal error: Agent loop failed to produce a response.",
2137
1809
  toolCalls: []
@@ -2142,14 +1814,6 @@ ${allHookContext}` : "");
2142
1814
  if (lastMsg?.role !== "assistant") {
2143
1815
  context.messages.push(response.message);
2144
1816
  }
2145
- const newSessionId = await this.compactionManager.checkAndCompact(
2146
- session.sessionId,
2147
- context,
2148
- getEffectiveApiKey(this.config.agent.provider, this.config.agent.api_key),
2149
- chatId,
2150
- this.config.agent.provider,
2151
- this.config.agent.utility_model
2152
- );
2153
1817
  const sessionUpdate = {
2154
1818
  updatedAt: Date.now(),
2155
1819
  messageCount: session.messageCount + 1,
@@ -2158,9 +1822,6 @@ ${allHookContext}` : "");
2158
1822
  inputTokens: (session.inputTokens ?? 0) + accumulatedUsage.input + accumulatedUsage.cacheRead + accumulatedUsage.cacheWrite,
2159
1823
  outputTokens: (session.outputTokens ?? 0) + accumulatedUsage.output
2160
1824
  };
2161
- if (newSessionId) {
2162
- sessionUpdate.sessionId = newSessionId;
2163
- }
2164
1825
  updateSession(chatId, sessionUpdate);
2165
1826
  if (accumulatedUsage.input > 0 || accumulatedUsage.output > 0) {
2166
1827
  const u = accumulatedUsage;
@@ -2170,20 +1831,20 @@ ${allHookContext}` : "");
2170
1831
  if (u.cacheRead) cacheParts.push(`${(u.cacheRead / 1e3).toFixed(1)}K cached`);
2171
1832
  if (u.cacheWrite) cacheParts.push(`${(u.cacheWrite / 1e3).toFixed(1)}K new`);
2172
1833
  const cacheInfo = cacheParts.length > 0 ? ` (${cacheParts.join(", ")})` : "";
2173
- log6.info(`\u{1F4B0} ${inK}K in${cacheInfo}, ${u.output} out | $${u.totalCost.toFixed(3)}`);
1834
+ log4.info(`\u{1F4B0} ${inK}K in${cacheInfo}, ${u.output} out | $${u.totalCost.toFixed(3)}`);
2174
1835
  globalTokenUsage.totalTokens += u.input + u.output + u.cacheRead + u.cacheWrite;
2175
1836
  globalTokenUsage.totalCost += u.totalCost;
2176
1837
  }
2177
1838
  let content = accumulatedTexts.join("\n").trim() || response.text;
2178
1839
  const usedTelegramSendTool = totalToolCalls.some((tc) => TELEGRAM_SEND_TOOLS.has(tc.name));
2179
1840
  if (!content && totalToolCalls.length > 0 && !usedTelegramSendTool) {
2180
- log6.warn("\u26A0\uFE0F Empty response after tool calls - generating fallback");
1841
+ log4.warn("\u26A0\uFE0F Empty response after tool calls - generating fallback");
2181
1842
  content = "I executed the requested action but couldn't generate a response. Please try again.";
2182
1843
  } else if (!content && usedTelegramSendTool) {
2183
- log6.info("\u2705 Response sent via Telegram tool - no additional text needed");
1844
+ log4.info("\u2705 Response sent via Telegram tool - no additional text needed");
2184
1845
  content = "";
2185
1846
  } else if (!content && accumulatedUsage.input === 0 && accumulatedUsage.output === 0) {
2186
- log6.warn("\u26A0\uFE0F Empty response with zero tokens - possible API issue");
1847
+ log4.warn("\u26A0\uFE0F Empty response with zero tokens - possible API issue");
2187
1848
  content = "I couldn't process your request. Please try again.";
2188
1849
  }
2189
1850
  let responseMetadata = {};
@@ -2200,7 +1861,7 @@ ${allHookContext}` : "");
2200
1861
  };
2201
1862
  await this.hookRunner.runModifyingHook("response:before", responseBeforeEvent);
2202
1863
  if (responseBeforeEvent.block) {
2203
- log6.info(
1864
+ log4.info(
2204
1865
  `\u{1F6AB} Response blocked by hook: ${responseBeforeEvent.blockReason || "no reason"}`
2205
1866
  );
2206
1867
  content = "";
@@ -2227,7 +1888,7 @@ ${allHookContext}` : "");
2227
1888
  toolCalls: totalToolCalls
2228
1889
  };
2229
1890
  } catch (error) {
2230
- log6.error({ err: error }, "Agent error");
1891
+ log4.error({ err: error }, "Agent error");
2231
1892
  throw error;
2232
1893
  }
2233
1894
  }
@@ -2240,7 +1901,7 @@ ${allHookContext}` : "");
2240
1901
  ).run(chatId);
2241
1902
  db.prepare(`DELETE FROM tg_messages WHERE chat_id = ?`).run(chatId);
2242
1903
  resetSession(chatId);
2243
- log6.info(`\u{1F5D1}\uFE0F Cleared history for chat ${chatId}`);
1904
+ log4.info(`\u{1F5D1}\uFE0F Cleared history for chat ${chatId}`);
2244
1905
  }
2245
1906
  getConfig() {
2246
1907
  return this.config;
@@ -2261,7 +1922,7 @@ ${allHookContext}` : "");
2261
1922
  }
2262
1923
  configureCompaction(config) {
2263
1924
  this.compactionManager.updateConfig(config);
2264
- log6.info({ config: this.compactionManager.getConfig() }, `\u{1F5DC}\uFE0F Compaction config updated`);
1925
+ log4.info({ config: this.compactionManager.getConfig() }, `\u{1F5DC}\uFE0F Compaction config updated`);
2265
1926
  }
2266
1927
  getCompactionConfig() {
2267
1928
  return this.compactionManager.getConfig();
@@ -2349,6 +2010,17 @@ function prefixButtons(rows, pluginName) {
2349
2010
 
2350
2011
  // src/bot/services/html-parser.ts
2351
2012
  import { Api as Api2 } from "telegram";
2013
+
2014
+ // src/utils/gramjs-bigint.ts
2015
+ import { randomBytes } from "crypto";
2016
+ function toLong(value) {
2017
+ return typeof value === "bigint" ? value : BigInt(value);
2018
+ }
2019
+ function randomLong() {
2020
+ return randomBytes(8).readBigUInt64BE();
2021
+ }
2022
+
2023
+ // src/bot/services/html-parser.ts
2352
2024
  function parseHtml(html) {
2353
2025
  const entities = [];
2354
2026
  let text = "";
@@ -2399,8 +2071,7 @@ function parseHtml(html) {
2399
2071
  new Api2.MessageEntityCustomEmoji({
2400
2072
  offset: open.offset,
2401
2073
  length,
2402
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS BigInteger compat
2403
- documentId: BigInt(open.emojiId)
2074
+ documentId: toLong(open.emojiId)
2404
2075
  })
2405
2076
  );
2406
2077
  }
@@ -2461,7 +2132,7 @@ function unescapeHtml(text) {
2461
2132
  }
2462
2133
 
2463
2134
  // src/bot/inline-router.ts
2464
- var log7 = createLogger("InlineRouter");
2135
+ var log5 = createLogger("InlineRouter");
2465
2136
  var INLINE_TIMEOUT_MS = 5e3;
2466
2137
  var CALLBACK_TIMEOUT_MS = 15e3;
2467
2138
  function compileGlob(pattern) {
@@ -2482,11 +2153,11 @@ var InlineRouter = class {
2482
2153
  }
2483
2154
  registerPlugin(name, handlers) {
2484
2155
  this.plugins.set(name, handlers);
2485
- log7.info(`Registered plugin "${name}" for inline routing`);
2156
+ log5.info(`Registered plugin "${name}" for inline routing`);
2486
2157
  }
2487
2158
  unregisterPlugin(name) {
2488
2159
  this.plugins.delete(name);
2489
- log7.info(`Unregistered plugin "${name}" from inline routing`);
2160
+ log5.info(`Unregistered plugin "${name}" from inline routing`);
2490
2161
  }
2491
2162
  hasPlugin(name) {
2492
2163
  return this.plugins.has(name);
@@ -2558,7 +2229,7 @@ var InlineRouter = class {
2558
2229
  is_personal: true
2559
2230
  });
2560
2231
  } catch (error) {
2561
- log7.error({ err: error }, `Plugin "${pluginName}" inline query handler failed`);
2232
+ log5.error({ err: error }, `Plugin "${pluginName}" inline query handler failed`);
2562
2233
  try {
2563
2234
  await ctx.answerInlineQuery([], { cache_time: 0, is_personal: true });
2564
2235
  } catch {
@@ -2618,7 +2289,7 @@ var InlineRouter = class {
2618
2289
  } catch (error) {
2619
2290
  const errMsg = error?.errorMessage;
2620
2291
  if (errMsg === "MESSAGE_NOT_MODIFIED") return;
2621
- log7.debug(`GramJS edit failed, falling back to Grammy: ${errMsg || error}`);
2292
+ log5.debug(`GramJS edit failed, falling back to Grammy: ${errMsg || error}`);
2622
2293
  }
2623
2294
  }
2624
2295
  const replyMarkup = styledButtons ? toGrammyKeyboard(styledButtons) : void 0;
@@ -2638,7 +2309,7 @@ var InlineRouter = class {
2638
2309
  await ctx.answerCallbackQuery();
2639
2310
  }
2640
2311
  } catch (error) {
2641
- log7.error({ err: error }, `Plugin "${pluginName}" callback handler failed`);
2312
+ log5.error({ err: error }, `Plugin "${pluginName}" callback handler failed`);
2642
2313
  if (!answered) {
2643
2314
  try {
2644
2315
  await ctx.answerCallbackQuery({ text: "Error processing action" });
@@ -2661,7 +2332,7 @@ var InlineRouter = class {
2661
2332
  };
2662
2333
  await plugin.onChosenResult(crCtx);
2663
2334
  } catch (error) {
2664
- log7.error({ err: error }, `Plugin "${pluginName}" chosen result handler failed`);
2335
+ log5.error({ err: error }, `Plugin "${pluginName}" chosen result handler failed`);
2665
2336
  }
2666
2337
  }
2667
2338
  /**
@@ -2740,7 +2411,7 @@ function withTimeout(promise, ms, message) {
2740
2411
 
2741
2412
  // src/agent/tools/plugin-loader.ts
2742
2413
  import { readdirSync as readdirSync2, readFileSync as readFileSync5, existsSync as existsSync6, statSync } from "fs";
2743
- import { join as join5 } from "path";
2414
+ import { join as join4 } from "path";
2744
2415
  import { pathToFileURL } from "url";
2745
2416
  import { execFile } from "child_process";
2746
2417
 
@@ -2771,7 +2442,7 @@ import { promisify } from "util";
2771
2442
 
2772
2443
  // src/agent/tools/plugin-validator.ts
2773
2444
  import { z } from "zod";
2774
- var log8 = createLogger("PluginValidator");
2445
+ var log6 = createLogger("PluginValidator");
2775
2446
  var ManifestSchema = z.object({
2776
2447
  name: z.string().min(1).max(64).regex(
2777
2448
  /^[a-z0-9][a-z0-9-]*$/,
@@ -2814,20 +2485,20 @@ function validateToolDefs(defs, pluginName) {
2814
2485
  const valid = [];
2815
2486
  for (const def of defs) {
2816
2487
  if (!def || typeof def !== "object") {
2817
- log8.warn(`[${pluginName}] tool is not an object, skipping`);
2488
+ log6.warn(`[${pluginName}] tool is not an object, skipping`);
2818
2489
  continue;
2819
2490
  }
2820
2491
  const t = def;
2821
2492
  if (!t.name || typeof t.name !== "string") {
2822
- log8.warn(`[${pluginName}] tool missing 'name', skipping`);
2493
+ log6.warn(`[${pluginName}] tool missing 'name', skipping`);
2823
2494
  continue;
2824
2495
  }
2825
2496
  if (!t.description || typeof t.description !== "string") {
2826
- log8.warn(`[${pluginName}] tool "${t.name}" missing 'description', skipping`);
2497
+ log6.warn(`[${pluginName}] tool "${t.name}" missing 'description', skipping`);
2827
2498
  continue;
2828
2499
  }
2829
2500
  if (!t.execute || typeof t.execute !== "function") {
2830
- log8.warn(`[${pluginName}] tool "${t.name}" missing 'execute' function, skipping`);
2501
+ log6.warn(`[${pluginName}] tool "${t.name}" missing 'execute' function, skipping`);
2831
2502
  continue;
2832
2503
  }
2833
2504
  valid.push(t);
@@ -2864,8 +2535,19 @@ import { Address, SendMode } from "@ton/core";
2864
2535
 
2865
2536
  // src/ton/tx-lock.ts
2866
2537
  var pending = Promise.resolve();
2538
+ var TX_LOCK_TIMEOUT_MS = 6e4;
2867
2539
  function withTxLock(fn) {
2868
- const execute = pending.then(fn, fn);
2540
+ const guarded = () => {
2541
+ let timerId;
2542
+ const timeoutPromise = new Promise((_, reject) => {
2543
+ timerId = setTimeout(
2544
+ () => reject(new Error("TON tx-lock timeout (60s)")),
2545
+ TX_LOCK_TIMEOUT_MS
2546
+ );
2547
+ });
2548
+ return Promise.race([fn(), timeoutPromise]).finally(() => clearTimeout(timerId));
2549
+ };
2550
+ const execute = pending.then(guarded, guarded);
2869
2551
  pending = execute.then(
2870
2552
  () => {
2871
2553
  },
@@ -2876,25 +2558,25 @@ function withTxLock(fn) {
2876
2558
  }
2877
2559
 
2878
2560
  // src/ton/transfer.ts
2879
- var log9 = createLogger("TON");
2561
+ var log7 = createLogger("TON");
2880
2562
  async function sendTon(params) {
2881
2563
  return withTxLock(async () => {
2882
2564
  try {
2883
2565
  const { toAddress: toAddress2, amount, comment = "", bounce = false } = params;
2884
2566
  if (!Number.isFinite(amount) || amount <= 0) {
2885
- log9.error({ amount }, "Invalid transfer amount");
2567
+ log7.error({ amount }, "Invalid transfer amount");
2886
2568
  return null;
2887
2569
  }
2888
2570
  let recipientAddress;
2889
2571
  try {
2890
2572
  recipientAddress = Address.parse(toAddress2);
2891
2573
  } catch (e) {
2892
- log9.error({ err: e }, `Invalid recipient address: ${toAddress2}`);
2574
+ log7.error({ err: e }, `Invalid recipient address: ${toAddress2}`);
2893
2575
  return null;
2894
2576
  }
2895
2577
  const keyPair = await getKeyPair();
2896
2578
  if (!keyPair) {
2897
- log9.error("Wallet not initialized");
2579
+ log7.error("Wallet not initialized");
2898
2580
  return null;
2899
2581
  }
2900
2582
  const wallet = WalletContractV5R1.create({
@@ -2918,7 +2600,7 @@ async function sendTon(params) {
2918
2600
  ]
2919
2601
  });
2920
2602
  const pseudoHash = `${seqno}_${Date.now()}_${amount.toFixed(2)}`;
2921
- log9.info(`Sent ${amount} TON to ${toAddress2.slice(0, 8)}... - seqno: ${seqno}`);
2603
+ log7.info(`Sent ${amount} TON to ${toAddress2.slice(0, 8)}... - seqno: ${seqno}`);
2922
2604
  return pseudoHash;
2923
2605
  } catch (error) {
2924
2606
  const err = error;
@@ -2926,14 +2608,14 @@ async function sendTon(params) {
2926
2608
  if (status === 429 || status !== void 0 && status >= 500) {
2927
2609
  invalidateTonClientCache();
2928
2610
  }
2929
- log9.error({ err: error }, "Error sending TON");
2611
+ log7.error({ err: error }, "Error sending TON");
2930
2612
  throw error;
2931
2613
  }
2932
2614
  });
2933
2615
  }
2934
2616
 
2935
2617
  // src/utils/retry.ts
2936
- var log10 = createLogger("Utils");
2618
+ var log8 = createLogger("Utils");
2937
2619
  var DEFAULT_OPTIONS = {
2938
2620
  maxAttempts: RETRY_DEFAULT_MAX_ATTEMPTS,
2939
2621
  baseDelayMs: RETRY_DEFAULT_BASE_DELAY_MS,
@@ -2957,7 +2639,7 @@ async function withRetry(fn, options = {}) {
2957
2639
  return result;
2958
2640
  } catch (error) {
2959
2641
  lastError = error instanceof Error ? error : new Error(String(error));
2960
- log10.warn(`Retry attempt ${attempt}/${opts.maxAttempts} failed: ${lastError.message}`);
2642
+ log8.warn(`Retry attempt ${attempt}/${opts.maxAttempts} failed: ${lastError.message}`);
2961
2643
  if (attempt < opts.maxAttempts) {
2962
2644
  const delay = Math.min(opts.baseDelayMs * Math.pow(2, attempt - 1), opts.maxDelayMs);
2963
2645
  await sleep(delay);
@@ -6435,7 +6117,7 @@ var DEDUST_GAS = {
6435
6117
  var NATIVE_TON_ADDRESS = "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c";
6436
6118
 
6437
6119
  // src/agent/tools/dedust/asset-cache.ts
6438
- var log11 = createLogger("Tools");
6120
+ var log9 = createLogger("Tools");
6439
6121
  var ASSET_LIST_URL = "https://assets.dedust.io/list.json";
6440
6122
  var CACHE_TTL_MS = 10 * 60 * 1e3;
6441
6123
  var cachedAssets = [];
@@ -6454,7 +6136,7 @@ async function getAssetList() {
6454
6136
  return cachedAssets;
6455
6137
  } catch (error) {
6456
6138
  if (cachedAssets.length > 0) {
6457
- log11.warn({ err: error }, "Asset list fetch failed, using stale cache");
6139
+ log9.warn({ err: error }, "Asset list fetch failed, using stale cache");
6458
6140
  return cachedAssets;
6459
6141
  }
6460
6142
  throw error;
@@ -6507,7 +6189,7 @@ var stonApiClient = new StonApiClient();
6507
6189
  function isTon(asset) {
6508
6190
  return asset.toLowerCase() === "ton";
6509
6191
  }
6510
- async function getStonfiQuote(fromAsset, toAsset, amount, slippage, log15) {
6192
+ async function getStonfiQuote(fromAsset, toAsset, amount, slippage, log13) {
6511
6193
  try {
6512
6194
  const isTonInput = isTon(fromAsset);
6513
6195
  const isTonOutput = isTon(toAsset);
@@ -6538,11 +6220,11 @@ async function getStonfiQuote(fromAsset, toAsset, amount, slippage, log15) {
6538
6220
  fee: feeAmount.toFixed(6)
6539
6221
  };
6540
6222
  } catch (err) {
6541
- log15.debug("dex.quoteSTONfi() failed:", err);
6223
+ log13.debug("dex.quoteSTONfi() failed:", err);
6542
6224
  return null;
6543
6225
  }
6544
6226
  }
6545
- async function getDedustQuote(fromAsset, toAsset, amount, slippage, log15) {
6227
+ async function getDedustQuote(fromAsset, toAsset, amount, slippage, log13) {
6546
6228
  try {
6547
6229
  const isTonInput = isTon(fromAsset);
6548
6230
  const isTonOutput = isTon(toAsset);
@@ -6576,7 +6258,7 @@ async function getDedustQuote(fromAsset, toAsset, amount, slippage, log15) {
6576
6258
  poolType
6577
6259
  };
6578
6260
  } catch (err) {
6579
- log15.debug("dex.quoteDeDust() failed:", err);
6261
+ log13.debug("dex.quoteDeDust() failed:", err);
6580
6262
  return null;
6581
6263
  }
6582
6264
  }
@@ -6748,14 +6430,14 @@ function validateDexParams(amount, slippage) {
6748
6430
  throw new PluginSDKError("Slippage must be between 0 and 1", "OPERATION_FAILED");
6749
6431
  }
6750
6432
  }
6751
- function createDexSDK(log15) {
6433
+ function createDexSDK(log13) {
6752
6434
  return {
6753
6435
  async quote(params) {
6754
6436
  validateDexParams(params.amount, params.slippage);
6755
6437
  const slippage = params.slippage ?? 0.01;
6756
6438
  const [stonfi, dedust] = await Promise.all([
6757
- getStonfiQuote(params.fromAsset, params.toAsset, params.amount, slippage, log15),
6758
- getDedustQuote(params.fromAsset, params.toAsset, params.amount, slippage, log15)
6439
+ getStonfiQuote(params.fromAsset, params.toAsset, params.amount, slippage, log13),
6440
+ getDedustQuote(params.fromAsset, params.toAsset, params.amount, slippage, log13)
6759
6441
  ]);
6760
6442
  if (!stonfi && !dedust) {
6761
6443
  throw new PluginSDKError("No DEX has liquidity for this pair", "OPERATION_FAILED");
@@ -6789,7 +6471,7 @@ function createDexSDK(log15) {
6789
6471
  params.toAsset,
6790
6472
  params.amount,
6791
6473
  params.slippage ?? 0.01,
6792
- log15
6474
+ log13
6793
6475
  );
6794
6476
  },
6795
6477
  async quoteDeDust(params) {
@@ -6798,25 +6480,25 @@ function createDexSDK(log15) {
6798
6480
  params.toAsset,
6799
6481
  params.amount,
6800
6482
  params.slippage ?? 0.01,
6801
- log15
6483
+ log13
6802
6484
  );
6803
6485
  },
6804
6486
  async swap(params) {
6805
6487
  validateDexParams(params.amount, params.slippage);
6806
6488
  if (params.dex === "stonfi") {
6807
- return executeSTONfiSwap(params, log15);
6489
+ return executeSTONfiSwap(params, log13);
6808
6490
  }
6809
6491
  if (params.dex === "dedust") {
6810
- return executeDedustSwap(params, log15);
6492
+ return executeDedustSwap(params, log13);
6811
6493
  }
6812
6494
  const quoteResult = await this.quote(params);
6813
- return quoteResult.recommended === "stonfi" ? executeSTONfiSwap(params, log15) : executeDedustSwap(params, log15);
6495
+ return quoteResult.recommended === "stonfi" ? executeSTONfiSwap(params, log13) : executeDedustSwap(params, log13);
6814
6496
  },
6815
6497
  async swapSTONfi(params) {
6816
- return executeSTONfiSwap(params, log15);
6498
+ return executeSTONfiSwap(params, log13);
6817
6499
  },
6818
6500
  async swapDeDust(params) {
6819
- return executeDedustSwap(params, log15);
6501
+ return executeDedustSwap(params, log13);
6820
6502
  }
6821
6503
  };
6822
6504
  }
@@ -6853,7 +6535,7 @@ function normalizeDomain(domain) {
6853
6535
  if (!d.endsWith(".ton")) d += ".ton";
6854
6536
  return d;
6855
6537
  }
6856
- function createDnsSDK(log15) {
6538
+ function createDnsSDK(log13) {
6857
6539
  return {
6858
6540
  async check(domain) {
6859
6541
  const normalized = normalizeDomain(domain);
@@ -6876,7 +6558,7 @@ function createDnsSDK(log15) {
6876
6558
  };
6877
6559
  } catch (err) {
6878
6560
  if (err instanceof PluginSDKError) throw err;
6879
- log15.debug("dns.check() failed:", err);
6561
+ log13.debug("dns.check() failed:", err);
6880
6562
  throw new PluginSDKError(
6881
6563
  `Failed to check domain: ${err instanceof Error ? err.message : String(err)}`,
6882
6564
  "OPERATION_FAILED"
@@ -6889,7 +6571,7 @@ function createDnsSDK(log15) {
6889
6571
  const response = await tonapiFetch(`/dns/${encodeURIComponent(normalized)}`);
6890
6572
  if (response.status === 404) return null;
6891
6573
  if (!response.ok) {
6892
- log15.debug(`dns.resolve() TonAPI error: ${response.status}`);
6574
+ log13.debug(`dns.resolve() TonAPI error: ${response.status}`);
6893
6575
  return null;
6894
6576
  }
6895
6577
  const data = await response.json();
@@ -6901,7 +6583,7 @@ function createDnsSDK(log15) {
6901
6583
  expirationDate: data.expiring_at || void 0
6902
6584
  };
6903
6585
  } catch (err) {
6904
- log15.debug("dns.resolve() failed:", err);
6586
+ log13.debug("dns.resolve() failed:", err);
6905
6587
  return null;
6906
6588
  }
6907
6589
  },
@@ -6911,7 +6593,7 @@ function createDnsSDK(log15) {
6911
6593
  `/dns/auctions?tld=ton&limit=${Math.min(limit ?? 20, 100)}`
6912
6594
  );
6913
6595
  if (!response.ok) {
6914
- log15.debug(`dns.getAuctions() TonAPI error: ${response.status}`);
6596
+ log13.debug(`dns.getAuctions() TonAPI error: ${response.status}`);
6915
6597
  return [];
6916
6598
  }
6917
6599
  const data = await response.json();
@@ -6924,7 +6606,7 @@ function createDnsSDK(log15) {
6924
6606
  bids: a.bids || 0
6925
6607
  }));
6926
6608
  } catch (err) {
6927
- log15.debug("dns.getAuctions() failed:", err);
6609
+ log13.debug("dns.getAuctions() failed:", err);
6928
6610
  return [];
6929
6611
  }
6930
6612
  },
@@ -7238,25 +6920,25 @@ function findJettonBalance(balances, jettonAddress) {
7238
6920
  }
7239
6921
  });
7240
6922
  }
7241
- function cleanupOldTransactions(db, retentionDays, log15) {
6923
+ function cleanupOldTransactions(db, retentionDays, log13) {
7242
6924
  if (Math.random() > CLEANUP_PROBABILITY) return;
7243
6925
  try {
7244
6926
  const cutoff = Math.floor(Date.now() / 1e3) - retentionDays * 24 * 60 * 60;
7245
6927
  const result = db.prepare("DELETE FROM used_transactions WHERE used_at < ?").run(cutoff);
7246
6928
  if (result.changes > 0) {
7247
- log15.debug(`Cleaned up ${result.changes} old transaction records (>${retentionDays}d)`);
6929
+ log13.debug(`Cleaned up ${result.changes} old transaction records (>${retentionDays}d)`);
7248
6930
  }
7249
6931
  } catch (err) {
7250
- log15.error("Transaction cleanup failed:", err);
6932
+ log13.error("Transaction cleanup failed:", err);
7251
6933
  }
7252
6934
  }
7253
- function createTonSDK(log15, db) {
6935
+ function createTonSDK(log13, db) {
7254
6936
  return {
7255
6937
  getAddress() {
7256
6938
  try {
7257
6939
  return getWalletAddress();
7258
6940
  } catch (err) {
7259
- log15.error("ton.getAddress() failed:", err);
6941
+ log13.error("ton.getAddress() failed:", err);
7260
6942
  return null;
7261
6943
  }
7262
6944
  },
@@ -7266,7 +6948,7 @@ function createTonSDK(log15, db) {
7266
6948
  if (!addr) return null;
7267
6949
  return await getWalletBalance(addr);
7268
6950
  } catch (err) {
7269
- log15.error("ton.getBalance() failed:", err);
6951
+ log13.error("ton.getBalance() failed:", err);
7270
6952
  return null;
7271
6953
  }
7272
6954
  },
@@ -7274,7 +6956,7 @@ function createTonSDK(log15, db) {
7274
6956
  try {
7275
6957
  return await getTonPrice();
7276
6958
  } catch (err) {
7277
- log15.error("ton.getPrice() failed:", err);
6959
+ log13.error("ton.getPrice() failed:", err);
7278
6960
  return null;
7279
6961
  }
7280
6962
  },
@@ -7325,7 +7007,7 @@ function createTonSDK(log15, db) {
7325
7007
  );
7326
7008
  return formatTransactions(transactions);
7327
7009
  } catch (err) {
7328
- log15.error("ton.getTransactions() failed:", err);
7010
+ log13.error("ton.getTransactions() failed:", err);
7329
7011
  return [];
7330
7012
  }
7331
7013
  },
@@ -7348,7 +7030,7 @@ function createTonSDK(log15, db) {
7348
7030
  throw new PluginSDKError("Wallet not initialized", "WALLET_NOT_INITIALIZED");
7349
7031
  }
7350
7032
  const maxAgeMinutes = params.maxAgeMinutes ?? DEFAULT_MAX_AGE_MINUTES;
7351
- cleanupOldTransactions(db, DEFAULT_TX_RETENTION_DAYS, log15);
7033
+ cleanupOldTransactions(db, DEFAULT_TX_RETENTION_DAYS, log13);
7352
7034
  try {
7353
7035
  const txs = await this.getTransactions(address4, 20);
7354
7036
  for (const tx of txs) {
@@ -7382,7 +7064,7 @@ function createTonSDK(log15, db) {
7382
7064
  };
7383
7065
  } catch (err) {
7384
7066
  if (err instanceof PluginSDKError) throw err;
7385
- log15.error("ton.verifyPayment() failed:", err);
7067
+ log13.error("ton.verifyPayment() failed:", err);
7386
7068
  return {
7387
7069
  verified: false,
7388
7070
  error: `Verification failed: ${err instanceof Error ? err.message : String(err)}`
@@ -7396,7 +7078,7 @@ function createTonSDK(log15, db) {
7396
7078
  if (!addr) return [];
7397
7079
  const response = await tonapiFetch(`/accounts/${encodeURIComponent(addr)}/jettons`);
7398
7080
  if (!response.ok) {
7399
- log15.error(`ton.getJettonBalances() TonAPI error: ${response.status}`);
7081
+ log13.error(`ton.getJettonBalances() TonAPI error: ${response.status}`);
7400
7082
  return [];
7401
7083
  }
7402
7084
  const data = await response.json();
@@ -7420,7 +7102,7 @@ function createTonSDK(log15, db) {
7420
7102
  }
7421
7103
  return balances;
7422
7104
  } catch (err) {
7423
- log15.error("ton.getJettonBalances() failed:", err);
7105
+ log13.error("ton.getJettonBalances() failed:", err);
7424
7106
  return [];
7425
7107
  }
7426
7108
  },
@@ -7429,7 +7111,7 @@ function createTonSDK(log15, db) {
7429
7111
  const response = await tonapiFetch(`/jettons/${encodeURIComponent(jettonAddress)}`);
7430
7112
  if (response.status === 404) return null;
7431
7113
  if (!response.ok) {
7432
- log15.error(`ton.getJettonInfo() TonAPI error: ${response.status}`);
7114
+ log13.error(`ton.getJettonInfo() TonAPI error: ${response.status}`);
7433
7115
  return null;
7434
7116
  }
7435
7117
  const data = await response.json();
@@ -7447,7 +7129,7 @@ function createTonSDK(log15, db) {
7447
7129
  image: data.preview || metadata.image || void 0
7448
7130
  };
7449
7131
  } catch (err) {
7450
- log15.error("ton.getJettonInfo() failed:", err);
7132
+ log13.error("ton.getJettonInfo() failed:", err);
7451
7133
  return null;
7452
7134
  }
7453
7135
  },
@@ -7534,12 +7216,13 @@ function createTonSDK(log15, db) {
7534
7216
  return seq;
7535
7217
  } catch (err) {
7536
7218
  lastErr = err;
7537
- const status = err?.status || err?.response?.status;
7538
- const respData = err?.response?.data;
7219
+ const httpErr = isHttpError(err) ? err : void 0;
7220
+ const status = httpErr?.status || httpErr?.response?.status;
7221
+ const respData = httpErr?.response?.data;
7539
7222
  if (status === 429 || status && status >= 500) {
7540
7223
  invalidateTonClientCache();
7541
7224
  if (attempt < MAX_SEND_ATTEMPTS) {
7542
- log15.warn(
7225
+ log13.warn(
7543
7226
  `sendJetton attempt ${attempt} failed (${status}): ${JSON.stringify(respData ?? err.message)}, retrying...`
7544
7227
  );
7545
7228
  await new Promise((r3) => setTimeout(r3, 1e3 * attempt));
@@ -7553,7 +7236,8 @@ function createTonSDK(log15, db) {
7553
7236
  });
7554
7237
  return { success: true, seqno };
7555
7238
  } catch (err) {
7556
- const status = err?.status || err?.response?.status;
7239
+ const outerHttpErr = isHttpError(err) ? err : void 0;
7240
+ const status = outerHttpErr?.status || outerHttpErr?.response?.status;
7557
7241
  if (status === 429 || status && status >= 500) {
7558
7242
  invalidateTonClientCache();
7559
7243
  }
@@ -7568,14 +7252,14 @@ function createTonSDK(log15, db) {
7568
7252
  try {
7569
7253
  const response = await tonapiFetch(`/accounts/${encodeURIComponent(ownerAddress)}/jettons`);
7570
7254
  if (!response.ok) {
7571
- log15.error(`ton.getJettonWalletAddress() TonAPI error: ${response.status}`);
7255
+ log13.error(`ton.getJettonWalletAddress() TonAPI error: ${response.status}`);
7572
7256
  return null;
7573
7257
  }
7574
7258
  const data = await response.json();
7575
7259
  const match = findJettonBalance(data.balances ?? [], jettonAddress);
7576
7260
  return match ? match.wallet_address.address : null;
7577
7261
  } catch (err) {
7578
- log15.error("ton.getJettonWalletAddress() failed:", err);
7262
+ log13.error("ton.getJettonWalletAddress() failed:", err);
7579
7263
  return null;
7580
7264
  }
7581
7265
  },
@@ -7752,7 +7436,7 @@ function createTonSDK(log15, db) {
7752
7436
  const wallet = loadWallet();
7753
7437
  return wallet?.publicKey ?? null;
7754
7438
  } catch (err) {
7755
- log15.error("ton.getPublicKey() failed:", err);
7439
+ log13.error("ton.getPublicKey() failed:", err);
7756
7440
  return null;
7757
7441
  }
7758
7442
  },
@@ -7768,14 +7452,14 @@ function createTonSDK(log15, db) {
7768
7452
  `/accounts/${encodeURIComponent(addr)}/nfts?limit=100&indirect_ownership=true`
7769
7453
  );
7770
7454
  if (!response.ok) {
7771
- log15.error(`ton.getNftItems() TonAPI error: ${response.status}`);
7455
+ log13.error(`ton.getNftItems() TonAPI error: ${response.status}`);
7772
7456
  return [];
7773
7457
  }
7774
7458
  const data = await response.json();
7775
7459
  if (!Array.isArray(data.nft_items)) return [];
7776
7460
  return data.nft_items.filter((item) => item.trust !== "blacklist").map((item) => mapNftItem(item));
7777
7461
  } catch (err) {
7778
- log15.error("ton.getNftItems() failed:", err);
7462
+ log13.error("ton.getNftItems() failed:", err);
7779
7463
  return [];
7780
7464
  }
7781
7465
  },
@@ -7784,13 +7468,13 @@ function createTonSDK(log15, db) {
7784
7468
  const response = await tonapiFetch(`/nfts/${encodeURIComponent(nftAddress)}`);
7785
7469
  if (response.status === 404) return null;
7786
7470
  if (!response.ok) {
7787
- log15.error(`ton.getNftInfo() TonAPI error: ${response.status}`);
7471
+ log13.error(`ton.getNftInfo() TonAPI error: ${response.status}`);
7788
7472
  return null;
7789
7473
  }
7790
7474
  const item = await response.json();
7791
7475
  return mapNftItem(item);
7792
7476
  } catch (err) {
7793
- log15.error("ton.getNftInfo() failed:", err);
7477
+ log13.error("ton.getNftInfo() failed:", err);
7794
7478
  return null;
7795
7479
  }
7796
7480
  },
@@ -7823,7 +7507,7 @@ function createTonSDK(log15, db) {
7823
7507
  `/rates?tokens=${encodeURIComponent(jettonAddress)}&currencies=usd,ton`
7824
7508
  );
7825
7509
  if (!response.ok) {
7826
- log15.debug(`ton.getJettonPrice() TonAPI error: ${response.status}`);
7510
+ log13.debug(`ton.getJettonPrice() TonAPI error: ${response.status}`);
7827
7511
  return null;
7828
7512
  }
7829
7513
  const data = await response.json();
@@ -7837,7 +7521,7 @@ function createTonSDK(log15, db) {
7837
7521
  change30d: rateData.diff_30d?.USD ?? null
7838
7522
  };
7839
7523
  } catch (err) {
7840
- log15.debug("ton.getJettonPrice() failed:", err);
7524
+ log13.debug("ton.getJettonPrice() failed:", err);
7841
7525
  return null;
7842
7526
  }
7843
7527
  },
@@ -7851,7 +7535,7 @@ function createTonSDK(log15, db) {
7851
7535
  tonapiFetch(`/jettons/${encodeURIComponent(jettonAddress)}`)
7852
7536
  ]);
7853
7537
  if (!holdersResponse.ok) {
7854
- log15.debug(`ton.getJettonHolders() TonAPI error: ${holdersResponse.status}`);
7538
+ log13.debug(`ton.getJettonHolders() TonAPI error: ${holdersResponse.status}`);
7855
7539
  return [];
7856
7540
  }
7857
7541
  const data = await holdersResponse.json();
@@ -7871,7 +7555,7 @@ function createTonSDK(log15, db) {
7871
7555
  };
7872
7556
  });
7873
7557
  } catch (err) {
7874
- log15.debug("ton.getJettonHolders() failed:", err);
7558
+ log13.debug("ton.getJettonHolders() failed:", err);
7875
7559
  return [];
7876
7560
  }
7877
7561
  },
@@ -7943,13 +7627,13 @@ function createTonSDK(log15, db) {
7943
7627
  holders: holdersCount
7944
7628
  };
7945
7629
  } catch (err) {
7946
- log15.debug("ton.getJettonHistory() failed:", err);
7630
+ log13.debug("ton.getJettonHistory() failed:", err);
7947
7631
  return null;
7948
7632
  }
7949
7633
  },
7950
7634
  // ─── Sub-namespaces ───────────────────────────────────────────
7951
- dex: Object.freeze(createDexSDK(log15)),
7952
- dns: Object.freeze(createDnsSDK(log15))
7635
+ dex: Object.freeze(createDexSDK(log13)),
7636
+ dns: Object.freeze(createDnsSDK(log13))
7953
7637
  };
7954
7638
  }
7955
7639
  function mapNftItem(item) {
@@ -7973,15 +7657,6 @@ function mapNftItem(item) {
7973
7657
  // src/sdk/telegram.ts
7974
7658
  import { Api as Api3 } from "telegram";
7975
7659
 
7976
- // src/utils/gramjs-bigint.ts
7977
- import { randomBytes } from "crypto";
7978
- function toLong(value) {
7979
- return typeof value === "bigint" ? value : BigInt(value);
7980
- }
7981
- function randomLong() {
7982
- return randomBytes(8).readBigUInt64BE();
7983
- }
7984
-
7985
7660
  // src/sdk/telegram-utils.ts
7986
7661
  function requireBridge(bridge) {
7987
7662
  if (!bridge.isAvailable()) {
@@ -7998,7 +7673,6 @@ function toSimpleMessage(msg) {
7998
7673
  return {
7999
7674
  id: msg.id,
8000
7675
  text: msg.message ?? "",
8001
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS fromId is a union of untyped peer types
8002
7676
  senderId: Number(msg.fromId?.userId ?? msg.fromId?.channelId ?? 0),
8003
7677
  timestamp: new Date(msg.date * 1e3)
8004
7678
  };
@@ -8012,7 +7686,7 @@ async function getApi() {
8012
7686
  }
8013
7687
 
8014
7688
  // src/sdk/telegram-messages.ts
8015
- function createTelegramMessagesSDK(bridge, log15) {
7689
+ function createTelegramMessagesSDK(bridge, log13) {
8016
7690
  function requireBridge2() {
8017
7691
  requireBridge(bridge);
8018
7692
  }
@@ -8119,7 +7793,7 @@ function createTelegramMessagesSDK(bridge, log15) {
8119
7793
  return (resultData.messages ?? []).map(toSimpleMessage);
8120
7794
  } catch (err) {
8121
7795
  if (err instanceof PluginSDKError) throw err;
8122
- log15.error("telegram.searchMessages() failed:", err);
7796
+ log13.error("telegram.searchMessages() failed:", err);
8123
7797
  return [];
8124
7798
  }
8125
7799
  },
@@ -8156,8 +7830,7 @@ function createTelegramMessagesSDK(bridge, log15) {
8156
7830
  limit,
8157
7831
  maxId: 0,
8158
7832
  minId: 0,
8159
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS BigInteger compat requires bigint cast
8160
- hash: 0n
7833
+ hash: toLong(0n)
8161
7834
  })
8162
7835
  );
8163
7836
  const messages = [];
@@ -8320,10 +7993,12 @@ function createTelegramMessagesSDK(bridge, log15) {
8320
7993
  if (!messages || messages.length === 0 || !messages[0].media) {
8321
7994
  return null;
8322
7995
  }
8323
- const doc = messages[0].media?.document;
8324
- if (doc?.size && Number(doc.size) > MAX_DOWNLOAD_SIZE) {
7996
+ const media = messages[0].media;
7997
+ const doc = media && "document" in media ? media.document : void 0;
7998
+ const docSize = doc && "size" in doc ? doc.size : void 0;
7999
+ if (docSize && Number(docSize) > MAX_DOWNLOAD_SIZE) {
8325
8000
  throw new PluginSDKError(
8326
- `File too large (${Math.round(Number(doc.size) / 1024 / 1024)}MB). Max: 50MB`,
8001
+ `File too large (${Math.round(Number(docSize) / 1024 / 1024)}MB). Max: 50MB`,
8327
8002
  "OPERATION_FAILED"
8328
8003
  );
8329
8004
  }
@@ -8347,8 +8022,7 @@ function createTelegramMessagesSDK(bridge, log15) {
8347
8022
  const result = await gramJsClient.invoke(
8348
8023
  new Api4.messages.GetScheduledHistory({
8349
8024
  peer,
8350
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- GramJS BigInteger compat requires bigint cast
8351
- hash: 0n
8025
+ hash: toLong(0n)
8352
8026
  })
8353
8027
  );
8354
8028
  const messages = [];
@@ -8362,7 +8036,7 @@ function createTelegramMessagesSDK(bridge, log15) {
8362
8036
  return messages;
8363
8037
  } catch (err) {
8364
8038
  if (err instanceof PluginSDKError) throw err;
8365
- log15.error("telegram.getScheduledMessages() failed:", err);
8039
+ log13.error("telegram.getScheduledMessages() failed:", err);
8366
8040
  return [];
8367
8041
  }
8368
8042
  },
@@ -8423,7 +8097,7 @@ function createTelegramMessagesSDK(bridge, log15) {
8423
8097
  }
8424
8098
 
8425
8099
  // src/sdk/telegram-social.ts
8426
- function createTelegramSocialSDK(bridge, log15) {
8100
+ function createTelegramSocialSDK(bridge, log13) {
8427
8101
  function requireBridge2() {
8428
8102
  requireBridge(bridge);
8429
8103
  }
@@ -8498,7 +8172,7 @@ function createTelegramSocialSDK(bridge, log15) {
8498
8172
  return null;
8499
8173
  } catch (err) {
8500
8174
  if (err instanceof PluginSDKError) throw err;
8501
- log15.error("telegram.getChatInfo() failed:", err);
8175
+ log13.error("telegram.getChatInfo() failed:", err);
8502
8176
  return null;
8503
8177
  }
8504
8178
  },
@@ -8612,7 +8286,7 @@ function createTelegramSocialSDK(bridge, log15) {
8612
8286
  });
8613
8287
  } catch (err) {
8614
8288
  if (err instanceof PluginSDKError) throw err;
8615
- log15.error("telegram.getParticipants() failed:", err);
8289
+ log13.error("telegram.getParticipants() failed:", err);
8616
8290
  return [];
8617
8291
  }
8618
8292
  },
@@ -8829,7 +8503,7 @@ function createTelegramSocialSDK(bridge, log15) {
8829
8503
  const user = await client.getInputEntity(userId.toString());
8830
8504
  const invoiceData = {
8831
8505
  peer: user,
8832
- giftId: BigInt(giftId),
8506
+ giftId: toLong(giftId),
8833
8507
  hideName: opts?.anonymous ?? false,
8834
8508
  message: opts?.message ? new Api4.TextWithEntities({ text: opts.message, entities: [] }) : void 0
8835
8509
  };
@@ -8913,7 +8587,7 @@ function createTelegramSocialSDK(bridge, log15) {
8913
8587
  const Api4 = await getApi();
8914
8588
  const result = await client.invoke(
8915
8589
  new Api4.payments.GetResaleStarGifts({
8916
- giftId: BigInt(giftId),
8590
+ giftId: toLong(giftId),
8917
8591
  offset: "",
8918
8592
  limit: limit ?? 50
8919
8593
  })
@@ -8974,7 +8648,7 @@ function createTelegramSocialSDK(bridge, log15) {
8974
8648
  }));
8975
8649
  } catch (err) {
8976
8650
  if (err instanceof PluginSDKError) throw err;
8977
- log15.error("telegram.getDialogs() failed:", err);
8651
+ log13.error("telegram.getDialogs() failed:", err);
8978
8652
  return [];
8979
8653
  }
8980
8654
  },
@@ -8988,7 +8662,7 @@ function createTelegramSocialSDK(bridge, log15) {
8988
8662
  return messages.map(toSimpleMessage);
8989
8663
  } catch (err) {
8990
8664
  if (err instanceof PluginSDKError) throw err;
8991
- log15.error("telegram.getHistory() failed:", err);
8665
+ log13.error("telegram.getHistory() failed:", err);
8992
8666
  return [];
8993
8667
  }
8994
8668
  },
@@ -9019,7 +8693,7 @@ function createTelegramSocialSDK(bridge, log15) {
9019
8693
  }));
9020
8694
  } catch (err) {
9021
8695
  if (err instanceof PluginSDKError) throw err;
9022
- log15.error("telegram.getStarsTransactions() failed:", err);
8696
+ log13.error("telegram.getStarsTransactions() failed:", err);
9023
8697
  return [];
9024
8698
  }
9025
8699
  },
@@ -9072,7 +8746,7 @@ function createTelegramSocialSDK(bridge, log15) {
9072
8746
  new Api4.payments.UpdateStarGiftPrice({
9073
8747
  stargift: new Api4.InputSavedStarGiftUser({ msgId }),
9074
8748
  resellAmount: new Api4.StarsAmount({
9075
- amount: BigInt(price),
8749
+ amount: toLong(price),
9076
8750
  nanos: 0
9077
8751
  })
9078
8752
  })
@@ -9124,7 +8798,7 @@ function createTelegramSocialSDK(bridge, log15) {
9124
8798
  };
9125
8799
  } catch (err) {
9126
8800
  if (err instanceof PluginSDKError) throw err;
9127
- log15.error("telegram.getCollectibleInfo() failed:", err);
8801
+ log13.error("telegram.getCollectibleInfo() failed:", err);
9128
8802
  return null;
9129
8803
  }
9130
8804
  },
@@ -9162,7 +8836,7 @@ function createTelegramSocialSDK(bridge, log15) {
9162
8836
  } catch (err) {
9163
8837
  if (err.errorMessage === "STARGIFT_SLUG_INVALID") return null;
9164
8838
  if (err instanceof PluginSDKError) throw err;
9165
- log15.error("telegram.getUniqueGift() failed:", err);
8839
+ log13.error("telegram.getUniqueGift() failed:", err);
9166
8840
  return null;
9167
8841
  }
9168
8842
  },
@@ -9188,7 +8862,7 @@ function createTelegramSocialSDK(bridge, log15) {
9188
8862
  } catch (err) {
9189
8863
  if (err.errorMessage === "STARGIFT_SLUG_INVALID") return null;
9190
8864
  if (err instanceof PluginSDKError) throw err;
9191
- log15.error("telegram.getUniqueGiftValue() failed:", err);
8865
+ log13.error("telegram.getUniqueGiftValue() failed:", err);
9192
8866
  return null;
9193
8867
  }
9194
8868
  },
@@ -9203,7 +8877,7 @@ function createTelegramSocialSDK(bridge, log15) {
9203
8877
  new Api4.payments.SendStarGiftOffer({
9204
8878
  peer,
9205
8879
  slug: giftSlug,
9206
- price: new Api4.StarsAmount({ amount: BigInt(price), nanos: 0 }),
8880
+ price: new Api4.StarsAmount({ amount: toLong(price), nanos: 0 }),
9207
8881
  duration,
9208
8882
  randomId: randomLong()
9209
8883
  })
@@ -9299,7 +8973,7 @@ function createTelegramSocialSDK(bridge, log15) {
9299
8973
  }
9300
8974
 
9301
8975
  // src/sdk/telegram.ts
9302
- function createTelegramSDK(bridge, log15) {
8976
+ function createTelegramSDK(bridge, log13) {
9303
8977
  function requireBridge2() {
9304
8978
  requireBridge(bridge);
9305
8979
  }
@@ -9403,7 +9077,7 @@ function createTelegramSDK(bridge, log15) {
9403
9077
  timestamp: m.timestamp
9404
9078
  }));
9405
9079
  } catch (err) {
9406
- log15.error("telegram.getMessages() failed:", err);
9080
+ log13.error("telegram.getMessages() failed:", err);
9407
9081
  return [];
9408
9082
  }
9409
9083
  },
@@ -9425,7 +9099,7 @@ function createTelegramSDK(bridge, log15) {
9425
9099
  return bridge.isAvailable();
9426
9100
  },
9427
9101
  getRawClient() {
9428
- log15.warn("getRawClient() called \u2014 this bypasses SDK sandbox guarantees");
9102
+ log13.warn("getRawClient() called \u2014 this bypasses SDK sandbox guarantees");
9429
9103
  if (!bridge.isAvailable()) return null;
9430
9104
  try {
9431
9105
  return bridge.getClient().getClient();
@@ -9434,17 +9108,17 @@ function createTelegramSDK(bridge, log15) {
9434
9108
  }
9435
9109
  },
9436
9110
  // Spread extended methods from sub-modules
9437
- ...createTelegramMessagesSDK(bridge, log15),
9438
- ...createTelegramSocialSDK(bridge, log15)
9111
+ ...createTelegramMessagesSDK(bridge, log13),
9112
+ ...createTelegramSocialSDK(bridge, log13)
9439
9113
  };
9440
9114
  }
9441
9115
 
9442
9116
  // src/sdk/secrets.ts
9443
9117
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, existsSync as existsSync5 } from "fs";
9444
- import { join as join4 } from "path";
9445
- var SECRETS_DIR = join4(TELETON_ROOT, "plugins", "data");
9118
+ import { join as join3 } from "path";
9119
+ var SECRETS_DIR = join3(TELETON_ROOT, "plugins", "data");
9446
9120
  function getSecretsPath(pluginName) {
9447
- return join4(SECRETS_DIR, `${pluginName}.secrets.json`);
9121
+ return join3(SECRETS_DIR, `${pluginName}.secrets.json`);
9448
9122
  }
9449
9123
  function readSecretsFile(pluginName) {
9450
9124
  const filePath = getSecretsPath(pluginName);
@@ -9476,23 +9150,23 @@ function deletePluginSecret(pluginName, key) {
9476
9150
  function listPluginSecretKeys(pluginName) {
9477
9151
  return Object.keys(readSecretsFile(pluginName));
9478
9152
  }
9479
- function createSecretsSDK(pluginName, pluginConfig, log15) {
9153
+ function createSecretsSDK(pluginName, pluginConfig, log13) {
9480
9154
  const envPrefix = pluginName.replace(/-/g, "_").toUpperCase();
9481
9155
  function get(key) {
9482
9156
  const envKey = `${envPrefix}_${key.toUpperCase()}`;
9483
9157
  const envValue = process.env[envKey];
9484
9158
  if (envValue) {
9485
- log15.debug(`Secret "${key}" resolved from env var ${envKey}`);
9159
+ log13.debug(`Secret "${key}" resolved from env var ${envKey}`);
9486
9160
  return envValue;
9487
9161
  }
9488
9162
  const stored = readSecretsFile(pluginName);
9489
9163
  if (key in stored && stored[key]) {
9490
- log15.debug(`Secret "${key}" resolved from secrets store`);
9164
+ log13.debug(`Secret "${key}" resolved from secrets store`);
9491
9165
  return stored[key];
9492
9166
  }
9493
9167
  const configValue = pluginConfig[key];
9494
9168
  if (configValue !== void 0 && configValue !== null) {
9495
- log15.debug(`Secret "${key}" resolved from pluginConfig`);
9169
+ log13.debug(`Secret "${key}" resolved from pluginConfig`);
9496
9170
  return String(configValue);
9497
9171
  }
9498
9172
  return void 0;
@@ -9594,7 +9268,7 @@ function createStorageSDK(db) {
9594
9268
  }
9595
9269
 
9596
9270
  // src/sdk/bot.ts
9597
- function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLimiter, log15) {
9271
+ function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLimiter, log13) {
9598
9272
  if (!router || !manifest || !manifest.inline && !manifest.callbacks) {
9599
9273
  return null;
9600
9274
  }
@@ -9617,7 +9291,7 @@ function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLi
9617
9291
  },
9618
9292
  onInlineQuery(handler) {
9619
9293
  if (handlers.onInlineQuery) {
9620
- log15.warn("onInlineQuery called again \u2014 overwriting previous handler");
9294
+ log13.warn("onInlineQuery called again \u2014 overwriting previous handler");
9621
9295
  }
9622
9296
  handlers.onInlineQuery = async (ctx) => {
9623
9297
  if (rateLimiter) {
@@ -9663,7 +9337,7 @@ function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLi
9663
9337
  return;
9664
9338
  } catch (error) {
9665
9339
  if (error?.errorMessage === "MESSAGE_NOT_MODIFIED") return;
9666
- log15.warn(`GramJS edit failed, falling back to Grammy: ${error?.errorMessage || error}`);
9340
+ log13.warn(`GramJS edit failed, falling back to Grammy: ${error?.errorMessage || error}`);
9667
9341
  }
9668
9342
  }
9669
9343
  if (grammyBot) {
@@ -9676,7 +9350,7 @@ function createBotSDK(router, gramjsBot, grammyBot, pluginName, manifest, rateLi
9676
9350
  });
9677
9351
  } catch (error) {
9678
9352
  if (error?.description?.includes("message is not modified")) return;
9679
- log15.error(`Failed to edit inline message: ${error?.description || error}`);
9353
+ log13.error(`Failed to edit inline message: ${error?.description || error}`);
9680
9354
  }
9681
9355
  }
9682
9356
  },
@@ -9735,13 +9409,13 @@ function createSafeDb(db) {
9735
9409
  });
9736
9410
  }
9737
9411
  function createPluginSDK(deps, opts) {
9738
- const log15 = createLogger2(opts.pluginName);
9412
+ const log13 = createLogger2(opts.pluginName);
9739
9413
  const safeDb = opts.db ? createSafeDb(opts.db) : null;
9740
- const ton = Object.freeze(createTonSDK(log15, safeDb));
9741
- const telegram = Object.freeze(createTelegramSDK(deps.bridge, log15));
9742
- const secrets = Object.freeze(createSecretsSDK(opts.pluginName, opts.pluginConfig, log15));
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));
9743
9417
  const storage = safeDb ? Object.freeze(createStorageSDK(safeDb)) : null;
9744
- const frozenLog = Object.freeze(log15);
9418
+ const frozenLog = Object.freeze(log13);
9745
9419
  const frozenConfig = Object.freeze(JSON.parse(JSON.stringify(opts.sanitizedConfig ?? {})));
9746
9420
  const frozenPluginConfig = Object.freeze(JSON.parse(JSON.stringify(opts.pluginConfig ?? {})));
9747
9421
  let cachedBot;
@@ -9772,20 +9446,20 @@ function createPluginSDK(deps, opts) {
9772
9446
  },
9773
9447
  on(hookName, handler, onOpts) {
9774
9448
  if (!opts.hookRegistry) {
9775
- log15.warn(`Hook registration unavailable \u2014 sdk.on() ignored`);
9449
+ log13.warn(`Hook registration unavailable \u2014 sdk.on() ignored`);
9776
9450
  return;
9777
9451
  }
9778
9452
  if (opts.declaredHooks) {
9779
9453
  const declared = opts.declaredHooks.some((h2) => h2.name === hookName);
9780
9454
  if (!declared) {
9781
- log15.warn(`Hook "${hookName}" not declared in manifest \u2014 registration rejected`);
9455
+ log13.warn(`Hook "${hookName}" not declared in manifest \u2014 registration rejected`);
9782
9456
  return;
9783
9457
  }
9784
9458
  }
9785
9459
  const rawPriority = Number(onOpts?.priority) || 0;
9786
9460
  const clampedPriority = Math.max(-1e3, Math.min(1e3, rawPriority));
9787
9461
  if (rawPriority !== clampedPriority) {
9788
- log15.debug(`Hook "${hookName}" priority ${rawPriority} clamped to ${clampedPriority}`);
9462
+ log13.debug(`Hook "${hookName}" priority ${rawPriority} clamped to ${clampedPriority}`);
9789
9463
  }
9790
9464
  const registered = opts.hookRegistry.register({
9791
9465
  pluginId: opts.pluginName,
@@ -9795,7 +9469,7 @@ function createPluginSDK(deps, opts) {
9795
9469
  globalPriority: opts.globalPriority ?? 0
9796
9470
  });
9797
9471
  if (!registered) {
9798
- log15.warn(
9472
+ log13.warn(
9799
9473
  `Hook registration limit reached for plugin "${opts.pluginName}" \u2014 "${hookName}" rejected`
9800
9474
  );
9801
9475
  }
@@ -9914,21 +9588,21 @@ var HookRegistry = class {
9914
9588
 
9915
9589
  // src/agent/tools/plugin-loader.ts
9916
9590
  var execFileAsync = promisify(execFile);
9917
- var log12 = createLogger("PluginLoader");
9918
- var PLUGIN_DATA_DIR = join5(TELETON_ROOT, "plugins", "data");
9591
+ var log10 = createLogger("PluginLoader");
9592
+ var PLUGIN_DATA_DIR = join4(TELETON_ROOT, "plugins", "data");
9919
9593
  function adaptPlugin(raw, entryName, config, loadedModuleNames, sdkDeps, hookRegistry, pluginPriorities) {
9920
9594
  let manifest = null;
9921
9595
  if (raw.manifest) {
9922
9596
  try {
9923
9597
  manifest = validateManifest(raw.manifest);
9924
9598
  } catch (err) {
9925
- log12.warn(
9599
+ log10.warn(
9926
9600
  `[${entryName}] invalid manifest, ignoring: ${err instanceof Error ? err.message : err}`
9927
9601
  );
9928
9602
  }
9929
9603
  }
9930
9604
  if (!manifest) {
9931
- const manifestPath = join5(WORKSPACE_PATHS.PLUGINS_DIR, entryName, "manifest.json");
9605
+ const manifestPath = join4(WORKSPACE_PATHS.PLUGINS_DIR, entryName, "manifest.json");
9932
9606
  try {
9933
9607
  if (existsSync6(manifestPath)) {
9934
9608
  const diskManifest = JSON.parse(readFileSync5(manifestPath, "utf-8"));
@@ -10006,7 +9680,7 @@ function adaptPlugin(raw, entryName, config, loadedModuleNames, sdkDeps, hookReg
10006
9680
  },
10007
9681
  migrate() {
10008
9682
  try {
10009
- const dbPath = join5(PLUGIN_DATA_DIR, `${pluginName}.db`);
9683
+ const dbPath = join4(PLUGIN_DATA_DIR, `${pluginName}.db`);
10010
9684
  pluginDb = openModuleDb(dbPath);
10011
9685
  if (hasMigrate) {
10012
9686
  raw.migrate?.(pluginDb);
@@ -10111,30 +9785,30 @@ function adaptPlugin(raw, entryName, config, loadedModuleNames, sdkDeps, hookReg
10111
9785
  return module;
10112
9786
  }
10113
9787
  async function ensurePluginDeps(pluginDir, pluginEntry) {
10114
- const pkgJson = join5(pluginDir, "package.json");
10115
- const lockfile = join5(pluginDir, "package-lock.json");
10116
- const nodeModules = join5(pluginDir, "node_modules");
9788
+ const pkgJson = join4(pluginDir, "package.json");
9789
+ const lockfile = join4(pluginDir, "package-lock.json");
9790
+ const nodeModules = join4(pluginDir, "node_modules");
10117
9791
  if (!existsSync6(pkgJson)) return;
10118
9792
  if (!existsSync6(lockfile)) {
10119
- log12.warn(
9793
+ log10.warn(
10120
9794
  `[${pluginEntry}] package.json without package-lock.json \u2014 skipping (lockfile required)`
10121
9795
  );
10122
9796
  return;
10123
9797
  }
10124
9798
  if (existsSync6(nodeModules)) {
10125
- const marker = join5(nodeModules, ".package-lock.json");
9799
+ const marker = join4(nodeModules, ".package-lock.json");
10126
9800
  if (existsSync6(marker) && statSync(marker).mtimeMs >= statSync(lockfile).mtimeMs) return;
10127
9801
  }
10128
- log12.info(`[${pluginEntry}] Installing dependencies...`);
9802
+ log10.info(`[${pluginEntry}] Installing dependencies...`);
10129
9803
  try {
10130
9804
  await execFileAsync("npm", ["ci", "--ignore-scripts", "--no-audit", "--no-fund"], {
10131
9805
  cwd: pluginDir,
10132
9806
  timeout: 6e4,
10133
9807
  env: { ...process.env, NODE_ENV: "production" }
10134
9808
  });
10135
- log12.info(`[${pluginEntry}] Dependencies installed`);
9809
+ log10.info(`[${pluginEntry}] Dependencies installed`);
10136
9810
  } catch (err) {
10137
- log12.error(`[${pluginEntry}] Failed to install deps: ${String(err).slice(0, 300)}`);
9811
+ log10.error(`[${pluginEntry}] Failed to install deps: ${String(err).slice(0, 300)}`);
10138
9812
  }
10139
9813
  }
10140
9814
  async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
@@ -10156,14 +9830,14 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
10156
9830
  const pluginPaths = [];
10157
9831
  for (const entry of entries) {
10158
9832
  if (entry === "data") continue;
10159
- const entryPath = join5(pluginsDir, entry);
9833
+ const entryPath = join4(pluginsDir, entry);
10160
9834
  let modulePath = null;
10161
9835
  try {
10162
9836
  const stat = statSync(entryPath);
10163
9837
  if (stat.isFile() && entry.endsWith(".js")) {
10164
9838
  modulePath = entryPath;
10165
9839
  } else if (stat.isDirectory()) {
10166
- const indexPath = join5(entryPath, "index.js");
9840
+ const indexPath = join4(entryPath, "index.js");
10167
9841
  if (existsSync6(indexPath)) {
10168
9842
  modulePath = indexPath;
10169
9843
  }
@@ -10176,7 +9850,7 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
10176
9850
  }
10177
9851
  }
10178
9852
  await Promise.allSettled(
10179
- pluginPaths.filter(({ path }) => path.endsWith("index.js")).map(({ entry }) => ensurePluginDeps(join5(pluginsDir, entry), entry))
9853
+ pluginPaths.filter(({ path }) => path.endsWith("index.js")).map(({ entry }) => ensurePluginDeps(join4(pluginsDir, entry), entry))
10180
9854
  );
10181
9855
  const loadResults = await Promise.allSettled(
10182
9856
  pluginPaths.map(async ({ entry, path }) => {
@@ -10187,7 +9861,7 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
10187
9861
  );
10188
9862
  for (const result of loadResults) {
10189
9863
  if (result.status === "rejected") {
10190
- log12.error(
9864
+ log10.error(
10191
9865
  `Plugin failed to load: ${result.reason instanceof Error ? result.reason.message : result.reason}`
10192
9866
  );
10193
9867
  continue;
@@ -10195,7 +9869,7 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
10195
9869
  const { entry, mod } = result.value;
10196
9870
  try {
10197
9871
  if (!mod.tools || typeof mod.tools !== "function" && !Array.isArray(mod.tools)) {
10198
- log12.warn(`Plugin "${entry}": no 'tools' array or function exported, skipping`);
9872
+ log10.warn(`Plugin "${entry}": no 'tools' array or function exported, skipping`);
10199
9873
  continue;
10200
9874
  }
10201
9875
  const adapted = adaptPlugin(
@@ -10208,13 +9882,13 @@ async function loadEnhancedPlugins(config, loadedModuleNames, sdkDeps, db) {
10208
9882
  pluginPriorities
10209
9883
  );
10210
9884
  if (loadedNames.has(adapted.name)) {
10211
- log12.warn(`Plugin "${adapted.name}" already loaded, skipping duplicate from "${entry}"`);
9885
+ log10.warn(`Plugin "${adapted.name}" already loaded, skipping duplicate from "${entry}"`);
10212
9886
  continue;
10213
9887
  }
10214
9888
  loadedNames.add(adapted.name);
10215
9889
  modules.push(adapted);
10216
9890
  } catch (err) {
10217
- log12.error(`Plugin "${entry}" failed to adapt: ${err instanceof Error ? err.message : err}`);
9891
+ log10.error(`Plugin "${entry}" failed to adapt: ${err instanceof Error ? err.message : err}`);
10218
9892
  }
10219
9893
  }
10220
9894
  return { modules, hookRegistry };
@@ -10874,13 +10548,13 @@ import {
10874
10548
  writeFileSync as writeFileSync4,
10875
10549
  unlinkSync
10876
10550
  } from "fs";
10877
- import { mkdir as mkdir2 } from "fs/promises";
10878
- import { join as join6 } from "path";
10551
+ import { mkdir } from "fs/promises";
10552
+ import { join as join5 } from "path";
10879
10553
  import { pipeline } from "stream/promises";
10880
- var log13 = createLogger("TonProxy");
10554
+ var log11 = createLogger("TonProxy");
10881
10555
  var GITHUB_REPO = "xssnick/Tonutils-Proxy";
10882
- var BINARY_DIR = join6(TELETON_ROOT, "bin");
10883
- var PID_FILE = join6(TELETON_ROOT, "ton-proxy.pid");
10556
+ var BINARY_DIR = join5(TELETON_ROOT, "bin");
10557
+ var PID_FILE = join5(TELETON_ROOT, "ton-proxy.pid");
10884
10558
  var HEALTH_CHECK_INTERVAL_MS = 3e4;
10885
10559
  var HEALTH_CHECK_TIMEOUT_MS = 5e3;
10886
10560
  var KILL_GRACE_MS = 5e3;
@@ -10896,7 +10570,7 @@ var TonProxyManager = class {
10896
10570
  /** Resolve the binary path — user-specified or auto-detected */
10897
10571
  getBinaryPath() {
10898
10572
  if (this.config.binary_path) return this.config.binary_path;
10899
- return join6(BINARY_DIR, getBinaryName());
10573
+ return join5(BINARY_DIR, getBinaryName());
10900
10574
  }
10901
10575
  /** Check if the binary exists on disk */
10902
10576
  isInstalled() {
@@ -10912,8 +10586,8 @@ var TonProxyManager = class {
10912
10586
  */
10913
10587
  async install() {
10914
10588
  const binaryName = getBinaryName();
10915
- log13.info(`Downloading TON Proxy binary (${binaryName})...`);
10916
- await mkdir2(BINARY_DIR, { recursive: true });
10589
+ log11.info(`Downloading TON Proxy binary (${binaryName})...`);
10590
+ await mkdir(BINARY_DIR, { recursive: true });
10917
10591
  const releaseUrl = `https://api.github.com/repos/${GITHUB_REPO}/releases/latest`;
10918
10592
  const releaseRes = await fetch(releaseUrl, {
10919
10593
  headers: { Accept: "application/vnd.github.v3+json" }
@@ -10924,7 +10598,7 @@ var TonProxyManager = class {
10924
10598
  const release = await releaseRes.json();
10925
10599
  const tag = release.tag_name;
10926
10600
  const downloadUrl = `https://github.com/${GITHUB_REPO}/releases/download/${tag}/${binaryName}`;
10927
- log13.info(`Downloading ${downloadUrl}`);
10601
+ log11.info(`Downloading ${downloadUrl}`);
10928
10602
  const res = await fetch(downloadUrl);
10929
10603
  if (!res.ok || !res.body) {
10930
10604
  throw new Error(`Download failed: ${res.status} ${res.statusText}`);
@@ -10933,7 +10607,7 @@ var TonProxyManager = class {
10933
10607
  const fileStream = createWriteStream(dest);
10934
10608
  await pipeline(res.body, fileStream);
10935
10609
  chmodSync(dest, 493);
10936
- log13.info(`TON Proxy installed: ${dest} (${tag})`);
10610
+ log11.info(`TON Proxy installed: ${dest} (${tag})`);
10937
10611
  }
10938
10612
  /** Kill any orphan proxy process from a previous session */
10939
10613
  killOrphan() {
@@ -10943,7 +10617,7 @@ var TonProxyManager = class {
10943
10617
  if (pid && !isNaN(pid)) {
10944
10618
  try {
10945
10619
  process.kill(pid, 0);
10946
- log13.warn(`Killing orphan TON Proxy (PID ${pid}) from previous session`);
10620
+ log11.warn(`Killing orphan TON Proxy (PID ${pid}) from previous session`);
10947
10621
  process.kill(pid, "SIGTERM");
10948
10622
  } catch {
10949
10623
  }
@@ -10960,7 +10634,7 @@ var TonProxyManager = class {
10960
10634
  const pidMatch = out.match(/pid=(\d+)/);
10961
10635
  if (pidMatch) {
10962
10636
  const pid = parseInt(pidMatch[1], 10);
10963
- log13.warn(`Port ${this.config.port} occupied by PID ${pid}, killing it`);
10637
+ log11.warn(`Port ${this.config.port} occupied by PID ${pid}, killing it`);
10964
10638
  try {
10965
10639
  process.kill(pid, "SIGTERM");
10966
10640
  } catch {
@@ -10975,7 +10649,7 @@ var TonProxyManager = class {
10975
10649
  try {
10976
10650
  writeFileSync4(PID_FILE, String(pid), { mode: 384 });
10977
10651
  } catch {
10978
- log13.warn("Failed to write TON Proxy PID file");
10652
+ log11.warn("Failed to write TON Proxy PID file");
10979
10653
  }
10980
10654
  }
10981
10655
  /** Remove PID file */
@@ -10988,7 +10662,7 @@ var TonProxyManager = class {
10988
10662
  /** Start the proxy process */
10989
10663
  async start() {
10990
10664
  if (this.isRunning()) {
10991
- log13.warn("TON Proxy is already running");
10665
+ log11.warn("TON Proxy is already running");
10992
10666
  return;
10993
10667
  }
10994
10668
  this.restartCount = 0;
@@ -10999,7 +10673,7 @@ var TonProxyManager = class {
10999
10673
  }
11000
10674
  const binaryPath = this.getBinaryPath();
11001
10675
  const port = String(this.config.port);
11002
- log13.info(`Starting TON Proxy on 127.0.0.1:${port}`);
10676
+ log11.info(`Starting TON Proxy on 127.0.0.1:${port}`);
11003
10677
  this.process = spawn(binaryPath, ["-addr", `127.0.0.1:${port}`], {
11004
10678
  cwd: BINARY_DIR,
11005
10679
  stdio: ["ignore", "pipe", "pipe"],
@@ -11007,24 +10681,24 @@ var TonProxyManager = class {
11007
10681
  });
11008
10682
  this.process.stdout?.on("data", (chunk) => {
11009
10683
  const line = chunk.toString().trim();
11010
- if (line) log13.debug(`[proxy] ${line}`);
10684
+ if (line) log11.debug(`[proxy] ${line}`);
11011
10685
  });
11012
10686
  this.process.stderr?.on("data", (chunk) => {
11013
10687
  const line = chunk.toString().trim();
11014
- if (line) log13.warn(`[proxy:err] ${line}`);
10688
+ if (line) log11.warn(`[proxy:err] ${line}`);
11015
10689
  });
11016
10690
  this.process.on("exit", (code, signal) => {
11017
- log13.info(`TON Proxy exited (code=${code}, signal=${signal})`);
10691
+ log11.info(`TON Proxy exited (code=${code}, signal=${signal})`);
11018
10692
  this.process = null;
11019
10693
  this.removePidFile();
11020
10694
  if (code !== 0 && code !== null && this.restartCount < this.maxRestarts) {
11021
10695
  this.restartCount++;
11022
- log13.warn(`Auto-restarting TON Proxy (attempt ${this.restartCount}/${this.maxRestarts})`);
11023
- this.start().catch((err) => log13.error({ err }, "Failed to auto-restart TON Proxy"));
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"));
11024
10698
  }
11025
10699
  });
11026
10700
  this.process.on("error", (err) => {
11027
- log13.error({ err }, "TON Proxy process error");
10701
+ log11.error({ err }, "TON Proxy process error");
11028
10702
  this.process = null;
11029
10703
  });
11030
10704
  this.startHealthCheck();
@@ -11042,14 +10716,14 @@ var TonProxyManager = class {
11042
10716
  });
11043
10717
  });
11044
10718
  if (this.process?.pid) this.writePidFile(this.process.pid);
11045
- log13.info(`TON Proxy running on 127.0.0.1:${port} (PID ${this.process?.pid})`);
10719
+ log11.info(`TON Proxy running on 127.0.0.1:${port} (PID ${this.process?.pid})`);
11046
10720
  }
11047
10721
  /** Stop the proxy process gracefully */
11048
10722
  async stop() {
11049
10723
  this.stopHealthCheck();
11050
10724
  if (!this.process) return;
11051
10725
  this.maxRestarts = 0;
11052
- log13.info("Stopping TON Proxy...");
10726
+ log11.info("Stopping TON Proxy...");
11053
10727
  return new Promise((resolve2) => {
11054
10728
  if (!this.process) {
11055
10729
  resolve2();
@@ -11057,7 +10731,7 @@ var TonProxyManager = class {
11057
10731
  }
11058
10732
  const forceKill = setTimeout(() => {
11059
10733
  if (this.process) {
11060
- log13.warn("TON Proxy did not exit gracefully, sending SIGKILL");
10734
+ log11.warn("TON Proxy did not exit gracefully, sending SIGKILL");
11061
10735
  this.process.kill("SIGKILL");
11062
10736
  }
11063
10737
  }, KILL_GRACE_MS);
@@ -11079,7 +10753,7 @@ var TonProxyManager = class {
11079
10753
  if (existsSync8(binaryPath)) {
11080
10754
  const { unlink } = await import("fs/promises");
11081
10755
  await unlink(binaryPath);
11082
- log13.info(`TON Proxy binary removed: ${binaryPath}`);
10756
+ log11.info(`TON Proxy binary removed: ${binaryPath}`);
11083
10757
  }
11084
10758
  }
11085
10759
  /** Get proxy status for WebUI / tools */
@@ -11113,7 +10787,7 @@ var TonProxyManager = class {
11113
10787
  }).catch(() => null);
11114
10788
  clearTimeout(timeout);
11115
10789
  if (!res) {
11116
- log13.warn("TON Proxy health check failed (no response)");
10790
+ log11.warn("TON Proxy health check failed (no response)");
11117
10791
  }
11118
10792
  } catch {
11119
10793
  }
@@ -11170,7 +10844,7 @@ var tonProxyStatusExecutor = async () => {
11170
10844
  };
11171
10845
 
11172
10846
  // src/ton-proxy/module.ts
11173
- var log14 = createLogger("TonProxyModule");
10847
+ var log12 = createLogger("TonProxyModule");
11174
10848
  var manager = null;
11175
10849
  function getTonProxyManager() {
11176
10850
  return manager;
@@ -11197,9 +10871,9 @@ var tonProxyModule = {
11197
10871
  setProxyManager(manager);
11198
10872
  try {
11199
10873
  await manager.start();
11200
- log14.info(`TON Proxy started on port ${proxyConfig.port}`);
10874
+ log12.info(`TON Proxy started on port ${proxyConfig.port}`);
11201
10875
  } catch (err) {
11202
- log14.error({ err }, "Failed to start TON Proxy");
10876
+ log12.error({ err }, "Failed to start TON Proxy");
11203
10877
  manager = null;
11204
10878
  }
11205
10879
  },