teleton 0.8.5 → 0.8.6

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 (80) hide show
  1. package/README.md +24 -5
  2. package/dist/{bootstrap-SPDT3XBQ.js → bootstrap-PFBH6ALD.js} +10 -7
  3. package/dist/bridge-guards-HZTNH7IB.js +9 -0
  4. package/dist/{chunk-FSL2MOYK.js → chunk-2UUGRY5B.js} +144 -163
  5. package/dist/{chunk-LM6AL6LN.js → chunk-4MFN75ZK.js} +4449 -2776
  6. package/dist/{chunk-GUX6ZFVF.js → chunk-4MG2AROG.js} +4 -6
  7. package/dist/{chunk-6U6VA2OT.js → chunk-6IFNQWIM.js} +7276 -7300
  8. package/dist/chunk-7KI25UJU.js +215 -0
  9. package/dist/chunk-AX5NBEHX.js +12 -0
  10. package/dist/{chunk-7ZXUUDQQ.js → chunk-BLUES3FJ.js} +79 -100
  11. package/dist/{chunk-KYSAHDYE.js → chunk-BT2I3ETV.js} +1 -1
  12. package/dist/chunk-CXTZPOTA.js +107 -0
  13. package/dist/{chunk-4KURCUWD.js → chunk-D3GT6YIY.js} +59 -7
  14. package/dist/chunk-EKCXKL5M.js +53 -0
  15. package/dist/{chunk-5K4YDCVU.js → chunk-F6S3L3OV.js} +3 -3
  16. package/dist/{chunk-L3LPVF4Z.js → chunk-J4WDJ7XS.js} +2 -2
  17. package/dist/{chunk-Z63KUQX4.js → chunk-JYF2MM5I.js} +120 -110
  18. package/dist/{chunk-NVKBBTI6.js → chunk-K3QSIIMZ.js} +9 -6
  19. package/dist/chunk-OMQIAWEU.js +273 -0
  20. package/dist/chunk-PCT7GYBP.js +274 -0
  21. package/dist/{chunk-35X3V6OW.js → chunk-QYZBWU2D.js} +5 -5
  22. package/dist/{chunk-WTDAICGT.js → chunk-R6W4DJRK.js} +7 -7
  23. package/dist/{chunk-5SEMA47R.js → chunk-RILOEIK6.js} +1 -1
  24. package/dist/{chunk-6OOHHJ4N.js → chunk-TFTNZZDH.js} +20 -20
  25. package/dist/chunk-TTOZCZWE.js +96 -0
  26. package/dist/chunk-UJ54YT2T.js +12 -0
  27. package/dist/{chunk-2MZP75SH.js → chunk-ULVL2W3D.js} +152 -256
  28. package/dist/{chunk-NQ6FZKCE.js → chunk-V3S3NXBQ.js} +3 -1
  29. package/dist/{chunk-H7MFXJZK.js → chunk-WSL4KIOI.js} +31 -26
  30. package/dist/{chunk-PK3TVFBT.js → chunk-Z5WY7BSB.js} +5 -5
  31. package/dist/{chunk-LD24DWWE.js → chunk-ZGKE3OTA.js} +110 -47
  32. package/dist/{chunk-M6M4DCDU.js → chunk-ZHRDETCX.js} +3 -3
  33. package/dist/cli/index.d.ts +2 -0
  34. package/dist/cli/index.js +263 -163
  35. package/dist/{client-G62EZT6U.js → client-S5UIK6OG.js} +9 -7
  36. package/dist/daily-logs-3WXGYAQF.js +25 -0
  37. package/dist/{get-my-gifts-Y7EN7RK4.js → get-my-gifts-3YSYM3LI.js} +3 -2
  38. package/dist/{harden-permissions-6BLHRCQJ.js → harden-permissions-PV5SGV5D.js} +1 -1
  39. package/dist/index.d.ts +923 -0
  40. package/dist/index.js +28 -20
  41. package/dist/knowledge-RRWUIO3G.js +19 -0
  42. package/dist/{local-HQ3UJ7KR.js → local-MSZAXWUL.js} +2 -2
  43. package/dist/mcp-loader-OELDFR63.js +15 -0
  44. package/dist/{memory-BJH724PQ.js → memory-6U6HGRK2.js} +22 -12
  45. package/dist/{memory-hook-LUAKTXU5.js → memory-hook-T7Y235KY.js} +7 -7
  46. package/dist/messages-KV5ADNJB.js +17 -0
  47. package/dist/{migrate-C4LBLOZH.js → migrate-AX3HOKOO.js} +9 -7
  48. package/dist/{server-4J56HS62.js → server-MFRYOGHR.js} +20 -16
  49. package/dist/{server-I6TYJ36S.js → server-SFLCAZFR.js} +220 -19
  50. package/dist/{setup-server-VJ3MGUSM.js → setup-server-YWAPKZVE.js} +14 -13
  51. package/dist/{store-2IGAMTES.js → store-PGHQASBC.js} +10 -8
  52. package/dist/{task-dependency-resolver-CQ432Z7J.js → task-dependency-resolver-YQKADDEU.js} +24 -10
  53. package/dist/{task-executor-JELRREUV.js → task-executor-LWAWD225.js} +4 -4
  54. package/dist/{tool-adapter-IVX2XQJE.js → tool-adapter-VKLUZSQS.js} +1 -1
  55. package/dist/{tool-index-XPCMWBYY.js → tool-index-YEWDF5CK.js} +4 -4
  56. package/dist/{transcript-OEO3HA4Z.js → transcript-4Y3Z2BJ3.js} +2 -2
  57. package/dist/web/assets/Config-MNxA69ib.js +1 -0
  58. package/dist/web/assets/Conversations-Dk958paA.js +1 -0
  59. package/dist/web/assets/Dashboard-dM18fGOm.js +1 -0
  60. package/dist/web/assets/Hooks-D2griQnI.js +1 -0
  61. package/dist/web/assets/Mcp-CtWNzwsz.js +1 -0
  62. package/dist/web/assets/Memory-CfLwH45G.js +1 -0
  63. package/dist/web/assets/Plugins-3hoJprFo.js +1 -0
  64. package/dist/web/assets/SearchInput-CpcETdpE.js +1 -0
  65. package/dist/web/assets/Soul-BSxE73aK.js +1 -0
  66. package/dist/web/assets/Tasks-DkCkfu3A.js +1 -0
  67. package/dist/web/assets/TelegramSettingsPanel-BRzc5G6e.js +1 -0
  68. package/dist/web/assets/Tools-Du8B8Mb4.js +1 -0
  69. package/dist/web/assets/Wallet-BLILP2Gn.js +1 -0
  70. package/dist/web/assets/Workspace-qklcXpXV.js +1 -0
  71. package/dist/web/assets/index-BwEPTTKp.js +90 -0
  72. package/dist/web/assets/index-noejUsK7.css +1 -0
  73. package/dist/web/assets/{index.es-eSR4Qv6s.js → index.es-DdpKlnGb.js} +1 -1
  74. package/dist/web/assets/useToolManager-tdxkKn3H.js +1 -0
  75. package/dist/web/assets/utils-CnsbSMo4.js +1 -0
  76. package/dist/web/index.html +2 -2
  77. package/package.json +7 -8
  78. package/dist/web/assets/index-DmlyQVhR.css +0 -1
  79. package/dist/web/assets/index-Dn5ZH1Y6.js +0 -80
  80. package/dist/{chunk-WFTC3JJW.js → chunk-3NO7QU7W.js} +1 -1
