teleton 0.6.0 → 0.7.1

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 (39) hide show
  1. package/README.md +34 -31
  2. package/dist/{chunk-6L6KGATM.js → chunk-3YM57ZAV.js} +1638 -1749
  3. package/dist/{chunk-D5I7GBV7.js → chunk-FNV5FF35.js} +22 -13
  4. package/dist/{chunk-4IPJ25HE.js → chunk-HZNZT4TG.js} +1106 -711
  5. package/dist/chunk-LRCPA7SC.js +149 -0
  6. package/dist/chunk-ND2X5FWB.js +368 -0
  7. package/dist/chunk-NERLQY2H.js +421 -0
  8. package/dist/{chunk-YBA6IBGT.js → chunk-OCLG5GKI.js} +24 -24
  9. package/dist/{chunk-ADCMUNYU.js → chunk-RBU6JXD3.js} +60 -55
  10. package/dist/chunk-RCMD3U65.js +141 -0
  11. package/dist/{chunk-ECSCVEQQ.js → chunk-UCN6TI25.js} +7 -3
  12. package/dist/{chunk-WL2Q3VRD.js → chunk-UDD7FYOU.js} +12 -4
  13. package/dist/chunk-VAUJSSD3.js +20 -0
  14. package/dist/chunk-XBE4JB7C.js +8 -0
  15. package/dist/{chunk-GDCODBNO.js → chunk-XBKSS6DM.js} +2 -16
  16. package/dist/cli/index.js +878 -433
  17. package/dist/client-3VWE7NC4.js +29 -0
  18. package/dist/{get-my-gifts-KVULMBJ3.js → get-my-gifts-RI7FAXAL.js} +3 -1
  19. package/dist/index.js +17 -11
  20. package/dist/{memory-TVDOGQXS.js → memory-5SS3Q5EA.js} +7 -5
  21. package/dist/{migrate-QIEMPOMT.js → migrate-M7SJMDOL.js} +14 -9
  22. package/dist/{server-RSWVCVY3.js → server-DS5OARW6.js} +174 -85
  23. package/dist/setup-server-C7ZTPHD5.js +934 -0
  24. package/dist/{task-dependency-resolver-72DLY2HV.js → task-dependency-resolver-WKZWJLLM.js} +19 -15
  25. package/dist/{task-executor-VXB6DAV2.js → task-executor-PD3H4MLO.js} +4 -1
  26. package/dist/tool-adapter-Y3TCEQOC.js +145 -0
  27. package/dist/{tool-index-DKI2ZNOU.js → tool-index-MIVK3D7H.js} +14 -9
  28. package/dist/{transcript-7V4UNID4.js → transcript-UDJZP6NK.js} +2 -1
  29. package/dist/web/assets/complete-fZLnb5Ot.js +1 -0
  30. package/dist/web/assets/index-BqwoDycr.js +72 -0
  31. package/dist/web/assets/index-CRDIf07k.css +1 -0
  32. package/dist/web/assets/index.es-D81xLR29.js +11 -0
  33. package/dist/web/assets/login-telegram-BP7CJDmx.js +1 -0
  34. package/dist/web/assets/run-DOrDowjK.js +1 -0
  35. package/dist/web/index.html +2 -2
  36. package/package.json +7 -3
  37. package/dist/chunk-2QUJLHCZ.js +0 -362
  38. package/dist/web/assets/index-BNhrx9S1.js +0 -67
  39. package/dist/web/assets/index-CqrrRLOh.css +0 -1
