teleton 0.8.1 → 0.8.3
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/dist/bootstrap-DDFVEMYI.js +128 -0
- package/dist/{server-3FHI2SEB.js → chunk-2ERTYRHA.js} +26 -372
- package/dist/{chunk-5FNWBZ5K.js → chunk-33Z47EXI.js} +264 -274
- package/dist/{chunk-3S4GGLLR.js → chunk-35MX4ZUI.js} +23 -104
- package/dist/chunk-3UFPFWYP.js +12 -0
- package/dist/chunk-5SEMA47R.js +75 -0
- package/dist/{chunk-PHSAHTK4.js → chunk-6OOHHJ4N.js} +3 -108
- package/dist/{chunk-CGOXE4WP.js → chunk-7MWKT67G.js} +467 -914
- package/dist/chunk-AEHTQI3H.js +142 -0
- package/dist/{chunk-S6PHGKOC.js → chunk-AERHOXGC.js} +88 -322
- package/dist/chunk-ALKAAG4O.js +487 -0
- package/dist/{chunk-UP55PXFH.js → chunk-C4NKJT2Z.js} +8 -0
- package/dist/chunk-CUE4UZXR.js +129 -0
- package/dist/chunk-FUNF6H4W.js +251 -0
- package/dist/{chunk-7U7BOHCL.js → chunk-GHMXWAXI.js} +147 -63
- package/dist/{chunk-QBHRXLZS.js → chunk-H7MFXJZK.js} +2 -2
- package/dist/{chunk-QV2GLOTK.js → chunk-LC4TV3KL.js} +1 -1
- package/dist/{chunk-AYWEJCDB.js → chunk-LVTKJQ7O.js} +12 -10
- package/dist/{chunk-RCMD3U65.js → chunk-NQ6FZKCE.js} +13 -0
- package/dist/chunk-NVKBBTI6.js +128 -0
- package/dist/{setup-server-32XGDPE6.js → chunk-OIMAE24Q.js} +55 -216
- package/dist/{chunk-OJCLKU5Z.js → chunk-WFTC3JJW.js} +16 -0
- package/dist/chunk-WTDAICGT.js +175 -0
- package/dist/{chunk-KVXV7EF7.js → chunk-XDZDOKIF.js} +2 -2
- package/dist/cli/index.js +91 -27
- package/dist/{client-MPHPIZB6.js → client-5KD25NOP.js} +5 -4
- package/dist/{get-my-gifts-CC6HAVWB.js → get-my-gifts-Y7EN7RK4.js} +3 -3
- package/dist/index.js +19 -13
- package/dist/local-IHKJFQJS.js +9 -0
- package/dist/{memory-UBHM7ILG.js → memory-QMJRM3XJ.js} +9 -5
- package/dist/memory-hook-VUNWZ3NY.js +19 -0
- package/dist/{migrate-UBBEJ5BL.js → migrate-5VBAP52B.js} +5 -4
- package/dist/server-JF6FX772.js +813 -0
- package/dist/server-N4T7E25M.js +396 -0
- package/dist/setup-server-IX3BFPPH.js +217 -0
- package/dist/{store-M5IMUQCL.js → store-BY7S6IFN.js} +6 -5
- package/dist/{task-dependency-resolver-RR2O5S7B.js → task-dependency-resolver-L6UUMTHK.js} +2 -2
- package/dist/{task-executor-6W5HRX5C.js → task-executor-XBNJLUCS.js} +2 -2
- package/dist/{tool-adapter-IH5VGBOO.js → tool-adapter-IVX2XQJE.js} +1 -1
- package/dist/{tool-index-PMAOXWUA.js → tool-index-FTERJSZK.js} +4 -3
- package/dist/{transcript-NGDPSNIH.js → transcript-IM7G25OS.js} +2 -2
- package/package.json +4 -2
- package/dist/chunk-XBE4JB7C.js +0 -8
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ConfigSchema
|
|
3
|
+
} from "./chunk-AERHOXGC.js";
|
|
4
|
+
import {
|
|
5
|
+
getProviderMetadata
|
|
6
|
+
} from "./chunk-6OOHHJ4N.js";
|
|
7
|
+
import {
|
|
8
|
+
TELETON_ROOT
|
|
9
|
+
} from "./chunk-EYWNOHMJ.js";
|
|
10
|
+
import {
|
|
11
|
+
createLogger
|
|
12
|
+
} from "./chunk-NQ6FZKCE.js";
|
|
13
|
+
|
|
14
|
+
// src/config/loader.ts
|
|
15
|
+
import { readFileSync, existsSync, writeFileSync, mkdirSync } from "fs";
|
|
16
|
+
import { parse, stringify } from "yaml";
|
|
17
|
+
import { homedir } from "os";
|
|
18
|
+
import { dirname, join } from "path";
|
|
19
|
+
var log = createLogger("Config");
|
|
20
|
+
var DEFAULT_CONFIG_PATH = join(TELETON_ROOT, "config.yaml");
|
|
21
|
+
function expandPath(path) {
|
|
22
|
+
if (path.startsWith("~")) {
|
|
23
|
+
return join(homedir(), path.slice(1));
|
|
24
|
+
}
|
|
25
|
+
return path;
|
|
26
|
+
}
|
|
27
|
+
function loadConfig(configPath = DEFAULT_CONFIG_PATH) {
|
|
28
|
+
const fullPath = expandPath(configPath);
|
|
29
|
+
if (!existsSync(fullPath)) {
|
|
30
|
+
throw new Error(`Config file not found: ${fullPath}
|
|
31
|
+
Run 'teleton setup' to create one.`);
|
|
32
|
+
}
|
|
33
|
+
let content;
|
|
34
|
+
try {
|
|
35
|
+
content = readFileSync(fullPath, "utf-8");
|
|
36
|
+
} catch (error) {
|
|
37
|
+
throw new Error(`Cannot read config file ${fullPath}: ${error.message}`);
|
|
38
|
+
}
|
|
39
|
+
let raw;
|
|
40
|
+
try {
|
|
41
|
+
raw = parse(content);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
throw new Error(`Invalid YAML in ${fullPath}: ${error.message}`);
|
|
44
|
+
}
|
|
45
|
+
if (raw && typeof raw === "object" && "market" in raw) {
|
|
46
|
+
log.warn("config.market is deprecated and ignored. Use market-api plugin instead.");
|
|
47
|
+
delete raw.market;
|
|
48
|
+
}
|
|
49
|
+
const result = ConfigSchema.safeParse(raw);
|
|
50
|
+
if (!result.success) {
|
|
51
|
+
throw new Error(`Invalid config: ${result.error.message}`);
|
|
52
|
+
}
|
|
53
|
+
const config = result.data;
|
|
54
|
+
const provider = config.agent.provider;
|
|
55
|
+
if (provider !== "anthropic" && provider !== "claude-code" && !raw.agent?.model) {
|
|
56
|
+
const meta = getProviderMetadata(provider);
|
|
57
|
+
config.agent.model = meta.defaultModel;
|
|
58
|
+
}
|
|
59
|
+
config.telegram.session_path = expandPath(config.telegram.session_path);
|
|
60
|
+
config.storage.sessions_file = expandPath(config.storage.sessions_file);
|
|
61
|
+
config.storage.memory_file = expandPath(config.storage.memory_file);
|
|
62
|
+
if (process.env.TELETON_API_KEY) {
|
|
63
|
+
config.agent.api_key = process.env.TELETON_API_KEY;
|
|
64
|
+
}
|
|
65
|
+
if (process.env.TELETON_TG_API_ID) {
|
|
66
|
+
const apiId = parseInt(process.env.TELETON_TG_API_ID, 10);
|
|
67
|
+
if (isNaN(apiId)) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
`Invalid TELETON_TG_API_ID environment variable: "${process.env.TELETON_TG_API_ID}" is not a valid integer`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
config.telegram.api_id = apiId;
|
|
73
|
+
}
|
|
74
|
+
if (process.env.TELETON_TG_API_HASH) {
|
|
75
|
+
config.telegram.api_hash = process.env.TELETON_TG_API_HASH;
|
|
76
|
+
}
|
|
77
|
+
if (process.env.TELETON_TG_PHONE) {
|
|
78
|
+
config.telegram.phone = process.env.TELETON_TG_PHONE;
|
|
79
|
+
}
|
|
80
|
+
if (process.env.TELETON_WEBUI_ENABLED) {
|
|
81
|
+
config.webui.enabled = process.env.TELETON_WEBUI_ENABLED === "true";
|
|
82
|
+
}
|
|
83
|
+
if (process.env.TELETON_WEBUI_PORT) {
|
|
84
|
+
const port = parseInt(process.env.TELETON_WEBUI_PORT, 10);
|
|
85
|
+
if (!isNaN(port) && port >= 1024 && port <= 65535) {
|
|
86
|
+
config.webui.port = port;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (process.env.TELETON_WEBUI_HOST) {
|
|
90
|
+
config.webui.host = process.env.TELETON_WEBUI_HOST;
|
|
91
|
+
if (!["127.0.0.1", "localhost", "::1"].includes(config.webui.host)) {
|
|
92
|
+
log.warn(
|
|
93
|
+
{ host: config.webui.host },
|
|
94
|
+
"WebUI bound to non-loopback address \u2014 ensure auth_token is set"
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (process.env.TELETON_API_ENABLED) {
|
|
99
|
+
if (!config.api) config.api = { enabled: false, port: 7778, key_hash: "", allowed_ips: [] };
|
|
100
|
+
config.api.enabled = process.env.TELETON_API_ENABLED === "true";
|
|
101
|
+
}
|
|
102
|
+
if (process.env.TELETON_API_PORT) {
|
|
103
|
+
const port = parseInt(process.env.TELETON_API_PORT, 10);
|
|
104
|
+
if (!isNaN(port) && port >= 1024 && port <= 65535) {
|
|
105
|
+
if (!config.api) config.api = { enabled: false, port: 7778, key_hash: "", allowed_ips: [] };
|
|
106
|
+
config.api.port = port;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (process.env.TELETON_BASE_URL) {
|
|
110
|
+
try {
|
|
111
|
+
new URL(process.env.TELETON_BASE_URL);
|
|
112
|
+
config.agent.base_url = process.env.TELETON_BASE_URL;
|
|
113
|
+
} catch {
|
|
114
|
+
throw new Error(
|
|
115
|
+
`Invalid TELETON_BASE_URL: "${process.env.TELETON_BASE_URL}" is not a valid URL`
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (process.env.TELETON_TAVILY_API_KEY) {
|
|
120
|
+
config.tavily_api_key = process.env.TELETON_TAVILY_API_KEY;
|
|
121
|
+
}
|
|
122
|
+
if (process.env.TELETON_TONAPI_KEY) {
|
|
123
|
+
config.tonapi_key = process.env.TELETON_TONAPI_KEY;
|
|
124
|
+
}
|
|
125
|
+
if (process.env.TELETON_TONCENTER_API_KEY) {
|
|
126
|
+
config.toncenter_api_key = process.env.TELETON_TONCENTER_API_KEY;
|
|
127
|
+
}
|
|
128
|
+
return config;
|
|
129
|
+
}
|
|
130
|
+
function configExists(configPath = DEFAULT_CONFIG_PATH) {
|
|
131
|
+
return existsSync(expandPath(configPath));
|
|
132
|
+
}
|
|
133
|
+
function getDefaultConfigPath() {
|
|
134
|
+
return DEFAULT_CONFIG_PATH;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export {
|
|
138
|
+
expandPath,
|
|
139
|
+
loadConfig,
|
|
140
|
+
configExists,
|
|
141
|
+
getDefaultConfigPath
|
|
142
|
+
};
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
COINGECKO_API_URL,
|
|
3
|
-
tonapiFetch
|
|
4
|
-
} from "./chunk-VFA7QMCZ.js";
|
|
5
1
|
import {
|
|
6
2
|
TELEGRAM_MAX_MESSAGE_LENGTH
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import {
|
|
9
|
-
fetchWithTimeout
|
|
10
|
-
} from "./chunk-XQUHC3JZ.js";
|
|
3
|
+
} from "./chunk-C4NKJT2Z.js";
|
|
11
4
|
import {
|
|
12
5
|
TELETON_ROOT,
|
|
13
6
|
WORKSPACE_PATHS,
|
|
@@ -15,228 +8,98 @@ import {
|
|
|
15
8
|
} from "./chunk-EYWNOHMJ.js";
|
|
16
9
|
import {
|
|
17
10
|
createLogger
|
|
18
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-NQ6FZKCE.js";
|
|
19
12
|
|
|
20
|
-
// src/
|
|
21
|
-
|
|
22
|
-
var ORBS_HOST = "ton.access.orbs.network";
|
|
23
|
-
var ORBS_TOPOLOGY_URL = `https://${ORBS_HOST}/mngr/nodes?npm_version=2.3.3`;
|
|
24
|
-
var TONCENTER_URL = `https://toncenter.com/api/v2/jsonRPC`;
|
|
25
|
-
var _cache = null;
|
|
26
|
-
var _toncenterApiKey;
|
|
27
|
-
function setToncenterApiKey(key) {
|
|
28
|
-
_toncenterApiKey = key;
|
|
29
|
-
}
|
|
30
|
-
function getToncenterApiKey() {
|
|
31
|
-
return _toncenterApiKey;
|
|
32
|
-
}
|
|
33
|
-
async function discoverOrbsEndpoint() {
|
|
34
|
-
const res = await fetch(ORBS_TOPOLOGY_URL, { signal: AbortSignal.timeout(5e3) });
|
|
35
|
-
const nodes = await res.json();
|
|
36
|
-
const healthy = nodes.filter(
|
|
37
|
-
(n) => n.Healthy === "1" && n.Weight > 0 && n.Mngr?.health?.["v2-mainnet"]
|
|
38
|
-
);
|
|
39
|
-
if (healthy.length === 0) throw new Error("no healthy orbs nodes");
|
|
40
|
-
const totalWeight = healthy.reduce((sum, n) => sum + n.Weight, 0);
|
|
41
|
-
let r = Math.floor(Math.random() * totalWeight);
|
|
42
|
-
let chosen = healthy[0];
|
|
43
|
-
for (const node of healthy) {
|
|
44
|
-
r -= node.Weight;
|
|
45
|
-
if (r < 0) {
|
|
46
|
-
chosen = node;
|
|
47
|
-
break;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return `https://${ORBS_HOST}/${chosen.NodeId}/1/mainnet/toncenter-api-v2/jsonRPC`;
|
|
51
|
-
}
|
|
52
|
-
async function getCachedHttpEndpoint() {
|
|
53
|
-
if (_cache && Date.now() - _cache.ts < ENDPOINT_CACHE_TTL_MS) {
|
|
54
|
-
return _cache.url;
|
|
55
|
-
}
|
|
56
|
-
let url;
|
|
57
|
-
if (_toncenterApiKey) {
|
|
58
|
-
try {
|
|
59
|
-
const testUrl = `https://toncenter.com/api/v2/getAddressInformation?address=EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c`;
|
|
60
|
-
const res = await fetch(testUrl, {
|
|
61
|
-
headers: { "X-API-Key": _toncenterApiKey },
|
|
62
|
-
signal: AbortSignal.timeout(5e3)
|
|
63
|
-
});
|
|
64
|
-
if (!res.ok) throw new Error(`TonCenter ${res.status}`);
|
|
65
|
-
url = TONCENTER_URL;
|
|
66
|
-
} catch {
|
|
67
|
-
try {
|
|
68
|
-
url = await discoverOrbsEndpoint();
|
|
69
|
-
} catch {
|
|
70
|
-
url = TONCENTER_URL;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
} else {
|
|
74
|
-
try {
|
|
75
|
-
url = await discoverOrbsEndpoint();
|
|
76
|
-
} catch {
|
|
77
|
-
url = TONCENTER_URL;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
_cache = { url, ts: Date.now() };
|
|
81
|
-
return url;
|
|
82
|
-
}
|
|
83
|
-
function invalidateEndpointCache() {
|
|
84
|
-
_cache = null;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// src/ton/wallet-service.ts
|
|
88
|
-
import { mnemonicNew, mnemonicToPrivateKey, mnemonicValidate } from "@ton/crypto";
|
|
89
|
-
import { WalletContractV5R1, TonClient, fromNano } from "@ton/ton";
|
|
90
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
13
|
+
// src/workspace/manager.ts
|
|
14
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from "fs";
|
|
91
15
|
import { join, dirname } from "path";
|
|
92
|
-
|
|
93
|
-
var
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const keyPair = await mnemonicToPrivateKey(mnemonic);
|
|
100
|
-
const wallet = WalletContractV5R1.create({
|
|
101
|
-
workchain: 0,
|
|
102
|
-
publicKey: keyPair.publicKey
|
|
103
|
-
});
|
|
104
|
-
const address = wallet.address.toString({ bounceable: true, testOnly: false });
|
|
105
|
-
return {
|
|
106
|
-
version: "w5r1",
|
|
107
|
-
address,
|
|
108
|
-
publicKey: keyPair.publicKey.toString("hex"),
|
|
109
|
-
mnemonic,
|
|
110
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
function saveWallet(wallet) {
|
|
114
|
-
const dir = dirname(WALLET_FILE);
|
|
115
|
-
if (!existsSync(dir)) {
|
|
116
|
-
mkdirSync(dir, { recursive: true });
|
|
16
|
+
import { fileURLToPath } from "url";
|
|
17
|
+
var log = createLogger("Workspace");
|
|
18
|
+
function findPackageRoot() {
|
|
19
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
for (let i = 0; i < 10; i++) {
|
|
21
|
+
if (existsSync(join(dir, "package.json"))) return dir;
|
|
22
|
+
dir = dirname(dir);
|
|
117
23
|
}
|
|
118
|
-
|
|
119
|
-
_walletCache = void 0;
|
|
120
|
-
_keyPairCache = null;
|
|
24
|
+
return process.cwd();
|
|
121
25
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
26
|
+
var TEMPLATES_DIR = join(findPackageRoot(), "src", "templates");
|
|
27
|
+
async function ensureWorkspace(config) {
|
|
28
|
+
const silent = config?.silent ?? false;
|
|
29
|
+
if (!existsSync(TELETON_ROOT)) {
|
|
30
|
+
mkdirSync(TELETON_ROOT, { recursive: true });
|
|
31
|
+
if (!silent) log.info(`Created Teleton root at ${TELETON_ROOT}`);
|
|
127
32
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (!parsed.mnemonic || !Array.isArray(parsed.mnemonic) || parsed.mnemonic.length !== 24) {
|
|
132
|
-
throw new Error("Invalid wallet.json: mnemonic must be a 24-word array");
|
|
133
|
-
}
|
|
134
|
-
_walletCache = parsed;
|
|
135
|
-
return _walletCache;
|
|
136
|
-
} catch (error) {
|
|
137
|
-
log.error({ err: error }, "Failed to load wallet");
|
|
138
|
-
_walletCache = null;
|
|
139
|
-
return null;
|
|
33
|
+
if (!existsSync(WORKSPACE_ROOT)) {
|
|
34
|
+
mkdirSync(WORKSPACE_ROOT, { recursive: true });
|
|
35
|
+
if (!silent) log.info(`Created workspace at ${WORKSPACE_ROOT}`);
|
|
140
36
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
37
|
+
const directories = [
|
|
38
|
+
WORKSPACE_PATHS.MEMORY_DIR,
|
|
39
|
+
WORKSPACE_PATHS.DOWNLOADS_DIR,
|
|
40
|
+
WORKSPACE_PATHS.UPLOADS_DIR,
|
|
41
|
+
WORKSPACE_PATHS.TEMP_DIR,
|
|
42
|
+
WORKSPACE_PATHS.MEMES_DIR
|
|
43
|
+
];
|
|
44
|
+
for (const dir of directories) {
|
|
45
|
+
if (!existsSync(dir)) {
|
|
46
|
+
mkdirSync(dir, { recursive: true });
|
|
47
|
+
}
|
|
149
48
|
}
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
49
|
+
const workspace = {
|
|
50
|
+
root: TELETON_ROOT,
|
|
51
|
+
workspace: WORKSPACE_ROOT,
|
|
52
|
+
// Workspace files
|
|
53
|
+
soulPath: WORKSPACE_PATHS.SOUL,
|
|
54
|
+
memoryPath: WORKSPACE_PATHS.MEMORY,
|
|
55
|
+
identityPath: WORKSPACE_PATHS.IDENTITY,
|
|
56
|
+
userPath: WORKSPACE_PATHS.USER,
|
|
57
|
+
strategyPath: WORKSPACE_PATHS.STRATEGY,
|
|
58
|
+
securityPath: WORKSPACE_PATHS.SECURITY,
|
|
59
|
+
// Workspace directories
|
|
60
|
+
memoryDir: WORKSPACE_PATHS.MEMORY_DIR,
|
|
61
|
+
downloadsDir: WORKSPACE_PATHS.DOWNLOADS_DIR,
|
|
62
|
+
uploadsDir: WORKSPACE_PATHS.UPLOADS_DIR,
|
|
63
|
+
tempDir: WORKSPACE_PATHS.TEMP_DIR,
|
|
64
|
+
memesDir: WORKSPACE_PATHS.MEMES_DIR,
|
|
65
|
+
// Protected files (outside workspace)
|
|
66
|
+
sessionPath: join(TELETON_ROOT, "telegram_session.txt"),
|
|
67
|
+
configPath: join(TELETON_ROOT, "config.yaml"),
|
|
68
|
+
walletPath: join(TELETON_ROOT, "wallet.json")
|
|
162
69
|
};
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const wallet = loadWallet();
|
|
166
|
-
return wallet?.address || null;
|
|
167
|
-
}
|
|
168
|
-
async function getCachedTonClient() {
|
|
169
|
-
const endpoint = await getCachedHttpEndpoint();
|
|
170
|
-
if (_tonClientCache && _tonClientCache.endpoint === endpoint) {
|
|
171
|
-
return _tonClientCache.client;
|
|
172
|
-
}
|
|
173
|
-
const apiKey = getToncenterApiKey();
|
|
174
|
-
const client = new TonClient({ endpoint, ...apiKey && { apiKey } });
|
|
175
|
-
_tonClientCache = { client, endpoint };
|
|
176
|
-
return client;
|
|
177
|
-
}
|
|
178
|
-
function invalidateTonClientCache() {
|
|
179
|
-
_tonClientCache = null;
|
|
180
|
-
invalidateEndpointCache();
|
|
181
|
-
}
|
|
182
|
-
async function getKeyPair() {
|
|
183
|
-
if (_keyPairCache) return _keyPairCache;
|
|
184
|
-
const wallet = loadWallet();
|
|
185
|
-
if (!wallet) return null;
|
|
186
|
-
_keyPairCache = await mnemonicToPrivateKey(wallet.mnemonic);
|
|
187
|
-
return _keyPairCache;
|
|
188
|
-
}
|
|
189
|
-
async function getWalletBalance(address) {
|
|
190
|
-
try {
|
|
191
|
-
const client = await getCachedTonClient();
|
|
192
|
-
const { Address } = await import("@ton/core");
|
|
193
|
-
const addressObj = Address.parse(address);
|
|
194
|
-
const balance = await client.getBalance(addressObj);
|
|
195
|
-
const balanceFormatted = fromNano(balance);
|
|
196
|
-
return {
|
|
197
|
-
balance: balanceFormatted,
|
|
198
|
-
balanceNano: balance.toString()
|
|
199
|
-
};
|
|
200
|
-
} catch (error) {
|
|
201
|
-
log.error({ err: error }, "Failed to get balance");
|
|
202
|
-
return null;
|
|
70
|
+
if (config?.ensureTemplates) {
|
|
71
|
+
await bootstrapTemplates(workspace, silent);
|
|
203
72
|
}
|
|
73
|
+
return workspace;
|
|
204
74
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
75
|
+
async function bootstrapTemplates(workspace, silent = false) {
|
|
76
|
+
const templates = [
|
|
77
|
+
{ name: "SOUL.md", path: workspace.soulPath },
|
|
78
|
+
{ name: "MEMORY.md", path: workspace.memoryPath },
|
|
79
|
+
{ name: "IDENTITY.md", path: workspace.identityPath },
|
|
80
|
+
{ name: "USER.md", path: workspace.userPath },
|
|
81
|
+
{ name: "SECURITY.md", path: workspace.securityPath },
|
|
82
|
+
{ name: "STRATEGY.md", path: workspace.strategyPath }
|
|
83
|
+
];
|
|
84
|
+
for (const template of templates) {
|
|
85
|
+
if (!existsSync(template.path)) {
|
|
86
|
+
const templateSource = join(TEMPLATES_DIR, template.name);
|
|
87
|
+
if (existsSync(templateSource)) {
|
|
88
|
+
copyFileSync(templateSource, template.path);
|
|
89
|
+
if (!silent) log.info(`Created ${template.name}`);
|
|
219
90
|
}
|
|
220
91
|
}
|
|
221
|
-
} catch {
|
|
222
92
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
const price = data["the-open-network"]?.usd;
|
|
232
|
-
if (typeof price === "number" && price > 0) {
|
|
233
|
-
_tonPriceCache = { usd: price, source: "CoinGecko", timestamp: Date.now() };
|
|
234
|
-
return _tonPriceCache;
|
|
235
|
-
}
|
|
236
|
-
} catch (error) {
|
|
237
|
-
log.error({ err: error }, "Failed to get TON price");
|
|
93
|
+
}
|
|
94
|
+
function isNewWorkspace(workspace) {
|
|
95
|
+
return !existsSync(workspace.configPath);
|
|
96
|
+
}
|
|
97
|
+
function loadTemplate(name) {
|
|
98
|
+
const templatePath = join(TEMPLATES_DIR, name);
|
|
99
|
+
if (!existsSync(templatePath)) {
|
|
100
|
+
throw new Error(`Template ${name} not found at ${templatePath}`);
|
|
238
101
|
}
|
|
239
|
-
return
|
|
102
|
+
return readFileSync(templatePath, "utf-8");
|
|
240
103
|
}
|
|
241
104
|
|
|
242
105
|
// src/config/schema.ts
|
|
@@ -351,6 +214,13 @@ var _DevObject = z.object({
|
|
|
351
214
|
hot_reload: z.boolean().default(false).describe("Enable plugin hot-reload (watches ~/.teleton/plugins/ for changes)")
|
|
352
215
|
});
|
|
353
216
|
var DevConfigSchema = _DevObject.default(_DevObject.parse({}));
|
|
217
|
+
var _ApiObject = z.object({
|
|
218
|
+
enabled: z.boolean().default(false).describe("Enable HTTPS Management API server"),
|
|
219
|
+
port: z.number().min(1).max(65535).default(7778).describe("HTTPS server port"),
|
|
220
|
+
key_hash: z.string().default("").describe("SHA-256 hash of the API key (auto-generated if empty)"),
|
|
221
|
+
allowed_ips: z.array(z.string()).default([]).describe("IP whitelist (empty = allow all authenticated requests)")
|
|
222
|
+
});
|
|
223
|
+
var ApiConfigSchema = _ApiObject.default(_ApiObject.parse({}));
|
|
354
224
|
var McpServerSchema = z.object({
|
|
355
225
|
command: z.string().optional().describe("Stdio command (e.g. 'npx @modelcontextprotocol/server-filesystem /tmp')"),
|
|
356
226
|
args: z.array(z.string()).optional().describe("Explicit args array (overrides command splitting)"),
|
|
@@ -410,6 +280,7 @@ var ConfigSchema = z.object({
|
|
|
410
280
|
dev: DevConfigSchema,
|
|
411
281
|
tool_rag: ToolRagConfigSchema,
|
|
412
282
|
capabilities: CapabilitiesConfigSchema,
|
|
283
|
+
api: ApiConfigSchema.optional(),
|
|
413
284
|
ton_proxy: TonProxyConfigSchema,
|
|
414
285
|
mcp: McpConfigSchema,
|
|
415
286
|
plugins: z.record(z.string(), z.unknown()).default({}).describe("Per-plugin config (key = plugin name with underscores)"),
|
|
@@ -421,115 +292,10 @@ var ConfigSchema = z.object({
|
|
|
421
292
|
tavily_api_key: z.string().optional().describe("Tavily API key for web search & extract (free at https://tavily.com)")
|
|
422
293
|
});
|
|
423
294
|
|
|
424
|
-
// src/workspace/manager.ts
|
|
425
|
-
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, copyFileSync } from "fs";
|
|
426
|
-
import { join as join2, dirname as dirname2 } from "path";
|
|
427
|
-
import { fileURLToPath } from "url";
|
|
428
|
-
var log2 = createLogger("Workspace");
|
|
429
|
-
function findPackageRoot() {
|
|
430
|
-
let dir = dirname2(fileURLToPath(import.meta.url));
|
|
431
|
-
for (let i = 0; i < 10; i++) {
|
|
432
|
-
if (existsSync2(join2(dir, "package.json"))) return dir;
|
|
433
|
-
dir = dirname2(dir);
|
|
434
|
-
}
|
|
435
|
-
return process.cwd();
|
|
436
|
-
}
|
|
437
|
-
var TEMPLATES_DIR = join2(findPackageRoot(), "src", "templates");
|
|
438
|
-
async function ensureWorkspace(config) {
|
|
439
|
-
const silent = config?.silent ?? false;
|
|
440
|
-
if (!existsSync2(TELETON_ROOT)) {
|
|
441
|
-
mkdirSync2(TELETON_ROOT, { recursive: true });
|
|
442
|
-
if (!silent) log2.info(`Created Teleton root at ${TELETON_ROOT}`);
|
|
443
|
-
}
|
|
444
|
-
if (!existsSync2(WORKSPACE_ROOT)) {
|
|
445
|
-
mkdirSync2(WORKSPACE_ROOT, { recursive: true });
|
|
446
|
-
if (!silent) log2.info(`Created workspace at ${WORKSPACE_ROOT}`);
|
|
447
|
-
}
|
|
448
|
-
const directories = [
|
|
449
|
-
WORKSPACE_PATHS.MEMORY_DIR,
|
|
450
|
-
WORKSPACE_PATHS.DOWNLOADS_DIR,
|
|
451
|
-
WORKSPACE_PATHS.UPLOADS_DIR,
|
|
452
|
-
WORKSPACE_PATHS.TEMP_DIR,
|
|
453
|
-
WORKSPACE_PATHS.MEMES_DIR
|
|
454
|
-
];
|
|
455
|
-
for (const dir of directories) {
|
|
456
|
-
if (!existsSync2(dir)) {
|
|
457
|
-
mkdirSync2(dir, { recursive: true });
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
const workspace = {
|
|
461
|
-
root: TELETON_ROOT,
|
|
462
|
-
workspace: WORKSPACE_ROOT,
|
|
463
|
-
// Workspace files
|
|
464
|
-
soulPath: WORKSPACE_PATHS.SOUL,
|
|
465
|
-
memoryPath: WORKSPACE_PATHS.MEMORY,
|
|
466
|
-
identityPath: WORKSPACE_PATHS.IDENTITY,
|
|
467
|
-
userPath: WORKSPACE_PATHS.USER,
|
|
468
|
-
strategyPath: WORKSPACE_PATHS.STRATEGY,
|
|
469
|
-
securityPath: WORKSPACE_PATHS.SECURITY,
|
|
470
|
-
// Workspace directories
|
|
471
|
-
memoryDir: WORKSPACE_PATHS.MEMORY_DIR,
|
|
472
|
-
downloadsDir: WORKSPACE_PATHS.DOWNLOADS_DIR,
|
|
473
|
-
uploadsDir: WORKSPACE_PATHS.UPLOADS_DIR,
|
|
474
|
-
tempDir: WORKSPACE_PATHS.TEMP_DIR,
|
|
475
|
-
memesDir: WORKSPACE_PATHS.MEMES_DIR,
|
|
476
|
-
// Protected files (outside workspace)
|
|
477
|
-
sessionPath: join2(TELETON_ROOT, "telegram_session.txt"),
|
|
478
|
-
configPath: join2(TELETON_ROOT, "config.yaml"),
|
|
479
|
-
walletPath: join2(TELETON_ROOT, "wallet.json")
|
|
480
|
-
};
|
|
481
|
-
if (config?.ensureTemplates) {
|
|
482
|
-
await bootstrapTemplates(workspace, silent);
|
|
483
|
-
}
|
|
484
|
-
return workspace;
|
|
485
|
-
}
|
|
486
|
-
async function bootstrapTemplates(workspace, silent = false) {
|
|
487
|
-
const templates = [
|
|
488
|
-
{ name: "SOUL.md", path: workspace.soulPath },
|
|
489
|
-
{ name: "MEMORY.md", path: workspace.memoryPath },
|
|
490
|
-
{ name: "IDENTITY.md", path: workspace.identityPath },
|
|
491
|
-
{ name: "USER.md", path: workspace.userPath },
|
|
492
|
-
{ name: "SECURITY.md", path: workspace.securityPath },
|
|
493
|
-
{ name: "STRATEGY.md", path: workspace.strategyPath }
|
|
494
|
-
];
|
|
495
|
-
for (const template of templates) {
|
|
496
|
-
if (!existsSync2(template.path)) {
|
|
497
|
-
const templateSource = join2(TEMPLATES_DIR, template.name);
|
|
498
|
-
if (existsSync2(templateSource)) {
|
|
499
|
-
copyFileSync(templateSource, template.path);
|
|
500
|
-
if (!silent) log2.info(`Created ${template.name}`);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
function isNewWorkspace(workspace) {
|
|
506
|
-
return !existsSync2(workspace.configPath);
|
|
507
|
-
}
|
|
508
|
-
function loadTemplate(name) {
|
|
509
|
-
const templatePath = join2(TEMPLATES_DIR, name);
|
|
510
|
-
if (!existsSync2(templatePath)) {
|
|
511
|
-
throw new Error(`Template ${name} not found at ${templatePath}`);
|
|
512
|
-
}
|
|
513
|
-
return readFileSync2(templatePath, "utf-8");
|
|
514
|
-
}
|
|
515
|
-
|
|
516
295
|
export {
|
|
517
296
|
DealsConfigSchema,
|
|
518
297
|
ConfigSchema,
|
|
519
298
|
ensureWorkspace,
|
|
520
299
|
isNewWorkspace,
|
|
521
|
-
loadTemplate
|
|
522
|
-
setToncenterApiKey,
|
|
523
|
-
invalidateEndpointCache,
|
|
524
|
-
generateWallet,
|
|
525
|
-
saveWallet,
|
|
526
|
-
loadWallet,
|
|
527
|
-
walletExists,
|
|
528
|
-
importWallet,
|
|
529
|
-
getWalletAddress,
|
|
530
|
-
getCachedTonClient,
|
|
531
|
-
invalidateTonClientCache,
|
|
532
|
-
getKeyPair,
|
|
533
|
-
getWalletBalance,
|
|
534
|
-
getTonPrice
|
|
300
|
+
loadTemplate
|
|
535
301
|
};
|