package/README.md CHANGED
@@ -146,6 +146,26 @@ Agent: [Displays uptime, model, tool count, wallet balance]
146
146
 
147
147
  ---
148
148
 
149
+ ## User Mode vs Bot Mode
150
+
151
+ Teleton can run as a **user account** (MTProto) or a **Telegram bot** (Bot API). Set `telegram.mode` in your config:
152
+
153
+ | | User Mode (default) | Bot Mode |
154
+ |---|---|---|
155
+ | **Auth** | Phone + api_id + api_hash | Bot token from @BotFather |
156
+ | **Protocol** | MTProto (GramJS) | Bot API (Grammy) |
157
+ | **Tools** | 135+ | 67 (11 Telegram + 56 non-Telegram) |
158
+ | **Risk** | Account ban possible | No ban risk |
159
+ | **Dialogs/History** | Full access | Not available |
160
+ | **Media sending** | All types | Photos only (v1) |
161
+ | **Inline keyboards** | Via bot_token | Native |
162
+ | **Stars/Gifts** | Full access | Not available |
163
+ | **Profile editing** | Yes | No |
164
+ | **Scheduled tasks** | Yes | Not available |
165
+ | **Setup** | `telegram.mode: "user"` | `telegram.mode: "bot"` |
166
+
167
+ ---
168
+
149
169
  ## Configuration