@@ -0,0 +1,421 @@
1
+ import {
2
+ getCachedHttpEndpoint
3
+ } from "./chunk-QUAPFI2N.js";
4
+ import {
5
+ COINGECKO_API_URL,
6
+ tonapiFetch
7
+ } from "./chunk-XBKSS6DM.js";
8
+ import {
9
+ TELEGRAM_MAX_MESSAGE_LENGTH
10
+ } from "./chunk-RO62LO6Z.js";
11
+ import {
12
+ fetchWithTimeout
13
+ } from "./chunk-VAUJSSD3.js";
14
+ import {
15
+ TELETON_ROOT,
16
+ WORKSPACE_PATHS,
17
+ WORKSPACE_ROOT
18
+ } from "./chunk-EYWNOHMJ.js";
19
+ import {
20
+ createLogger
21
+ } from "./chunk-RCMD3U65.js";
22
+
23
+ // src/ton/wallet-service.ts
24
+ import { mnemonicNew, mnemonicToPrivateKey, mnemonicValidate } from "@ton/crypto";
25
+ import { WalletContractV5R1, TonClient, fromNano } from "@ton/ton";
26
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
27
+ import { join, dirname } from "path";
28
+ var log = createLogger("TON");
29
+ var WALLET_FILE = join(TELETON_ROOT, "wallet.json");
30
+ var _walletCache;
31
+ var _keyPairCache = null;
32
+ async function generateWallet() {
33
+ const mnemonic = await mnemonicNew(24);
34
+ const keyPair = await mnemonicToPrivateKey(mnemonic);
35
+ const wallet = WalletContractV5R1.create({
36
+ workchain: 0,
37
+ publicKey: keyPair.publicKey
38
+ });
39
+ const address = wallet.address.toString({ bounceable: true, testOnly: false });
40
+ return {
41
+ version: "w5r1",
42
+ address,
43
+ publicKey: keyPair.publicKey.toString("hex"),
44
+ mnemonic,
45
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
46
+ };
47
+ }
48
+ function saveWallet(wallet) {
49
+ const dir = dirname(WALLET_FILE);
50
+ if (!existsSync(dir)) {
51
+ mkdirSync(dir, { recursive: true });
52
+ }
53
+ writeFileSync(WALLET_FILE, JSON.stringify(wallet, null, 2), { encoding: "utf-8", mode: 384 });
54
+ _walletCache = void 0;
55
+ _keyPairCache = null;
56
+ }
57
+ function loadWallet() {
58
+ if (_walletCache !== void 0) return _walletCache;
59
+ if (!existsSync(WALLET_FILE)) {
60
+ _walletCache = null;
61
+ return null;
62
+ }
63
+ try {
64
+ const content = readFileSync(WALLET_FILE, "utf-8");
65
+ const parsed = JSON.parse(content);
66
+ if (!parsed.mnemonic || !Array.isArray(parsed.mnemonic) || parsed.mnemonic.length !== 24) {
67
+ throw new Error("Invalid wallet.json: mnemonic must be a 24-word array");
68
+ }
69
+ _walletCache = parsed;
70
+ return _walletCache;
71
+ } catch (error) {
72
+ log.error({ err: error }, "Failed to load wallet");
73
+ _walletCache = null;
74
+ return null;
75
+ }
76
+ }
77
+ function walletExists() {
78
+ return existsSync(WALLET_FILE);
79
+ }
80
+ async function importWallet(mnemonic) {
81
+ const valid = await mnemonicValidate(mnemonic);
82
+ if (!valid) {
83
+ throw new Error("Invalid mnemonic: words do not form a valid TON seed phrase");
84
+ }
85
+ const keyPair = await mnemonicToPrivateKey(mnemonic);
86
+ const wallet = WalletContractV5R1.create({
87
+ workchain: 0,
88
+ publicKey: keyPair.publicKey
89
+ });
90
+ const address = wallet.address.toString({ bounceable: true, testOnly: false });
91
+ return {
92
+ version: "w5r1",
93
+ address,
94
+ publicKey: keyPair.publicKey.toString("hex"),
95
+ mnemonic,
96
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
97
+ };
98
+ }
99
+ function getWalletAddress() {
100
+ const wallet = loadWallet();
101
+ return wallet?.address || null;
102
+ }
103
+ async function getKeyPair() {
104
+ if (_keyPairCache) return _keyPairCache;
105
+ const wallet = loadWallet();
106
+ if (!wallet) return null;
107
+ _keyPairCache = await mnemonicToPrivateKey(wallet.mnemonic);
108
+ return _keyPairCache;
109
+ }
110
+ async function getWalletBalance(address) {
111
+ try {
112
+ const endpoint = await getCachedHttpEndpoint();
113
+ const client = new TonClient({ endpoint });
114
+ const { Address } = await import("@ton/core");
115
+ const addressObj = Address.parse(address);
116
+ const balance = await client.getBalance(addressObj);
117
+ const balanceFormatted = fromNano(balance);
118
+ return {
119
+ balance: balanceFormatted,
120
+ balanceNano: balance.toString()
121
+ };
122
+ } catch (error) {
123
+ log.error({ err: error }, "Failed to get balance");
124
+ return null;
125
+ }
126
+ }
127
+ var TON_PRICE_CACHE_TTL_MS = 3e4;
128
+ var _tonPriceCache = null;
129
+ async function getTonPrice() {
130
+ if (_tonPriceCache && Date.now() - _tonPriceCache.timestamp < TON_PRICE_CACHE_TTL_MS) {
131
+ return { ..._tonPriceCache };
132
+ }
133
+ try {
134
+ const response = await tonapiFetch(`/rates?tokens=ton&currencies=usd`);
135
+ if (response.ok) {
136
+ const data = await response.json();
137
+ const price = data?.rates?.TON?.prices?.USD;
138
+ if (typeof price === "number" && price > 0) {
139
+ _tonPriceCache = { usd: price, source: "TonAPI", timestamp: Date.now() };
140
+ return _tonPriceCache;
141
+ }
142
+ }
143
+ } catch {
144
+ }
145
+ try {
146
+ const response = await fetchWithTimeout(
147
+ `${COINGECKO_API_URL}/simple/price?ids=the-open-network&vs_currencies=usd`
148
+ );
149
+ if (!response.ok) {
150
+ throw new Error(`CoinGecko API error: ${response.status}`);
151
+ }
152
+ const data = await response.json();
153
+ const price = data["the-open-network"]?.usd;
154
+ if (typeof price === "number" && price > 0) {
155
+ _tonPriceCache = { usd: price, source: "CoinGecko", timestamp: Date.now() };
156
+ return _tonPriceCache;
157
+ }
158
+ } catch (error) {
159
+ log.error({ err: error }, "Failed to get TON price");
160
+ }
161
+ return null;
162
+ }
163
+
164
+ // src/config/schema.ts
165
+ import { z } from "zod";
166
+ var DMPolicy = z.enum(["pairing", "allowlist", "open", "disabled"]);
167
+ var GroupPolicy = z.enum(["open", "allowlist", "disabled"]);
168
+ var SessionResetPolicySchema = z.object({
169
+ daily_reset_enabled: z.boolean().default(true).describe("Enable daily session reset"),
170
+ daily_reset_hour: z.number().min(0).max(23).default(4).describe("Hour of day (0-23) to reset sessions"),
171
+ idle_expiry_enabled: z.boolean().default(true).describe("Enable session reset after idle period"),
172
+ idle_expiry_minutes: z.number().default(1440).describe("Minutes of inactivity before session reset (default: 24h)")
173
+ });
174
+ var AgentConfigSchema = z.object({
175
+ provider: z.enum([
176
+ "anthropic",
177
+ "openai",
178
+ "google",
179
+ "xai",
180
+ "groq",
181
+ "openrouter",
182
+ "moonshot",
183
+ "mistral",
184
+ "cocoon",
185
+ "local"
186
+ ]).default("anthropic"),
187
+ api_key: z.string().default(""),
188
+ base_url: z.string().url().optional().describe("Base URL for local LLM server (e.g. http://localhost:11434/v1)"),
189
+ model: z.string().default("claude-opus-4-5-20251101"),
190
+ utility_model: z.string().optional().describe("Cheap model for summarization (auto-detected if omitted)"),
191
+ max_tokens: z.number().default(4096),
192
+ temperature: z.number().default(0.7),
193
+ system_prompt: z.string().nullable().default(null),
194
+ max_agentic_iterations: z.number().default(5).describe("Maximum number of agentic loop iterations (tool call \u2192 result \u2192 tool call cycles)"),
195
+ session_reset_policy: SessionResetPolicySchema.default(SessionResetPolicySchema.parse({}))
196
+ });
197
+ var TelegramConfigSchema = z.object({
198
+ api_id: z.number(),
199
+ api_hash: z.string(),
200
+ phone: z.string(),
201
+ session_name: z.string().default("teleton_session"),
202
+ session_path: z.string().default("~/.teleton"),
203
+ dm_policy: DMPolicy.default("pairing"),
204
+ allow_from: z.array(z.number()).default([]),
205
+ group_policy: GroupPolicy.default("open"),
206
+ group_allow_from: z.array(z.number()).default([]),
207
+ require_mention: z.boolean().default(true),
208
+ max_message_length: z.number().default(TELEGRAM_MAX_MESSAGE_LENGTH),
209
+ typing_simulation: z.boolean().default(true),
210
+ rate_limit_messages_per_second: z.number().default(1),
211
+ rate_limit_groups_per_minute: z.number().default(20),
212
+ admin_ids: z.array(z.number()).default([]),
213
+ agent_channel: z.string().nullable().default(null),
214
+ owner_name: z.string().optional().describe("Owner's first name (e.g., 'Alex')"),
215
+ owner_username: z.string().optional().describe("Owner's Telegram username (without @)"),
216
+ owner_id: z.number().optional().describe("Owner's Telegram user ID"),
217
+ debounce_ms: z.number().default(1500).describe("Debounce delay in milliseconds for group messages (0 = disabled)"),
218
+ bot_token: z.string().optional().describe("Telegram Bot token from @BotFather for inline deal buttons"),
219
+ bot_username: z.string().optional().describe("Bot username without @ (e.g., 'teleton_deals_bot')")
220
+ });
221
+ var StorageConfigSchema = z.object({
222
+ sessions_file: z.string().default("~/.teleton/sessions.json"),
223
+ pairing_file: z.string().default("~/.teleton/pairing.json"),
224
+ memory_file: z.string().default("~/.teleton/memory.json"),
225
+ history_limit: z.number().default(100)
226
+ });
227
+ var MetaConfigSchema = z.object({
228
+ version: z.string().default("1.0.0"),
229
+ created_at: z.string().optional(),
230
+ last_modified_at: z.string().optional(),
231
+ onboard_command: z.string().default("teleton setup")
232
+ });
233
+ var _DealsObject = z.object({
234
+ enabled: z.boolean().default(true),
235
+ expiry_seconds: z.number().default(120),
236
+ buy_max_floor_percent: z.number().default(100),
237
+ sell_min_floor_percent: z.number().default(105),
238
+ poll_interval_ms: z.number().default(5e3),
239
+ max_verification_retries: z.number().default(12),
240
+ expiry_check_interval_ms: z.number().default(6e4)
241
+ });
242
+ var DealsConfigSchema = _DealsObject.default(_DealsObject.parse({}));
243
+ var _WebUIObject = z.object({
244
+ enabled: z.boolean().default(false).describe("Enable WebUI server"),
245
+ port: z.number().default(7777).describe("HTTP server port"),
246
+ host: z.string().default("127.0.0.1").describe("Bind address (localhost only for security)"),
247
+ auth_token: z.string().optional().describe("Bearer token for API auth (auto-generated if omitted)"),
248
+ cors_origins: z.array(z.string()).default(["http://localhost:5173", "http://localhost:7777"]).describe("Allowed CORS origins for development"),
249
+ log_requests: z.boolean().default(false).describe("Log all HTTP requests")
250
+ });
251
+ var WebUIConfigSchema = _WebUIObject.default(_WebUIObject.parse({}));
252
+ var _EmbeddingObject = z.object({
253
+ provider: z.enum(["local", "anthropic", "none"]).default("local").describe("Embedding provider: local (ONNX), anthropic (API), or none (FTS5-only)"),
254
+ model: z.string().optional().describe("Model override (default: Xenova/all-MiniLM-L6-v2 for local)")
255
+ });
256
+ var EmbeddingConfigSchema = _EmbeddingObject.default(_EmbeddingObject.parse({}));
257
+ var _LoggingObject = z.object({
258
+ level: z.enum(["trace", "debug", "info", "warn", "error", "fatal"]).default("info").describe("Log level (trace/debug/info/warn/error/fatal)"),
259
+ pretty: z.boolean().default(true).describe("Enable pino-pretty formatting (human-readable, colored output)")
260
+ });
261
+ var LoggingConfigSchema = _LoggingObject.default(_LoggingObject.parse({}));
262
+ var _DevObject = z.object({
263
+ hot_reload: z.boolean().default(false).describe("Enable plugin hot-reload (watches ~/.teleton/plugins/ for changes)")
264
+ });
265
+ var DevConfigSchema = _DevObject.default(_DevObject.parse({}));
266
+ var McpServerSchema = z.object({
267
+ command: z.string().optional().describe("Stdio command (e.g. 'npx @modelcontextprotocol/server-filesystem /tmp')"),
268
+ args: z.array(z.string()).optional().describe("Explicit args array (overrides command splitting)"),
269
+ env: z.record(z.string(), z.string()).optional().describe("Environment variables for stdio server"),
270
+ url: z.string().url().optional().describe("SSE/HTTP endpoint URL (alternative to command)"),
271
+ scope: z.enum(["always", "dm-only", "group-only", "admin-only"]).default("always").describe("Tool scope"),
272
+ enabled: z.boolean().default(true).describe("Enable/disable this server")
273
+ }).refine((s) => s.command || s.url, {
274
+ message: "Each MCP server needs either 'command' (stdio) or 'url' (SSE/HTTP)"
275
+ });
276
+ var _McpObject = z.object({
277
+ servers: z.record(z.string(), McpServerSchema).default({})
278
+ });
279
+ var McpConfigSchema = _McpObject.default(_McpObject.parse({}));
280
+ var _ToolRagObject = z.object({
281
+ enabled: z.boolean().default(false).describe("Enable semantic tool retrieval (Tool RAG)"),
282
+ top_k: z.number().default(25).describe("Max tools to retrieve per LLM call"),
283
+ always_include: z.array(z.string()).default([
284
+ "telegram_send_message",
285
+ "telegram_reply_message",
286
+ "telegram_send_photo",
287
+ "telegram_send_document",
288
+ "journal_*",
289
+ "workspace_*",
290
+ "web_*"
291
+ ]).describe("Tool name patterns always included (prefix glob with *)"),
292
+ skip_unlimited_providers: z.boolean().default(false).describe("Skip Tool RAG for providers with no tool limit (e.g. Anthropic)")
293
+ });
294
+ var ToolRagConfigSchema = _ToolRagObject.default(_ToolRagObject.parse({}));
295
+ var ConfigSchema = z.object({
296
+ meta: MetaConfigSchema.default(MetaConfigSchema.parse({})),
297
+ agent: AgentConfigSchema,
298
+ telegram: TelegramConfigSchema,
299
+ storage: StorageConfigSchema.default(StorageConfigSchema.parse({})),
300
+ embedding: EmbeddingConfigSchema,
301
+ deals: DealsConfigSchema,
302
+ webui: WebUIConfigSchema,
303
+ logging: LoggingConfigSchema,
304
+ dev: DevConfigSchema,
305
+ tool_rag: ToolRagConfigSchema,
306
+ mcp: McpConfigSchema,
307
+ plugins: z.record(z.string(), z.unknown()).default({}).describe("Per-plugin config (key = plugin name with underscores)"),
308
+ cocoon: z.object({
309
+ port: z.number().min(1).max(65535).default(1e4).describe("HTTP port of the cocoon-cli proxy")
310
+ }).optional().describe("Cocoon Network \u2014 expects external cocoon-cli running on this port"),
311
+ tonapi_key: z.string().optional().describe("TonAPI key for higher rate limits (from @tonapi_bot)"),
312
+ tavily_api_key: z.string().optional().describe("Tavily API key for web search & extract (free at https://tavily.com)")
313
+ });
314
+
315
+ // src/workspace/manager.ts
316
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, copyFileSync } from "fs";
317
+ import { join as join2, dirname as dirname2 } from "path";
318
+ import { fileURLToPath } from "url";
319
+ var log2 = createLogger("Workspace");
320
+ function findPackageRoot() {
321
+ let dir = dirname2(fileURLToPath(import.meta.url));
322
+ for (let i = 0; i < 10; i++) {
323
+ if (existsSync2(join2(dir, "package.json"))) return dir;
324
+ dir = dirname2(dir);
325
+ }
326
+ return process.cwd();
327
+ }
328
+ var TEMPLATES_DIR = join2(findPackageRoot(), "src", "templates");
329
+ async function ensureWorkspace(config) {
330
+ if (!existsSync2(TELETON_ROOT)) {
331
+ mkdirSync2(TELETON_ROOT, { recursive: true });
332
+ log2.info(`Created Teleton root at ${TELETON_ROOT}`);
333
+ }
334
+ if (!existsSync2(WORKSPACE_ROOT)) {
335
+ mkdirSync2(WORKSPACE_ROOT, { recursive: true });
336
+ log2.info(`Created workspace at ${WORKSPACE_ROOT}`);
337
+ }
338
+ const directories = [
339
+ WORKSPACE_PATHS.MEMORY_DIR,
340
+ WORKSPACE_PATHS.DOWNLOADS_DIR,
341
+ WORKSPACE_PATHS.UPLOADS_DIR,
342
+ WORKSPACE_PATHS.TEMP_DIR,
343
+ WORKSPACE_PATHS.MEMES_DIR
344
+ ];
345
+ for (const dir of directories) {
346
+ if (!existsSync2(dir)) {
347
+ mkdirSync2(dir, { recursive: true });
348
+ }
349
+ }
350
+ const workspace = {
351
+ root: TELETON_ROOT,
352
+ workspace: WORKSPACE_ROOT,
353
+ // Workspace files
354
+ soulPath: WORKSPACE_PATHS.SOUL,
355
+ memoryPath: WORKSPACE_PATHS.MEMORY,
356
+ identityPath: WORKSPACE_PATHS.IDENTITY,
357
+ userPath: WORKSPACE_PATHS.USER,
358
+ strategyPath: WORKSPACE_PATHS.STRATEGY,
359
+ securityPath: WORKSPACE_PATHS.SECURITY,
360
+ // Workspace directories
361
+ memoryDir: WORKSPACE_PATHS.MEMORY_DIR,
362
+ downloadsDir: WORKSPACE_PATHS.DOWNLOADS_DIR,
363
+ uploadsDir: WORKSPACE_PATHS.UPLOADS_DIR,
364
+ tempDir: WORKSPACE_PATHS.TEMP_DIR,
365
+ memesDir: WORKSPACE_PATHS.MEMES_DIR,
366
+ // Protected files (outside workspace)
367
+ sessionPath: join2(TELETON_ROOT, "telegram_session.txt"),
368
+ configPath: join2(TELETON_ROOT, "config.yaml"),
369
+ walletPath: join2(TELETON_ROOT, "wallet.json")
370
+ };
371
+ if (config?.ensureTemplates) {
372
+ await bootstrapTemplates(workspace);
373
+ }
374
+ return workspace;
375
+ }
376
+ async function bootstrapTemplates(workspace) {
377
+ const templates = [
378
+ { name: "SOUL.md", path: workspace.soulPath },
379
+ { name: "MEMORY.md", path: workspace.memoryPath },
380
+ { name: "IDENTITY.md", path: workspace.identityPath },
381
+ { name: "USER.md", path: workspace.userPath },
382
+ { name: "SECURITY.md", path: workspace.securityPath },
383
+ { name: "STRATEGY.md", path: workspace.strategyPath }
384
+ ];
385
+ for (const template of templates) {
386
+ if (!existsSync2(template.path)) {
387
+ const templateSource = join2(TEMPLATES_DIR, template.name);
388
+ if (existsSync2(templateSource)) {
389
+ copyFileSync(templateSource, template.path);
390
+ log2.info(`Created ${template.name}`);
391
+ }
392
+ }
393
+ }
394
+ }
395
+ function isNewWorkspace(workspace) {
396
+ return !existsSync2(workspace.configPath);
397
+ }
398
+ function loadTemplate(name) {
399
+ const templatePath = join2(TEMPLATES_DIR, name);
400
+ if (!existsSync2(templatePath)) {
401
+ throw new Error(`Template ${name} not found at ${templatePath}`);
402
+ }
403
+ return readFileSync2(templatePath, "utf-8");
404
+ }
405
+
406
+ export {
407
+ DealsConfigSchema,
408
+ ConfigSchema,
409
+ ensureWorkspace,
410
+ isNewWorkspace,
411
+ loadTemplate,
412
+ generateWallet,
413
+ saveWallet,
414
+ loadWallet,
415
+ walletExists,
416
+ importWallet,
417
+ getWalletAddress,
418
+ getKeyPair,
419
+ getWalletBalance,
420
+ getTonPrice
421
+ };
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  TELETON_ROOT
3
3
  } from "./chunk-EYWNOHMJ.js";
