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.
- package/README.md +24 -5
- package/dist/{bootstrap-SPDT3XBQ.js → bootstrap-PFBH6ALD.js} +10 -7
- package/dist/bridge-guards-HZTNH7IB.js +9 -0
- package/dist/{chunk-FSL2MOYK.js → chunk-2UUGRY5B.js} +144 -163
- package/dist/{chunk-LM6AL6LN.js → chunk-4MFN75ZK.js} +4449 -2776
- package/dist/{chunk-GUX6ZFVF.js → chunk-4MG2AROG.js} +4 -6
- package/dist/{chunk-6U6VA2OT.js → chunk-6IFNQWIM.js} +7276 -7300
- package/dist/chunk-7KI25UJU.js +215 -0
- package/dist/chunk-AX5NBEHX.js +12 -0
- package/dist/{chunk-7ZXUUDQQ.js → chunk-BLUES3FJ.js} +79 -100
- package/dist/{chunk-KYSAHDYE.js → chunk-BT2I3ETV.js} +1 -1
- package/dist/chunk-CXTZPOTA.js +107 -0
- package/dist/{chunk-4KURCUWD.js → chunk-D3GT6YIY.js} +59 -7
- package/dist/chunk-EKCXKL5M.js +53 -0
- package/dist/{chunk-5K4YDCVU.js → chunk-F6S3L3OV.js} +3 -3
- package/dist/{chunk-L3LPVF4Z.js → chunk-J4WDJ7XS.js} +2 -2
- package/dist/{chunk-Z63KUQX4.js → chunk-JYF2MM5I.js} +120 -110
- package/dist/{chunk-NVKBBTI6.js → chunk-K3QSIIMZ.js} +9 -6
- package/dist/chunk-OMQIAWEU.js +273 -0
- package/dist/chunk-PCT7GYBP.js +274 -0
- package/dist/{chunk-35X3V6OW.js → chunk-QYZBWU2D.js} +5 -5
- package/dist/{chunk-WTDAICGT.js → chunk-R6W4DJRK.js} +7 -7
- package/dist/{chunk-5SEMA47R.js → chunk-RILOEIK6.js} +1 -1
- package/dist/{chunk-6OOHHJ4N.js → chunk-TFTNZZDH.js} +20 -20
- package/dist/chunk-TTOZCZWE.js +96 -0
- package/dist/chunk-UJ54YT2T.js +12 -0
- package/dist/{chunk-2MZP75SH.js → chunk-ULVL2W3D.js} +152 -256
- package/dist/{chunk-NQ6FZKCE.js → chunk-V3S3NXBQ.js} +3 -1
- package/dist/{chunk-H7MFXJZK.js → chunk-WSL4KIOI.js} +31 -26
- package/dist/{chunk-PK3TVFBT.js → chunk-Z5WY7BSB.js} +5 -5
- package/dist/{chunk-LD24DWWE.js → chunk-ZGKE3OTA.js} +110 -47
- package/dist/{chunk-M6M4DCDU.js → chunk-ZHRDETCX.js} +3 -3
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +263 -163
- package/dist/{client-G62EZT6U.js → client-S5UIK6OG.js} +9 -7
- package/dist/daily-logs-3WXGYAQF.js +25 -0
- package/dist/{get-my-gifts-Y7EN7RK4.js → get-my-gifts-3YSYM3LI.js} +3 -2
- package/dist/{harden-permissions-6BLHRCQJ.js → harden-permissions-PV5SGV5D.js} +1 -1
- package/dist/index.d.ts +923 -0
- package/dist/index.js +28 -20
- package/dist/knowledge-RRWUIO3G.js +19 -0
- package/dist/{local-HQ3UJ7KR.js → local-MSZAXWUL.js} +2 -2
- package/dist/mcp-loader-OELDFR63.js +15 -0
- package/dist/{memory-BJH724PQ.js → memory-6U6HGRK2.js} +22 -12
- package/dist/{memory-hook-LUAKTXU5.js → memory-hook-T7Y235KY.js} +7 -7
- package/dist/messages-KV5ADNJB.js +17 -0
- package/dist/{migrate-C4LBLOZH.js → migrate-AX3HOKOO.js} +9 -7
- package/dist/{server-4J56HS62.js → server-MFRYOGHR.js} +20 -16
- package/dist/{server-I6TYJ36S.js → server-SFLCAZFR.js} +220 -19
- package/dist/{setup-server-VJ3MGUSM.js → setup-server-YWAPKZVE.js} +14 -13
- package/dist/{store-2IGAMTES.js → store-PGHQASBC.js} +10 -8
- package/dist/{task-dependency-resolver-CQ432Z7J.js → task-dependency-resolver-YQKADDEU.js} +24 -10
- package/dist/{task-executor-JELRREUV.js → task-executor-LWAWD225.js} +4 -4
- package/dist/{tool-adapter-IVX2XQJE.js → tool-adapter-VKLUZSQS.js} +1 -1
- package/dist/{tool-index-XPCMWBYY.js → tool-index-YEWDF5CK.js} +4 -4
- package/dist/{transcript-OEO3HA4Z.js → transcript-4Y3Z2BJ3.js} +2 -2
- package/dist/web/assets/Config-MNxA69ib.js +1 -0
- package/dist/web/assets/Conversations-Dk958paA.js +1 -0
- package/dist/web/assets/Dashboard-dM18fGOm.js +1 -0
- package/dist/web/assets/Hooks-D2griQnI.js +1 -0
- package/dist/web/assets/Mcp-CtWNzwsz.js +1 -0
- package/dist/web/assets/Memory-CfLwH45G.js +1 -0
- package/dist/web/assets/Plugins-3hoJprFo.js +1 -0
- package/dist/web/assets/SearchInput-CpcETdpE.js +1 -0
- package/dist/web/assets/Soul-BSxE73aK.js +1 -0
- package/dist/web/assets/Tasks-DkCkfu3A.js +1 -0
- package/dist/web/assets/TelegramSettingsPanel-BRzc5G6e.js +1 -0
- package/dist/web/assets/Tools-Du8B8Mb4.js +1 -0
- package/dist/web/assets/Wallet-BLILP2Gn.js +1 -0
- package/dist/web/assets/Workspace-qklcXpXV.js +1 -0
- package/dist/web/assets/index-BwEPTTKp.js +90 -0
- package/dist/web/assets/index-noejUsK7.css +1 -0
- package/dist/web/assets/{index.es-eSR4Qv6s.js → index.es-DdpKlnGb.js} +1 -1
- package/dist/web/assets/useToolManager-tdxkKn3H.js +1 -0
- package/dist/web/assets/utils-CnsbSMo4.js +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +7 -8
- package/dist/web/assets/index-DmlyQVhR.css +0 -1
- package/dist/web/assets/index-Dn5ZH1Y6.js +0 -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-
|
|
3
|
+
} from "./chunk-K3QSIIMZ.js";
|
|
4
4
|
import {
|
|
5
5
|
configExists,
|
|
6
|
-
ensureWorkspace,
|
|
7
6
|
getDefaultConfigPath
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import
|
|
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-
|
|
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-
|
|
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"),
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TELEGRAM_MAX_MESSAGE_LENGTH
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-J4WDJ7XS.js";
|
|
4
4
|
import {
|
|
5
5
|
getProviderMetadata
|
|
6
|
-
} from "./chunk-
|
|
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-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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(
|
|
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
|
-
"
|
|
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(
|
|
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
|
|
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
|
-
|
|
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 (
|
|
267
|
-
config.agent.api_key =
|
|
357
|
+
if (env.TELETON_API_KEY) {
|
|
358
|
+
config.agent.api_key = env.TELETON_API_KEY;
|
|
268
359
|
}
|
|
269
|
-
if (
|
|
270
|
-
|
|
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 (
|
|
279
|
-
config.telegram.api_hash =
|
|
363
|
+
if (env.TELETON_TG_API_HASH) {
|
|
364
|
+
config.telegram.api_hash = env.TELETON_TG_API_HASH;
|
|
280
365
|
}
|
|
281
|
-
if (
|
|
282
|
-
config.telegram.phone =
|
|
366
|
+
if (env.TELETON_TG_PHONE) {
|
|
367
|
+
config.telegram.phone = env.TELETON_TG_PHONE;
|
|
283
368
|
}
|
|
284
|
-
if (
|
|
285
|
-
config.webui.enabled =
|
|
369
|
+
if (env.TELETON_WEBUI_ENABLED != null) {
|
|
370
|
+
config.webui.enabled = env.TELETON_WEBUI_ENABLED;
|
|
286
371
|
}
|
|
287
|
-
if (
|
|
288
|
-
|
|
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 (
|
|
294
|
-
config.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
|
-
|
|
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 (
|
|
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 =
|
|
386
|
+
config.api.enabled = env.TELETON_API_ENABLED;
|
|
305
387
|
}
|
|
306
|
-
if (
|
|
307
|
-
|
|
308
|
-
|
|
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 (
|
|
392
|
+
if (env.TELETON_BASE_URL) {
|
|
314
393
|
try {
|
|
315
|
-
new URL(
|
|
316
|
-
config.agent.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 (
|
|
324
|
-
config.tavily_api_key =
|
|
400
|
+
if (env.TELETON_TAVILY_API_KEY) {
|
|
401
|
+
config.tavily_api_key = env.TELETON_TAVILY_API_KEY;
|
|
325
402
|
}
|
|
326
|
-
if (
|
|
327
|
-
config.tonapi_key =
|
|
403
|
+
if (env.TELETON_TONAPI_KEY) {
|
|
404
|
+
config.tonapi_key = env.TELETON_TONAPI_KEY;
|
|
328
405
|
}
|
|
329
|
-
if (
|
|
330
|
-
config.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
|
};
|