150
170
 
151
171
  The `teleton setup` wizard generates a fully configured `~/.teleton/config.yaml` file. Manual editing is only necessary if you want to adjust settings after the initial setup.
@@ -157,6 +177,10 @@ agent:
157
177
  model: "claude-opus-4-6"
158
178
  utility_model: "claude-haiku-4-5-20251001" # for summarization, compaction, vision
159
179
  max_agentic_iterations: 5
180
+ session_reset_policy:
181
+ daily_reset_enabled: true
182
+ daily_reset_hour: 4
183
+ idle_expiry_minutes: 1440 # 24h idle → new session
160
184
 
161
185
  telegram:
162
186
  dm_policy: "admin-only" # open | allowlist | admin-only | disabled
@@ -171,11 +195,6 @@ telegram:
171
195
  bot_token: "123456:ABC-DEF..."
172
196
  bot_username: "your_bot"
173
197
 
174
- session_reset_policy:
175
- daily_reset_enabled: true
176
- daily_reset_hour: 4
177
- idle_expiry_minutes: 1440 # 24h idle → new session
178
-
179
198
  webui: # Optional: Web dashboard
180
199
  enabled: false # Enable WebUI server
181
200
  port: 7777 # HTTP server port
@@ -1,20 +1,23 @@
1
1
  import {
2
2
  AgentLifecycle
3
- } from "./chunk-NVKBBTI6.js";
3
+ } from "./chunk-K3QSIIMZ.js";
4
4
  import {
5
5
  configExists,
6
- ensureWorkspace,
7
6
  getDefaultConfigPath
8
- } from "./chunk-FSL2MOYK.js";
9
- import "./chunk-L3LPVF4Z.js";
10
- import "./chunk-6OOHHJ4N.js";
7
+ } from "./chunk-2UUGRY5B.js";
8
+ import "./chunk-3UFPFWYP.js";
9
+ import {
10
+ ensureWorkspace
11
+ } from "./chunk-CXTZPOTA.js";
12
+ import "./chunk-J4WDJ7XS.js";
13
+ import "./chunk-TFTNZZDH.js";
11
14
  import {
12
15
  SHUTDOWN_TIMEOUT_MS
13
16
  } from "./chunk-R4YSJ4EY.js";
14
17
  import "./chunk-L653KKCR.js";
15
18
  import {
16
19
  createLogger
17
- } from "./chunk-NQ6FZKCE.js";
20
+ } from "./chunk-V3S3NXBQ.js";
18
21
  import "./chunk-3RG5ZIWI.js";
19
22
 
20
23
  // src/api/bootstrap.ts
@@ -42,7 +45,7 @@ async function startApiOnly(options) {
42
45
  marketplace: null,
43
46
  userHookEvaluator: null
44
47
  };
45
- const { ApiServer } = await import("./server-4J56HS62.js");
48
+ const { ApiServer } = await import("./server-MFRYOGHR.js");
46
49
  const apiConfig = {
47
50
  enabled: true,
48
51
  port: parseInt(options.apiPort || process.env.TELETON_API_PORT || "7778"),
@@ -0,0 +1,9 @@
1
+ import {
2
+ isBotBridge,
3
+ isUserBridge
4
+ } from "./chunk-UJ54YT2T.js";
5
+ import "./chunk-3RG5ZIWI.js";
6
+ export {
7
+ isBotBridge,
8
+ isUserBridge
9
+ };
@@ -1,17 +1,15 @@
1
1
  import {
2
2
  TELEGRAM_MAX_MESSAGE_LENGTH
3
- } from "./chunk-L3LPVF4Z.js";
3
+ } from "./chunk-J4WDJ7XS.js";
4
4
  import {
5
5
  getProviderMetadata
6
- } from "./chunk-6OOHHJ4N.js";
6
+ } from "./chunk-TFTNZZDH.js";
7
7
  import {
8
- TELETON_ROOT,
9
- WORKSPACE_PATHS,
10
- WORKSPACE_ROOT
8
+ TELETON_ROOT
11
9
  } from "./chunk-L653KKCR.js";
12
10
  import {
13
11
  createLogger
14
- } from "./chunk-NQ6FZKCE.js";
12
+ } from "./chunk-V3S3NXBQ.js";
15
13
 
16
14
  // src/config/loader.ts
17
15
  import { readFileSync, existsSync, writeFileSync, mkdirSync } from "fs";