4
+ import {
5
+ createLogger
6
+ } from "./chunk-RCMD3U65.js";
4
7
 
5
8
  // src/session/transcript.ts
6
9
  import {
@@ -14,6 +17,7 @@ import {
14
17
  statSync
15
18
  } from "fs";
16
19
  import { join } from "path";
20
+ var log = createLogger("Session");
17
21
  var SESSIONS_DIR = join(TELETON_ROOT, "sessions");
18
22
  function getTranscriptPath(sessionId) {
19
23
  return join(SESSIONS_DIR, `${sessionId}.jsonl`);
@@ -30,17 +34,15 @@ function appendToTranscript(sessionId, message) {
30
34
  try {
31
35
  appendFileSync(transcriptPath, line, "utf-8");
32
36
  } catch (error) {
33
- console.error(`Failed to append to transcript ${sessionId}:`, error);
37
+ log.error({ err: error }, `Failed to append to transcript ${sessionId}`);
34
38
  }
35
39
  }
36
40
  function extractToolCallIds(msg) {
37
41
  const ids = /* @__PURE__ */ new Set();
38
42
  if (msg.role === "assistant" && Array.isArray(msg.content)) {
39
43
  for (const block of msg.content) {
40
- const blockType = block.type;
41
- if (blockType === "toolCall" || blockType === "tool_use") {
42
- const id = block.id || block.toolCallId || block.tool_use_id;
43
- if (id) ids.add(id);
44
+ if (block.type === "toolCall") {
45
+ if (block.id) ids.add(block.id);
44
46
  }
45
47
  }
46
48
  }
@@ -55,17 +57,15 @@ function sanitizeMessages(messages) {
55
57
  if (msg.role === "assistant") {
56
58
  const newToolIds = extractToolCallIds(msg);
57
59
  if (pendingToolCallIds.size > 0 && newToolIds.size > 0) {
58
- console.warn(
59
- `\u26A0\uFE0F Found ${pendingToolCallIds.size} pending tool results that were never received`
60
- );
60
+ log.warn(`Found ${pendingToolCallIds.size} pending tool results that were never received`);
61
61
  }
62
62
  pendingToolCallIds = newToolIds;
63
63
  sanitized.push(msg);
64
- } else if (msg.role === "toolResult" || msg.role === "tool_result") {
65
- const toolCallId = msg.toolCallId || msg.tool_use_id || msg.tool_call_id;
64
+ } else if (msg.role === "toolResult") {
65
+ const toolCallId = msg.toolCallId;
66
66
  if (!toolCallId || typeof toolCallId !== "string") {
67
67
  removedCount++;
68
- console.warn(`\u{1F9F9} Removing toolResult with missing/invalid toolCallId`);
68
+ log.warn(`Removing toolResult with missing/invalid toolCallId`);
69
69
  continue;
70
70
  }
71
71
  if (pendingToolCallIds.has(toolCallId)) {
@@ -73,13 +73,13 @@ function sanitizeMessages(messages) {
73
73
  sanitized.push(msg);
74
74
  } else {
75
75
  removedCount++;
76
- console.warn(`\u{1F9F9} Removing orphaned toolResult: ${toolCallId.slice(0, 20)}...`);
76
+ log.warn(`Removing orphaned toolResult: ${toolCallId.slice(0, 20)}...`);
77
77
  continue;
78
78
  }
79
79
  } else if (msg.role === "user") {
80
80
  if (pendingToolCallIds.size > 0) {
81
- console.warn(
82
- `\u26A0\uFE0F User message arrived while ${pendingToolCallIds.size} tool results pending - marking them as orphaned`
81
+ log.warn(
82
+ `User message arrived while ${pendingToolCallIds.size} tool results pending - marking them as orphaned`
83
83
  );
84
84
  pendingToolCallIds.clear();
85
85
  }
@@ -89,7 +89,7 @@ function sanitizeMessages(messages) {
89
89
  }
90
90
  }
91
91
  if (removedCount > 0) {
92
- console.log(`\u{1F9F9} Sanitized ${removedCount} orphaned/out-of-order toolResult(s) from transcript`);
92
+ log.info(`Sanitized ${removedCount} orphaned/out-of-order toolResult(s) from transcript`);
93
93
  }
94
94
  return sanitized;
95
95
  }
@@ -107,16 +107,16 @@ function readTranscript(sessionId) {
107
107
  return JSON.parse(line);
108
108
  } catch {
109
109
  corruptCount++;
110
- console.warn(`\u26A0\uFE0F Skipping corrupt line ${i + 1} in transcript ${sessionId}`);
110
+ log.warn(`Skipping corrupt line ${i + 1} in transcript ${sessionId}`);
111
111
  return null;
112
112
  }
113
113
  }).filter(Boolean);
114
114
  if (corruptCount > 0) {
115
- console.warn(`\u26A0\uFE0F ${corruptCount} corrupt line(s) skipped in transcript ${sessionId}`);
115
+ log.warn(`${corruptCount} corrupt line(s) skipped in transcript ${sessionId}`);
116
116
  }
117
117
  return sanitizeMessages(messages);
118
118
  } catch (error) {
119
- console.error(`Failed to read transcript ${sessionId}:`, error);
119
+ log.error({ err: error }, `Failed to read transcript ${sessionId}`);
120
120
  return [];
121
121
  }
122
122
  }
@@ -138,10 +138,10 @@ function deleteTranscript(sessionId) {
138
138
  }
139
139
  try {
140
140
  unlinkSync(transcriptPath);
141
- console.log(`\u{1F5D1}\uFE0F Deleted transcript: ${sessionId}`);
141
+ log.info(`Deleted transcript: ${sessionId}`);
142
142
  return true;
143
143
  } catch (error) {
144
- console.error(`Failed to delete transcript ${sessionId}:`, error);
144
+ log.error({ err: error }, `Failed to delete transcript ${sessionId}`);
145
145
  return false;
146
146
  }
147
147
  }
@@ -154,10 +154,10 @@ function archiveTranscript(sessionId) {
154
154
  }
155
155
  try {
156
156
  renameSync(transcriptPath, archivePath);
157
- console.log(`\u{1F4E6} Archived transcript: ${sessionId} \u2192 ${timestamp}.archived`);
157
+ log.info(`Archived transcript: ${sessionId} \u2192 ${timestamp}.archived`);
158
158
  return true;
159
159
  } catch (error) {
160
- console.error(`Failed to archive transcript ${sessionId}:`, error);
160
+ log.error({ err: error }, `Failed to archive transcript ${sessionId}`);
161
161
  return false;
162
162
  }
163
163
  }
@@ -179,10 +179,10 @@ function cleanupOldTranscripts(maxAgeDays = 30) {
179
179
  }
180
180
  }
181
181
  } catch (error) {
182
- console.error("Failed to cleanup old transcripts:", error);
182
+ log.error({ err: error }, "Failed to cleanup old transcripts");
183
183
  }
184
184
  if (deleted > 0) {
185
- console.log(`\u{1F9F9} Cleaned up ${deleted} transcript(s) older than ${maxAgeDays} days`);
185
+ log.info(`Cleaned up ${deleted} transcript(s) older than ${maxAgeDays} days`);
186
186
  }
187
187
  return deleted;
188
188
  }