@@ -55,12 +53,14 @@ var AgentConfigSchema = z.object({
55
53
  temperature: z.number().default(0.7),
56
54
  system_prompt: z.string().nullable().default(null),
57
55
  max_agentic_iterations: z.number().default(5).describe("Maximum number of agentic loop iterations (tool call \u2192 result \u2192 tool call cycles)"),
56
+ toolset: z.string().default("full").describe("Active toolset profile: minimal, standard, trading, full"),
58
57
  session_reset_policy: SessionResetPolicySchema.default(SessionResetPolicySchema.parse({}))
59
58
  });
60
59
  var TelegramConfigSchema = z.object({
61
- api_id: z.number(),
62
- api_hash: z.string(),
63
- phone: z.string(),
60
+ mode: z.enum(["user", "bot"]).default("user"),
61
+ api_id: z.number().optional(),
62
+ api_hash: z.string().optional(),
63
+ phone: z.string().optional(),
64
64
  session_name: z.string().default("teleton_session"),
65
65
  session_path: z.string().default("~/.teleton"),
66
66
  dm_policy: DMPolicy.default("allowlist"),
@@ -79,7 +79,45 @@ var TelegramConfigSchema = z.object({
79
79
  owner_id: z.number().optional().describe("Owner's Telegram user ID"),
80
80
  debounce_ms: z.number().default(1500).describe("Debounce delay in milliseconds for group messages (0 = disabled)"),
81
81
  bot_token: z.string().optional().describe("Telegram Bot token from @BotFather for inline deal buttons"),
82
- bot_username: z.string().optional().describe("Bot username without @ (e.g., 'teleton_deals_bot')")
82
+ bot_username: z.string().optional().describe("Bot username without @ (e.g., 'teleton_deals_bot')"),
83
+ stream_mode: z.enum(["all", "replace", "off"]).default("replace").describe(
84
+ "Bot streaming mode: replace=each iteration replaces draft (default), all=concatenate all iterations, off=no streaming"
85
+ )
86
+ }).superRefine((data, ctx) => {
87
+ if (data.mode === "user") {
88
+ if (!data.api_id)
89
+ ctx.addIssue({
90
+ code: z.ZodIssueCode.custom,
91
+ message: "api_id is required in user mode",
92
+ path: ["api_id"]
93
+ });
94
+ if (!data.api_hash)
95
+ ctx.addIssue({
96
+ code: z.ZodIssueCode.custom,
97
+ message: "api_hash is required in user mode",
98
+ path: ["api_hash"]
99
+ });
100
+ if (!data.phone)
101
+ ctx.addIssue({
102
+ code: z.ZodIssueCode.custom,
103
+ message: "phone is required in user mode",
104
+ path: ["phone"]
105
+ });
106
+ }
107
+ if (data.mode === "bot") {
108
+ if (!data.bot_token)
109
+ ctx.addIssue({
110
+ code: z.ZodIssueCode.custom,
111
+ message: "bot_token is required in bot mode",
112
+ path: ["bot_token"]
113
+ });
114
+ if (!data.owner_id)
115
+ ctx.addIssue({
116
+ code: z.ZodIssueCode.custom,
117
+ message: "owner_id is required in bot mode",
118
+ path: ["owner_id"]
119
+ });
120
+ }
83
121
  });
84
122
  var StorageConfigSchema = z.object({
85
123
  sessions_file: z.string().default("~/.teleton/sessions.json"),
@@ -143,7 +181,7 @@ var McpServerSchema = z.object({
143
181
  args: z.array(z.string()).optional().describe("Explicit args array (overrides command splitting)"),
144
182
  env: z.record(z.string(), z.string()).optional().describe("Environment variables for stdio server"),
145
183
  url: z.string().url().optional().describe("SSE/HTTP endpoint URL (alternative to command)"),
146
- scope: z.enum(["always", "dm-only", "group-only", "admin-only"]).default("always").describe("Tool scope"),
184
+ scope: z.enum(["always", "dm-only", "group-only", "admin-only", "open", "allowlist", "disabled"]).default("always").describe("Tool scope"),
147
185
  enabled: z.boolean().default(true).describe("Enable/disable this server")
148
186
  }).refine((s) => s.command || s.url, {
149
187
  message: "Each MCP server needs either 'command' (stdio) or 'url' (SSE/HTTP)"
@@ -154,15 +192,13 @@ var _McpObject = z.object({
154
192
  var McpConfigSchema = _McpObject.default(_McpObject.parse({}));
155
193
  var _ToolRagObject = z.object({
156
194
  enabled: z.boolean().default(true).describe("Enable semantic tool retrieval (Tool RAG)"),
157
- top_k: z.number().default(25).describe("Max tools to retrieve per LLM call"),
195
+ top_k: z.number().default(35).describe("Max tools to retrieve per LLM call"),
158
196
  always_include: z.array(z.string()).default([
159
197
  "telegram_send_message",
160
- "telegram_reply_message",
198
+ "telegram_quote_reply",
161
199
  "telegram_send_photo",
162
- "telegram_send_document",
163
200
  "journal_*",
164
- "workspace_*",
165
- "web_*"
201
+ "workspace_*"
166
202
  ]).describe("Tool name patterns always included (prefix glob with *)"),
167
203
  skip_unlimited_providers: z.boolean().default(false).describe("Skip Tool RAG for providers with no tool limit (e.g. Anthropic)")
168
204
  });
@@ -187,10 +223,8 @@ var _CapabilitiesObject = z.object({
187
223
  var CapabilitiesConfigSchema = _CapabilitiesObject.default(_CapabilitiesObject.parse({}));
188
224
  var _HeartbeatObject = z.object({
189
225
  enabled: z.boolean().default(true).describe("Enable periodic heartbeat timer"),
190
- interval_ms: z.number().min(6e4).default(18e5).describe("Heartbeat interval in milliseconds (min 60s, default 30min)"),
191
- prompt: z.string().default(
192
- "Read HEARTBEAT.md if it exists. Follow it strictly. If nothing needs attention, reply NO_ACTION."
193
- ).describe("Prompt sent to agent on each heartbeat tick"),
226
+ interval_ms: z.number().min(6e4).default(36e5).describe("Heartbeat interval in milliseconds (min 60s, default 60min)"),
227
+ prompt: z.string().default("Execute your HEARTBEAT.md checklist now. Work through each item using tool calls.").describe("Prompt sent to agent on each heartbeat tick"),
194
228
  self_configurable: z.boolean().default(false).describe("Allow agent to modify heartbeat config via config_set")
195
229
  });
196
230
  var HeartbeatConfigSchema = _HeartbeatObject.default(_HeartbeatObject.parse({}));
@@ -219,8 +253,64 @@ var ConfigSchema = z.object({
219
253
  tavily_api_key: z.string().optional().describe("Tavily API key for web search & extract (free at https://tavily.com)")
220
254
  });
221
255
 
256
+ // src/config/env.ts
257
+ import { z as z2 } from "zod";
258
+ var log = createLogger("Env");
259
+ var optionalString = z2.string().optional();
260
+ var optionalInt = z2.coerce.number().int().optional();
261
+ var optionalPort = z2.coerce.number().int().min(1).max(65535).optional();
262
+ var optionalBoolean = z2.string().optional().transform(
263
+ (v) => v === "true" || v === "1" || v === "yes" ? true : v === "false" || v === "0" || v === "no" ? false : void 0
264
+ );
265
+ var envSchema = z2.object({
266
+ // Core
267
+ TELETON_HOME: optionalString,
268
+ TELETON_API_KEY: optionalString,
269
+ TELETON_BASE_URL: optionalString,
270
+ // Telegram
271
+ TELETON_TG_API_ID: optionalInt,
272
+ TELETON_TG_API_HASH: optionalString,
273
+ TELETON_TG_PHONE: optionalString,
274
+ // WebUI
275
+ TELETON_WEBUI_ENABLED: optionalBoolean,
276
+ TELETON_WEBUI_PORT: optionalPort,
277
+ TELETON_WEBUI_HOST: optionalString,
278
+ // Management API
279
+ TELETON_API_ENABLED: optionalBoolean,
280
+ TELETON_API_PORT: optionalPort,
281
+ TELETON_JSON_CREDENTIALS: optionalBoolean,
282
+ // Logging
283
+ TELETON_LOG_LEVEL: optionalString,
284
+ TELETON_LOG: optionalString,
285
+ TELETON_LOG_PRETTY: optionalString,
286
+ // External API keys
287
+ TELETON_TAVILY_API_KEY: optionalString,
288
+ TELETON_TONAPI_KEY: optionalString,
289
+ TELETON_TONCENTER_API_KEY: optionalString
290
+ });
291
+ function validateEnv() {
292
+ const result = envSchema.safeParse(process.env);
293
+ if (!result.success) {
294
+ for (const issue of result.error.issues) {
295
+ const path = issue.path.join(".");
296
+ if (path === "TELETON_TG_API_ID" && process.env.TELETON_TG_API_ID) {
297
+ throw new Error(
298
+ `Invalid TELETON_TG_API_ID environment variable: "${process.env.TELETON_TG_API_ID}" is not a valid integer`
299
+ );
300
+ }
301
+ log.warn({ path, message: issue.message }, "Invalid env var");
302
+ }
303
+ const invalidKeys = new Set(result.error.issues.map((i) => String(i.path[0])));
304
+ const cleaned = { ...process.env };
305
+ for (const key of invalidKeys) delete cleaned[key];
306
+ const retry = envSchema.safeParse(cleaned);
307
+ return retry.success ? retry.data : {};
308
+ }
309
+ return result.data;
310
+ }
311
+
222
312
  // src/config/loader.ts
223
- var log = createLogger("Config");
313
+ var log2 = createLogger("Config");
224
314
  var DEFAULT_CONFIG_PATH = join(TELETON_ROOT, "config.yaml");
225
315
  function expandPath(path) {
226
316
  if (path.startsWith("~")) {
@@ -229,6 +319,7 @@ function expandPath(path) {
229
319
  return path;
230
320
  }
231
321
  function loadConfig(configPath = DEFAULT_CONFIG_PATH) {
322
+ const env = validateEnv();
232
323
  const fullPath = expandPath(configPath);
233
324
  if (!existsSync(fullPath)) {
234
325
  throw new Error(`Config file not found: ${fullPath}
@@ -247,7 +338,7 @@ Run 'teleton setup' to create one.`);
247
338
  throw new Error(`Invalid YAML in ${fullPath}: ${error.message}`);
248
339
  }
249
340
  if (raw && typeof raw === "object" && "market" in raw) {
250
- log.warn("config.market is deprecated and ignored. Use market-api plugin instead.");
341
+ log2.warn("config.market is deprecated and ignored. Use market-api plugin instead.");
251
342
  delete raw.market;
252
343
  }
253
344
  const result = ConfigSchema.safeParse(raw);
@@ -263,71 +354,57 @@ Run 'teleton setup' to create one.`);
263
354
  config.telegram.session_path = expandPath(config.telegram.session_path);
264
355
  config.storage.sessions_file = expandPath(config.storage.sessions_file);
265
356
  config.storage.memory_file = expandPath(config.storage.memory_file);
266
- if (process.env.TELETON_API_KEY) {
267
- config.agent.api_key = process.env.TELETON_API_KEY;
357
+ if (env.TELETON_API_KEY) {
358
+ config.agent.api_key = env.TELETON_API_KEY;
268
359
  }
269
- if (process.env.TELETON_TG_API_ID) {
270
- const apiId = parseInt(process.env.TELETON_TG_API_ID, 10);
271
- if (isNaN(apiId)) {
272
- throw new Error(
273
- `Invalid TELETON_TG_API_ID environment variable: "${process.env.TELETON_TG_API_ID}" is not a valid integer`
274
- );
275
- }
276
- config.telegram.api_id = apiId;
360
+ if (env.TELETON_TG_API_ID != null) {
361
+ config.telegram.api_id = env.TELETON_TG_API_ID;
277
362
  }
278
- if (process.env.TELETON_TG_API_HASH) {
279
- config.telegram.api_hash = process.env.TELETON_TG_API_HASH;
363
+ if (env.TELETON_TG_API_HASH) {
364
+ config.telegram.api_hash = env.TELETON_TG_API_HASH;
280
365
  }
281
- if (process.env.TELETON_TG_PHONE) {
282
- config.telegram.phone = process.env.TELETON_TG_PHONE;
366
+ if (env.TELETON_TG_PHONE) {
367
+ config.telegram.phone = env.TELETON_TG_PHONE;
283
368
  }
284
- if (process.env.TELETON_WEBUI_ENABLED) {
285
- config.webui.enabled = process.env.TELETON_WEBUI_ENABLED === "true";
369
+ if (env.TELETON_WEBUI_ENABLED != null) {
370
+ config.webui.enabled = env.TELETON_WEBUI_ENABLED;
286
371
  }
287
- if (process.env.TELETON_WEBUI_PORT) {
288
- const port = parseInt(process.env.TELETON_WEBUI_PORT, 10);
289
- if (!isNaN(port) && port >= 1024 && port <= 65535) {
290
- config.webui.port = port;
291
- }
372
+ if (env.TELETON_WEBUI_PORT != null && env.TELETON_WEBUI_PORT >= 1024) {
373
+ config.webui.port = env.TELETON_WEBUI_PORT;
292
374
  }
293
- if (process.env.TELETON_WEBUI_HOST) {
294
- config.webui.host = process.env.TELETON_WEBUI_HOST;
375
+ if (env.TELETON_WEBUI_HOST) {
376
+ config.webui.host = env.TELETON_WEBUI_HOST;
295
377
  if (!["127.0.0.1", "localhost", "::1"].includes(config.webui.host)) {
296
- log.warn(
378
+ log2.warn(
297
379
  { host: config.webui.host },
298
380
  "WebUI bound to non-loopback address \u2014 ensure auth_token is set"
299
381
  );
300
382
  }
301
383
  }
302
- if (process.env.TELETON_API_ENABLED) {
384
+ if (env.TELETON_API_ENABLED != null) {
303
385
  if (!config.api) config.api = { enabled: false, port: 7778, key_hash: "", allowed_ips: [] };
304
- config.api.enabled = process.env.TELETON_API_ENABLED === "true";
386
+ config.api.enabled = env.TELETON_API_ENABLED;
305
387
  }
306
- if (process.env.TELETON_API_PORT) {
307
- const port = parseInt(process.env.TELETON_API_PORT, 10);
308
- if (!isNaN(port) && port >= 1024 && port <= 65535) {
309
- if (!config.api) config.api = { enabled: false, port: 7778, key_hash: "", allowed_ips: [] };
310
- config.api.port = port;
311
- }
388
+ if (env.TELETON_API_PORT != null && env.TELETON_API_PORT >= 1024) {
389
+ if (!config.api) config.api = { enabled: false, port: 7778, key_hash: "", allowed_ips: [] };
390
+ config.api.port = env.TELETON_API_PORT;
312
391
  }
313
- if (process.env.TELETON_BASE_URL) {
392
+ if (env.TELETON_BASE_URL) {
314
393
  try {
315
- new URL(process.env.TELETON_BASE_URL);
316
- config.agent.base_url = process.env.TELETON_BASE_URL;
394
+ new URL(env.TELETON_BASE_URL);
395
+ config.agent.base_url = env.TELETON_BASE_URL;
317
396
  } catch {
318
- throw new Error(
319
- `Invalid TELETON_BASE_URL: "${process.env.TELETON_BASE_URL}" is not a valid URL`
320
- );
397
+ throw new Error(`Invalid TELETON_BASE_URL: "${env.TELETON_BASE_URL}" is not a valid URL`);
321
398
  }
322
399
  }
323
- if (process.env.TELETON_TAVILY_API_KEY) {
324
- config.tavily_api_key = process.env.TELETON_TAVILY_API_KEY;
400
+ if (env.TELETON_TAVILY_API_KEY) {
401
+ config.tavily_api_key = env.TELETON_TAVILY_API_KEY;
325
402
  }
326
- if (process.env.TELETON_TONAPI_KEY) {
327
- config.tonapi_key = process.env.TELETON_TONAPI_KEY;
403
+ if (env.TELETON_TONAPI_KEY) {
404
+ config.tonapi_key = env.TELETON_TONAPI_KEY;
328
405
  }
329
- if (process.env.TELETON_TONCENTER_API_KEY) {
330
- config.toncenter_api_key = process.env.TELETON_TONCENTER_API_KEY;
406
+ if (env.TELETON_TONCENTER_API_KEY) {
407
+ config.toncenter_api_key = env.TELETON_TONCENTER_API_KEY;
331
408
  }
332
409
  return config;
333
410
  }
@@ -338,107 +415,11 @@ function getDefaultConfigPath() {
338
415
  return DEFAULT_CONFIG_PATH;
339
416
  }
340
417
 
341
- // src/workspace/manager.ts
342
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, copyFileSync } from "fs";
343
- import { join as join2, dirname as dirname2 } from "path";
344
- import { fileURLToPath } from "url";
345
- var log2 = createLogger("Workspace");
346
- function findPackageRoot() {
347
- let dir = dirname2(fileURLToPath(import.meta.url));
348
- for (let i = 0; i < 10; i++) {
349
- if (existsSync2(join2(dir, "package.json"))) return dir;
350
- dir = dirname2(dir);
351
- }
352
- return process.cwd();
353
- }
354
- var TEMPLATES_DIR = join2(findPackageRoot(), "src", "templates");
355
- async function ensureWorkspace(config) {
356
- const silent = config?.silent ?? false;
357
- if (!existsSync2(TELETON_ROOT)) {
358
- mkdirSync2(TELETON_ROOT, { recursive: true });
359
- if (!silent) log2.info(`Created Teleton root at ${TELETON_ROOT}`);
360
- }
361
- if (!existsSync2(WORKSPACE_ROOT)) {
362
- mkdirSync2(WORKSPACE_ROOT, { recursive: true });
363
- if (!silent) log2.info(`Created workspace at ${WORKSPACE_ROOT}`);
364
- }
365
- const directories = [
366
- WORKSPACE_PATHS.MEMORY_DIR,
367
- WORKSPACE_PATHS.DOWNLOADS_DIR,
368
- WORKSPACE_PATHS.UPLOADS_DIR,
369
- WORKSPACE_PATHS.TEMP_DIR,
370
- WORKSPACE_PATHS.MEMES_DIR
371
- ];
372
- for (const dir of directories) {
373
- if (!existsSync2(dir)) {
374
- mkdirSync2(dir, { recursive: true });
375
- }
376
- }
377
- const workspace = {
378
- root: TELETON_ROOT,
379
- workspace: WORKSPACE_ROOT,
380
- // Workspace files
381
- soulPath: WORKSPACE_PATHS.SOUL,
382
- memoryPath: WORKSPACE_PATHS.MEMORY,
383
- identityPath: WORKSPACE_PATHS.IDENTITY,
384
- userPath: WORKSPACE_PATHS.USER,
385
- strategyPath: WORKSPACE_PATHS.STRATEGY,
386
- securityPath: WORKSPACE_PATHS.SECURITY,
387
- // Workspace directories
388
- memoryDir: WORKSPACE_PATHS.MEMORY_DIR,
389
- downloadsDir: WORKSPACE_PATHS.DOWNLOADS_DIR,
390
- uploadsDir: WORKSPACE_PATHS.UPLOADS_DIR,
391
- tempDir: WORKSPACE_PATHS.TEMP_DIR,
392
- memesDir: WORKSPACE_PATHS.MEMES_DIR,
393
- // Protected files (outside workspace)
394
- sessionPath: join2(TELETON_ROOT, "telegram_session.txt"),
395
- configPath: join2(TELETON_ROOT, "config.yaml"),
396
- walletPath: join2(TELETON_ROOT, "wallet.json")
397
- };
398
- if (config?.ensureTemplates) {
399
- await bootstrapTemplates(workspace, silent);
400
- }
401
- return workspace;
402
- }
403
- async function bootstrapTemplates(workspace, silent = false) {
404
- const templates = [
405
- { name: "SOUL.md", path: workspace.soulPath },
406
- { name: "MEMORY.md", path: workspace.memoryPath },
407
- { name: "IDENTITY.md", path: workspace.identityPath },
408
- { name: "USER.md", path: workspace.userPath },
409
- { name: "SECURITY.md", path: workspace.securityPath },
410
- { name: "STRATEGY.md", path: workspace.strategyPath },
411
- { name: "HEARTBEAT.md", path: WORKSPACE_PATHS.HEARTBEAT }
412
- ];
413
- for (const template of templates) {
414
- if (!existsSync2(template.path)) {
415
- const templateSource = join2(TEMPLATES_DIR, template.name);
416
- if (existsSync2(templateSource)) {
417
- copyFileSync(templateSource, template.path);
418
- if (!silent) log2.info(`Created ${template.name}`);
419
- }
420
- }
421
- }
422
- }
423
- function isNewWorkspace(workspace) {
424
- return !existsSync2(workspace.configPath);
425
- }
426
- function loadTemplate(name) {
427
- const templatePath = join2(TEMPLATES_DIR, name);
428
- if (!existsSync2(templatePath)) {
429
- throw new Error(`Template ${name} not found at ${templatePath}`);
430
- }
431
- return readFileSync2(templatePath, "utf-8");
432
- }
433
-
434
418
  export {
435
419
  DealsConfigSchema,
436
420
  ConfigSchema,
437
421
  expandPath,
438
422
  loadConfig,
439
423
  configExists,
440
- getDefaultConfigPath,
441
- ensureWorkspace,
442
- isNewWorkspace,
443
- loadTemplate
424
+ getDefaultConfigPath
444
425
  };