teleton 0.7.2 → 0.7.4
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 +31 -12
- package/dist/{chunk-ND2X5FWB.js → chunk-5PLZ3KSO.js} +16 -3
- package/dist/{chunk-NERLQY2H.js → chunk-BGC2IUM5.js} +73 -15
- package/dist/{chunk-FNV5FF35.js → chunk-EK7M5K26.js} +29 -13
- package/dist/chunk-JQDLW7IE.js +107 -0
- package/dist/{chunk-VSMUAU5X.js → chunk-LAQOUFOJ.js} +2419 -2132
- package/dist/chunk-QOQWUUA4.js +158 -0
- package/dist/{chunk-LRCPA7SC.js → chunk-RMLQS3X6.js} +15 -3
- package/dist/{chunk-UDD7FYOU.js → chunk-WIKM24GZ.js} +1 -18
- package/dist/{chunk-RBU6JXD3.js → chunk-XDYDA2KV.js} +1 -1
- package/dist/{chunk-JHKWHGBM.js → chunk-YFG2QHLA.js} +380 -47
- package/dist/cli/index.js +216 -272
- package/dist/{client-3VWE7NC4.js → client-RTNALK7W.js} +3 -2
- package/dist/{get-my-gifts-RI7FAXAL.js → get-my-gifts-TPVUGUWT.js} +1 -1
- package/dist/index.js +9 -10
- package/dist/{memory-5SS3Q5EA.js → memory-JQZ6MTRU.js} +2 -2
- package/dist/{migrate-M7SJMDOL.js → migrate-GS5ACQDA.js} +2 -2
- package/dist/{server-NPSODUMA.js → server-TCJOBV3D.js} +292 -11
- package/dist/{setup-server-C7ZTPHD5.js → setup-server-YHYJLAMA.js} +77 -112
- package/dist/{tool-index-MIVK3D7H.js → tool-index-6HBRVXVG.js} +1 -1
- package/dist/web/assets/index-B6M9knfJ.css +1 -0
- package/dist/web/assets/index-DAGeQfVZ.js +72 -0
- package/dist/web/assets/{index.es-D81xLR29.js → index.es-CqZHj0tz.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +2 -2
- package/dist/chunk-EHEV7FJ7.js +0 -157
- package/dist/chunk-QUAPFI2N.js +0 -42
- package/dist/endpoint-FLYNEZ2F.js +0 -7
- package/dist/format-transactions-FD74HI5N.js +0 -9
- package/dist/web/assets/index-BqwoDycr.js +0 -72
- package/dist/web/assets/index-CRDIf07k.css +0 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
- **Full Telegram access** - Operates as a real user via MTProto (GramJS), not a limited bot
|
|
23
23
|
- **Agentic loop** - Up to 5 iterations of tool calling per message, the agent thinks, acts, observes, and repeats
|
|
24
|
-
- **Multi-Provider LLM** - Anthropic, OpenAI, Google Gemini, xAI Grok, Groq, OpenRouter, Moonshot, Mistral, Cocoon, Local
|
|
24
|
+
- **Multi-Provider LLM** - Anthropic, Claude Code, OpenAI, Google Gemini, xAI Grok, Groq, OpenRouter, Moonshot, Mistral, Cocoon, Local (11 providers)
|
|
25
25
|
- **TON Blockchain** - Built-in W5R1 wallet, send/receive TON & jettons, swap on STON.fi and DeDust, NFTs, DNS domains
|
|
26
26
|
- **Persistent memory** - Hybrid RAG (sqlite-vec + FTS5), auto-compaction with AI summarization, daily logs
|
|
27
27
|
- **100+ built-in tools** - Messaging, media, blockchain, DEX trading, deals, DNS, journaling, and more
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
| Category | Tools | Description |
|
|
39
39
|
| ------------- | ----- | ------------------------------------------------------------------------------------------------------------------ |
|
|
40
|
-
| Telegram |
|
|
40
|
+
| Telegram | 73 | Messaging, media, chats, groups, polls, stickers, gifts, stars, stories, contacts, folders, profile, memory, tasks, voice transcription, scheduled messages |
|
|
41
41
|
| TON & Jettons | 15 | W5R1 wallet, send/receive TON & jettons, balances, prices, holders, history, charts, NFTs, smart DEX router |
|
|
42
42
|
| STON.fi DEX | 5 | Swap, quote, search, trending tokens, liquidity pools |
|
|
43
43
|
| DeDust DEX | 5 | Swap, quote, pools, prices, token analytics (holders, top traders, buy/sell tax) |
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
|
|
52
52
|
| Capability | Description |
|
|
53
53
|
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
54
|
-
| **Multi-Provider LLM** | Switch between Anthropic, OpenAI, Google, xAI, Groq, OpenRouter, Moonshot, Mistral, Cocoon, or Local
|
|
54
|
+
| **Multi-Provider LLM** | Switch between Anthropic, Claude Code, OpenAI, Google, xAI, Groq, OpenRouter, Moonshot, Mistral, Cocoon, or Local — Dashboard validates API key before switching |
|
|
55
55
|
| **RAG + Hybrid Search** | Local ONNX embeddings (384d) or Voyage AI (512d/1024d) with FTS5 keyword + sqlite-vec cosine similarity, fused via RRF |
|
|
56
56
|
| **Auto-Compaction** | AI-summarized context management prevents overflow, preserves key information in `memory/*.md` files |
|
|
57
57
|
| **Observation Masking** | Compresses old tool results to one-line summaries, saving ~90% context window |
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
## Prerequisites
|
|
72
72
|
|
|
73
73
|
- **Node.js 20.0.0+** - [Download](https://nodejs.org/)
|
|
74
|
-
- **LLM API Key** - One of: [Anthropic](https://console.anthropic.com/) (recommended), [OpenAI](https://platform.openai.com/), [Google](https://aistudio.google.com/), [xAI](https://console.x.ai/), [Groq](https://console.groq.com/), [OpenRouter](https://openrouter.ai/)
|
|
74
|
+
- **LLM API Key** - One of: [Anthropic](https://console.anthropic.com/) (recommended), [OpenAI](https://platform.openai.com/), [Google](https://aistudio.google.com/), [xAI](https://console.x.ai/), [Groq](https://console.groq.com/), [OpenRouter](https://openrouter.ai/), [Moonshot](https://platform.moonshot.ai/), [Mistral](https://console.mistral.ai/) — or keyless: Claude Code (auto-detect), Cocoon (TON), Local (Ollama/vLLM)
|
|
75
75
|
- **Telegram Account** - Dedicated account recommended for security
|
|
76
76
|
- **Telegram API Credentials** - From [my.telegram.org/apps](https://my.telegram.org/apps)
|
|
77
77
|
- **Your Telegram User ID** - Message [@userinfobot](https://t.me/userinfobot)
|
|
@@ -109,7 +109,7 @@ teleton setup
|
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
The wizard will configure:
|
|
112
|
-
- LLM provider selection (Anthropic, OpenAI, Google, xAI, Groq, OpenRouter)
|
|
112
|
+
- LLM provider selection (11 providers: Anthropic, Claude Code, OpenAI, Google, xAI, Groq, OpenRouter, Moonshot, Mistral, Cocoon, Local)
|
|
113
113
|
- Telegram authentication (API credentials, phone, login code)
|
|
114
114
|
- Access policies (DM/group response rules)
|
|
115
115
|
- Admin user ID
|
|
@@ -152,10 +152,10 @@ The `teleton setup` wizard generates a fully configured `~/.teleton/config.yaml`
|
|
|
152
152
|
|
|
153
153
|
```yaml
|
|
154
154
|
agent:
|
|
155
|
-
provider: "anthropic" # anthropic | openai | google | xai | groq | openrouter
|
|
155
|
+
provider: "anthropic" # anthropic | claude-code | openai | google | xai | groq | openrouter | moonshot | mistral | cocoon | local
|
|
156
156
|
api_key: "sk-ant-api03-..."
|
|
157
|
-
model: "claude-opus-4-
|
|
158
|
-
utility_model: "claude-
|
|
157
|
+
model: "claude-opus-4-6"
|
|
158
|
+
utility_model: "claude-haiku-4-5-20251001" # for summarization, compaction, vision
|
|
159
159
|
max_agentic_iterations: 5
|
|
160
160
|
|
|
161
161
|
telegram:
|
|
@@ -183,6 +183,24 @@ webui: # Optional: Web dashboard
|
|
|
183
183
|
# auth_token: "..." # Auto-generated if omitted
|
|
184
184
|
```
|
|
185
185
|
|
|
186
|
+
### Supported Models
|
|
187
|
+
|
|
188
|
+
All models are defined in `src/config/model-catalog.ts` and shared across the CLI setup, WebUI setup wizard, and Dashboard. To add a model, add it there — it will appear everywhere automatically.
|
|
189
|
+
|
|
190
|
+
| Provider | Models |
|
|
191
|
+
|----------|--------|
|
|
192
|
+
| **Anthropic** | Claude Opus 4.6, Claude Opus 4.5, Claude Sonnet 4.6, Claude Haiku 4.5 |
|
|
193
|
+
| **Claude Code** | Same as Anthropic (auto-detected credentials) |
|
|
194
|
+
| **OpenAI** | GPT-5, GPT-5 Pro, GPT-5 Mini, GPT-5.1, GPT-4o, GPT-4.1, GPT-4.1 Mini, o4 Mini, o3, Codex Mini |
|
|
195
|
+
| **Google** | Gemini 3 Pro (preview), Gemini 3 Flash (preview), Gemini 2.5 Pro, Gemini 2.5 Flash, Gemini 2.5 Flash Lite, Gemini 2.0 Flash |
|
|
196
|
+
| **xAI** | Grok 4.1 Fast, Grok 4 Fast, Grok 4, Grok Code, Grok 3 |
|
|
197
|
+
| **Groq** | Llama 4 Maverick, Qwen3 32B, DeepSeek R1 70B, Llama 3.3 70B |
|
|
198
|
+
| **OpenRouter** | Claude Opus/Sonnet, GPT-5, Gemini, DeepSeek R1/V3, Qwen3 Coder/Max/235B, Nemotron, Sonar Pro, MiniMax, Grok 4 |
|
|
199
|
+
| **Moonshot** | Kimi K2.5, Kimi K2 Thinking |
|
|
200
|
+
| **Mistral** | Devstral Small/Medium, Mistral Large, Magistral Small |
|
|
201
|
+
| **Cocoon** | Qwen/Qwen3-32B (decentralized, pays in TON) |
|
|
202
|
+
| **Local** | Auto-detected (Ollama, vLLM, LM Studio) |
|
|
203
|
+
|
|
186
204
|
### MCP Servers
|
|
187
205
|
|
|
188
206
|
Connect external tool servers via the [Model Context Protocol](https://modelcontextprotocol.io/). No code needed - tools are auto-discovered and registered at startup.
|
|
@@ -283,7 +301,7 @@ Teleton includes an **optional web dashboard** for monitoring and configuration.
|
|
|
283
301
|
|
|
284
302
|
### Features
|
|
285
303
|
|
|
286
|
-
- **Dashboard**: System status, uptime, model info, session count, memory stats
|
|
304
|
+
- **Dashboard**: System status, uptime, model info, session count, memory stats, provider switching with API key validation
|
|
287
305
|
- **Tools Management**: View all tools grouped by module, toggle enable/disable, change scope per tool
|
|
288
306
|
- **Plugin Marketplace**: Install, update, and manage plugins from registry with secrets management
|
|
289
307
|
- **Soul Editor**: Edit SOUL.md, SECURITY.md, STRATEGY.md, MEMORY.md with unsaved changes warning
|
|
@@ -386,7 +404,7 @@ All admin commands support `/`, `!`, or `.` prefix:
|
|
|
386
404
|
|
|
387
405
|
| Layer | Technology |
|
|
388
406
|
|-------|------------|
|
|
389
|
-
| LLM | Multi-provider via [pi-ai](https://github.com/mariozechner/pi-ai) (Anthropic, OpenAI, Google, xAI, Groq, OpenRouter) |
|
|
407
|
+
| LLM | Multi-provider via [pi-ai](https://github.com/mariozechner/pi-ai) (11 providers: Anthropic, Claude Code, OpenAI, Google, xAI, Groq, OpenRouter, Moonshot, Mistral, Cocoon, Local) |
|
|
390
408
|
| Telegram Userbot | [GramJS](https://gram.js.org/) (MTProto) |
|
|
391
409
|
| Inline Bot | [Grammy](https://grammy.dev/) (Bot API, for deals) |
|
|
392
410
|
| Blockchain | [TON SDK](https://github.com/ton-org/ton) (W5R1 wallet) |
|
|
@@ -414,7 +432,7 @@ src/
|
|
|
414
432
|
│ ├── module-loader.ts # Built-in module loading (deals → +5 tools)
|
|
415
433
|
│ ├── plugin-loader.ts # External plugin discovery, validation, hot-reload
|
|
416
434
|
│ ├── mcp-loader.ts # MCP client (stdio/SSE), tool discovery, lifecycle
|
|
417
|
-
│ ├── telegram/ # Telegram operations (
|
|
435
|
+
│ ├── telegram/ # Telegram operations (73 tools)
|
|
418
436
|
│ ├── ton/ # TON blockchain + jettons + DEX router (15 tools)
|
|
419
437
|
│ ├── stonfi/ # STON.fi DEX (5 tools)
|
|
420
438
|
│ ├── dedust/ # DeDust DEX (5 tools)
|
|
@@ -463,7 +481,8 @@ src/
|
|
|
463
481
|
│ └── loader.ts # 10 sections: soul + security + strategy + memory + context + ...
|
|
464
482
|
├── config/ # Configuration
|
|
465
483
|
│ ├── schema.ts # Zod schemas + validation
|
|
466
|
-
│
|
|
484
|
+
│ ├── providers.ts # Multi-provider LLM registry (11 providers)
|
|
485
|
+
│ └── model-catalog.ts # Shared model catalog (60+ models across all providers)
|
|
467
486
|
├── webui/ # Optional web dashboard
|
|
468
487
|
│ ├── server.ts # Hono server, auth middleware, static serving
|
|
469
488
|
│ └── routes/ # 11 API route groups (status, tools, logs, memory, soul, plugins, mcp, tasks, workspace, config, marketplace)
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getClaudeCodeApiKey,
|
|
3
|
+
refreshClaudeCodeApiKey
|
|
4
|
+
} from "./chunk-JQDLW7IE.js";
|
|
1
5
|
import {
|
|
2
6
|
getProviderMetadata
|
|
3
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-RMLQS3X6.js";
|
|
4
8
|
import {
|
|
5
9
|
appendToTranscript,
|
|
6
10
|
readTranscript
|
|
@@ -92,12 +96,13 @@ function sanitizeToolsForGemini(tools) {
|
|
|
92
96
|
// src/agent/client.ts
|
|
93
97
|
var log = createLogger("LLM");
|
|
94
98
|
function isOAuthToken(apiKey, provider) {
|
|
95
|
-
if (provider && provider !== "anthropic") return false;
|
|
99
|
+
if (provider && provider !== "anthropic" && provider !== "claude-code") return false;
|
|
96
100
|
return apiKey.startsWith("sk-ant-oat01-");
|
|
97
101
|
}
|
|
98
102
|
function getEffectiveApiKey(provider, rawKey) {
|
|
99
103
|
if (provider === "local") return "local";
|
|
100
104
|
if (provider === "cocoon") return "";
|
|
105
|
+
if (provider === "claude-code") return getClaudeCodeApiKey(rawKey);
|
|
101
106
|
return rawKey;
|
|
102
107
|
}
|
|
103
108
|
var modelCache = /* @__PURE__ */ new Map();
|
|
@@ -307,7 +312,15 @@ async function chatWithContext(config, options) {
|
|
|
307
312
|
const { stripCocoonPayload } = await import("./tool-adapter-Y3TCEQOC.js");
|
|
308
313
|
completeOptions.onPayload = stripCocoonPayload;
|
|
309
314
|
}
|
|
310
|
-
|
|
315
|
+
let response = await complete(model, context, completeOptions);
|
|
316
|
+
if (provider === "claude-code" && response.stopReason === "error" && response.errorMessage && (response.errorMessage.includes("401") || response.errorMessage.toLowerCase().includes("unauthorized"))) {
|
|
317
|
+
log.warn("Claude Code token rejected (401), refreshing credentials and retrying...");
|
|
318
|
+
const refreshedKey = refreshClaudeCodeApiKey();
|
|
319
|
+
if (refreshedKey) {
|
|
320
|
+
completeOptions.apiKey = refreshedKey;
|
|
321
|
+
response = await complete(model, context, completeOptions);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
311
324
|
if (isCocoon) {
|
|
312
325
|
const textBlock = response.content.find((b) => b.type === "text");
|
|
313
326
|
if (textBlock?.type === "text" && textBlock.text.includes("<tool_call>")) {
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getCachedHttpEndpoint
|
|
3
|
-
} from "./chunk-QUAPFI2N.js";
|
|
4
1
|
import {
|
|
5
2
|
COINGECKO_API_URL,
|
|
6
3
|
tonapiFetch
|
|
@@ -25,10 +22,55 @@ import { mnemonicNew, mnemonicToPrivateKey, mnemonicValidate } from "@ton/crypto
|
|
|
25
22
|
import { WalletContractV5R1, TonClient, fromNano } from "@ton/ton";
|
|
26
23
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
27
24
|
import { join, dirname } from "path";
|
|
25
|
+
|
|
26
|
+
// src/ton/endpoint.ts
|
|
27
|
+
var ENDPOINT_CACHE_TTL_MS = 6e4;
|
|
28
|
+
var ORBS_HOST = "ton.access.orbs.network";
|
|
29
|
+
var ORBS_TOPOLOGY_URL = `https://${ORBS_HOST}/mngr/nodes?npm_version=2.3.3`;
|
|
30
|
+
var TONCENTER_FALLBACK = `https://toncenter.com/api/v2/jsonRPC`;
|
|
31
|
+
var _cache = null;
|
|
32
|
+
async function discoverOrbsEndpoint() {
|
|
33
|
+
const res = await fetch(ORBS_TOPOLOGY_URL);
|
|
34
|
+
const nodes = await res.json();
|
|
35
|
+
const healthy = nodes.filter(
|
|
36
|
+
(n) => n.Healthy === "1" && n.Weight > 0 && n.Mngr?.health?.["v2-mainnet"]
|
|
37
|
+
);
|
|
38
|
+
if (healthy.length === 0) throw new Error("no healthy orbs nodes");
|
|
39
|
+
const totalWeight = healthy.reduce((sum, n) => sum + n.Weight, 0);
|
|
40
|
+
let r = Math.floor(Math.random() * totalWeight);
|
|
41
|
+
let chosen = healthy[0];
|
|
42
|
+
for (const node of healthy) {
|
|
43
|
+
r -= node.Weight;
|
|
44
|
+
if (r < 0) {
|
|
45
|
+
chosen = node;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return `https://${ORBS_HOST}/${chosen.NodeId}/1/mainnet/toncenter-api-v2/jsonRPC`;
|
|
50
|
+
}
|
|
51
|
+
async function getCachedHttpEndpoint() {
|
|
52
|
+
if (_cache && Date.now() - _cache.ts < ENDPOINT_CACHE_TTL_MS) {
|
|
53
|
+
return _cache.url;
|
|
54
|
+
}
|
|
55
|
+
let url;
|
|
56
|
+
try {
|
|
57
|
+
url = await discoverOrbsEndpoint();
|
|
58
|
+
} catch {
|
|
59
|
+
url = TONCENTER_FALLBACK;
|
|
60
|
+
}
|
|
61
|
+
_cache = { url, ts: Date.now() };
|
|
62
|
+
return url;
|
|
63
|
+
}
|
|
64
|
+
function invalidateEndpointCache() {
|
|
65
|
+
_cache = null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/ton/wallet-service.ts
|
|
28
69
|
var log = createLogger("TON");
|
|
29
70
|
var WALLET_FILE = join(TELETON_ROOT, "wallet.json");
|
|
30
71
|
var _walletCache;
|
|
31
72
|
var _keyPairCache = null;
|
|
73
|
+
var _tonClientCache = null;
|
|
32
74
|
async function generateWallet() {
|
|
33
75
|
const mnemonic = await mnemonicNew(24);
|
|
34
76
|
const keyPair = await mnemonicToPrivateKey(mnemonic);
|
|
@@ -100,6 +142,19 @@ function getWalletAddress() {
|
|
|
100
142
|
const wallet = loadWallet();
|
|
101
143
|
return wallet?.address || null;
|
|
102
144
|
}
|
|
145
|
+
async function getCachedTonClient() {
|
|
146
|
+
const endpoint = await getCachedHttpEndpoint();
|
|
147
|
+
if (_tonClientCache && _tonClientCache.endpoint === endpoint) {
|
|
148
|
+
return _tonClientCache.client;
|
|
149
|
+
}
|
|
150
|
+
const client = new TonClient({ endpoint });
|
|
151
|
+
_tonClientCache = { client, endpoint };
|
|
152
|
+
return client;
|
|
153
|
+
}
|
|
154
|
+
function invalidateTonClientCache() {
|
|
155
|
+
_tonClientCache = null;
|
|
156
|
+
invalidateEndpointCache();
|
|
157
|
+
}
|
|
103
158
|
async function getKeyPair() {
|
|
104
159
|
if (_keyPairCache) return _keyPairCache;
|
|
105
160
|
const wallet = loadWallet();
|
|
@@ -109,8 +164,7 @@ async function getKeyPair() {
|
|
|
109
164
|
}
|
|
110
165
|
async function getWalletBalance(address) {
|
|
111
166
|
try {
|
|
112
|
-
const
|
|
113
|
-
const client = new TonClient({ endpoint });
|
|
167
|
+
const client = await getCachedTonClient();
|
|
114
168
|
const { Address } = await import("@ton/core");
|
|
115
169
|
const addressObj = Address.parse(address);
|
|
116
170
|
const balance = await client.getBalance(addressObj);
|
|
@@ -163,7 +217,7 @@ async function getTonPrice() {
|
|
|
163
217
|
|
|
164
218
|
// src/config/schema.ts
|
|
165
219
|
import { z } from "zod";
|
|
166
|
-
var DMPolicy = z.enum(["
|
|
220
|
+
var DMPolicy = z.enum(["allowlist", "open", "disabled"]);
|
|
167
221
|
var GroupPolicy = z.enum(["open", "allowlist", "disabled"]);
|
|
168
222
|
var SessionResetPolicySchema = z.object({
|
|
169
223
|
daily_reset_enabled: z.boolean().default(true).describe("Enable daily session reset"),
|
|
@@ -174,6 +228,7 @@ var SessionResetPolicySchema = z.object({
|
|
|
174
228
|
var AgentConfigSchema = z.object({
|
|
175
229
|
provider: z.enum([
|
|
176
230
|
"anthropic",
|
|
231
|
+
"claude-code",
|
|
177
232
|
"openai",
|
|
178
233
|
"google",
|
|
179
234
|
"xai",
|
|
@@ -186,7 +241,7 @@ var AgentConfigSchema = z.object({
|
|
|
186
241
|
]).default("anthropic"),
|
|
187
242
|
api_key: z.string().default(""),
|
|
188
243
|
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-
|
|
244
|
+
model: z.string().default("claude-opus-4-6"),
|
|
190
245
|
utility_model: z.string().optional().describe("Cheap model for summarization (auto-detected if omitted)"),
|
|
191
246
|
max_tokens: z.number().default(4096),
|
|
192
247
|
temperature: z.number().default(0.7),
|
|
@@ -200,7 +255,7 @@ var TelegramConfigSchema = z.object({
|
|
|
200
255
|
phone: z.string(),
|
|
201
256
|
session_name: z.string().default("teleton_session"),
|
|
202
257
|
session_path: z.string().default("~/.teleton"),
|
|
203
|
-
dm_policy: DMPolicy.default("
|
|
258
|
+
dm_policy: DMPolicy.default("allowlist"),
|
|
204
259
|
allow_from: z.array(z.number()).default([]),
|
|
205
260
|
group_policy: GroupPolicy.default("open"),
|
|
206
261
|
group_allow_from: z.array(z.number()).default([]),
|
|
@@ -220,7 +275,6 @@ var TelegramConfigSchema = z.object({
|
|
|
220
275
|
});
|
|
221
276
|
var StorageConfigSchema = z.object({
|
|
222
277
|
sessions_file: z.string().default("~/.teleton/sessions.json"),
|
|
223
|
-
pairing_file: z.string().default("~/.teleton/pairing.json"),
|
|
224
278
|
memory_file: z.string().default("~/.teleton/memory.json"),
|
|
225
279
|
history_limit: z.number().default(100)
|
|
226
280
|
});
|
|
@@ -233,7 +287,7 @@ var MetaConfigSchema = z.object({
|
|
|
233
287
|
var _DealsObject = z.object({
|
|
234
288
|
enabled: z.boolean().default(true),
|
|
235
289
|
expiry_seconds: z.number().default(120),
|
|
236
|
-
buy_max_floor_percent: z.number().default(
|
|
290
|
+
buy_max_floor_percent: z.number().default(95),
|
|
237
291
|
sell_min_floor_percent: z.number().default(105),
|
|
238
292
|
poll_interval_ms: z.number().default(5e3),
|
|
239
293
|
max_verification_retries: z.number().default(12),
|
|
@@ -327,13 +381,14 @@ function findPackageRoot() {
|
|
|
327
381
|
}
|
|
328
382
|
var TEMPLATES_DIR = join2(findPackageRoot(), "src", "templates");
|
|
329
383
|
async function ensureWorkspace(config) {
|
|
384
|
+
const silent = config?.silent ?? false;
|
|
330
385
|
if (!existsSync2(TELETON_ROOT)) {
|
|
331
386
|
mkdirSync2(TELETON_ROOT, { recursive: true });
|
|
332
|
-
log2.info(`Created Teleton root at ${TELETON_ROOT}`);
|
|
387
|
+
if (!silent) log2.info(`Created Teleton root at ${TELETON_ROOT}`);
|
|
333
388
|
}
|
|
334
389
|
if (!existsSync2(WORKSPACE_ROOT)) {
|
|
335
390
|
mkdirSync2(WORKSPACE_ROOT, { recursive: true });
|
|
336
|
-
log2.info(`Created workspace at ${WORKSPACE_ROOT}`);
|
|
391
|
+
if (!silent) log2.info(`Created workspace at ${WORKSPACE_ROOT}`);
|
|
337
392
|
}
|
|
338
393
|
const directories = [
|
|
339
394
|
WORKSPACE_PATHS.MEMORY_DIR,
|
|
@@ -369,11 +424,11 @@ async function ensureWorkspace(config) {
|
|
|
369
424
|
walletPath: join2(TELETON_ROOT, "wallet.json")
|
|
370
425
|
};
|
|
371
426
|
if (config?.ensureTemplates) {
|
|
372
|
-
await bootstrapTemplates(workspace);
|
|
427
|
+
await bootstrapTemplates(workspace, silent);
|
|
373
428
|
}
|
|
374
429
|
return workspace;
|
|
375
430
|
}
|
|
376
|
-
async function bootstrapTemplates(workspace) {
|
|
431
|
+
async function bootstrapTemplates(workspace, silent = false) {
|
|
377
432
|
const templates = [
|
|
378
433
|
{ name: "SOUL.md", path: workspace.soulPath },
|
|
379
434
|
{ name: "MEMORY.md", path: workspace.memoryPath },
|
|
@@ -387,7 +442,7 @@ async function bootstrapTemplates(workspace) {
|
|
|
387
442
|
const templateSource = join2(TEMPLATES_DIR, template.name);
|
|
388
443
|
if (existsSync2(templateSource)) {
|
|
389
444
|
copyFileSync(templateSource, template.path);
|
|
390
|
-
log2.info(`Created ${template.name}`);
|
|
445
|
+
if (!silent) log2.info(`Created ${template.name}`);
|
|
391
446
|
}
|
|
392
447
|
}
|
|
393
448
|
}
|
|
@@ -409,12 +464,15 @@ export {
|
|
|
409
464
|
ensureWorkspace,
|
|
410
465
|
isNewWorkspace,
|
|
411
466
|
loadTemplate,
|
|
467
|
+
getCachedHttpEndpoint,
|
|
412
468
|
generateWallet,
|
|
413
469
|
saveWallet,
|
|
414
470
|
loadWallet,
|
|
415
471
|
walletExists,
|
|
416
472
|
importWallet,
|
|
417
473
|
getWalletAddress,
|
|
474
|
+
getCachedTonClient,
|
|
475
|
+
invalidateTonClientCache,
|
|
418
476
|
getKeyPair,
|
|
419
477
|
getWalletBalance,
|
|
420
478
|
getTonPrice
|
|
@@ -91,14 +91,22 @@ var AnthropicEmbeddingProvider = class {
|
|
|
91
91
|
// src/memory/embeddings/local.ts
|
|
92
92
|
import { pipeline, env } from "@huggingface/transformers";
|
|
93
93
|
import { join } from "path";
|
|
94
|
+
import { mkdirSync } from "fs";
|
|
94
95
|
var log = createLogger("Memory");
|
|
95
|
-
|
|
96
|
+
var modelCacheDir = join(TELETON_ROOT, "models");
|
|
97
|
+
try {
|
|
98
|
+
mkdirSync(modelCacheDir, { recursive: true });
|
|
99
|
+
} catch {
|
|
100
|
+
}
|
|
101
|
+
env.cacheDir = modelCacheDir;
|
|
96
102
|
var extractorPromise = null;
|
|
97
103
|
function getExtractor(model) {
|
|
98
104
|
if (!extractorPromise) {
|
|
99
|
-
log.info(`Loading local embedding model: ${model} (cache: ${
|
|
105
|
+
log.info(`Loading local embedding model: ${model} (cache: ${modelCacheDir})`);
|
|
100
106
|
extractorPromise = pipeline("feature-extraction", model, {
|
|
101
|
-
dtype: "fp32"
|
|
107
|
+
dtype: "fp32",
|
|
108
|
+
// Explicit cache_dir to avoid any env race condition
|
|
109
|
+
cache_dir: modelCacheDir
|
|
102
110
|
}).then((ext) => {
|
|
103
111
|
log.info(`Local embedding model ready`);
|
|
104
112
|
return ext;
|
|
@@ -121,21 +129,29 @@ var LocalEmbeddingProvider = class {
|
|
|
121
129
|
}
|
|
122
130
|
/**
|
|
123
131
|
* Pre-download and load the model at startup.
|
|
124
|
-
* If loading fails, marks
|
|
132
|
+
* If loading fails, retries once then marks provider as disabled (FTS5-only).
|
|
125
133
|
* Call this once during app init — avoids retry spam on every message.
|
|
126
134
|
* @returns true if model loaded successfully, false if fallback to noop
|
|
127
135
|
*/
|
|
128
136
|
async warmup() {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
137
|
+
for (let attempt = 1; attempt <= 2; attempt++) {
|
|
138
|
+
try {
|
|
139
|
+
await getExtractor(this.model);
|
|
140
|
+
return true;
|
|
141
|
+
} catch (err) {
|
|
142
|
+
if (attempt === 1) {
|
|
143
|
+
log.warn(`Embedding model load failed (attempt 1), retrying...`);
|
|
144
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
145
|
+
} else {
|
|
146
|
+
log.warn(
|
|
147
|
+
`Local embedding model unavailable \u2014 falling back to FTS5-only search (no vector embeddings)`
|
|
148
|
+
);
|
|
149
|
+
this._disabled = true;
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
138
153
|
}
|
|
154
|
+
return false;
|
|
139
155
|
}
|
|
140
156
|
async embedQuery(text) {
|
|
141
157
|
if (this._disabled) return [];
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createLogger
|
|
3
|
+
} from "./chunk-RCMD3U65.js";
|
|
4
|
+
|
|
5
|
+
// src/providers/claude-code-credentials.ts
|
|
6
|
+
import { readFileSync, existsSync } from "fs";
|
|
7
|
+
import { execSync } from "child_process";
|
|
8
|
+
import { homedir } from "os";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
var log = createLogger("ClaudeCodeCreds");
|
|
11
|
+
var cachedToken = null;
|
|
12
|
+
var cachedExpiresAt = 0;
|
|
13
|
+
function getClaudeConfigDir() {
|
|
14
|
+
return process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
|
|
15
|
+
}
|
|
16
|
+
function getCredentialsFilePath() {
|
|
17
|
+
return join(getClaudeConfigDir(), ".credentials.json");
|
|
18
|
+
}
|
|
19
|
+
function readCredentialsFile() {
|
|
20
|
+
const filePath = getCredentialsFilePath();
|
|
21
|
+
if (!existsSync(filePath)) return null;
|
|
22
|
+
try {
|
|
23
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
24
|
+
return JSON.parse(raw);
|
|
25
|
+
} catch (e) {
|
|
26
|
+
log.warn({ err: e, path: filePath }, "Failed to parse Claude Code credentials file");
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function readKeychainCredentials() {
|
|
31
|
+
const serviceNames = ["Claude Code-credentials", "Claude Code"];
|
|
32
|
+
for (const service of serviceNames) {
|
|
33
|
+
try {
|
|
34
|
+
const raw = execSync(`security find-generic-password -s "${service}" -w`, {
|
|
35
|
+
encoding: "utf-8",
|
|
36
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
37
|
+
}).trim();
|
|
38
|
+
return JSON.parse(raw);
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
function readCredentials() {
|
|
45
|
+
if (process.platform === "darwin") {
|
|
46
|
+
const keychainCreds = readKeychainCredentials();
|
|
47
|
+
if (keychainCreds) return keychainCreds;
|
|
48
|
+
log.debug("Keychain read failed, falling back to credentials file");
|
|
49
|
+
}
|
|
50
|
+
return readCredentialsFile();
|
|
51
|
+
}
|
|
52
|
+
function extractToken(creds) {
|
|
53
|
+
const oauth = creds.claudeAiOauth;
|
|
54
|
+
if (!oauth?.accessToken) {
|
|
55
|
+
log.warn("Claude Code credentials found but missing accessToken");
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
token: oauth.accessToken,
|
|
60
|
+
expiresAt: oauth.expiresAt ?? 0
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function getClaudeCodeApiKey(fallbackKey) {
|
|
64
|
+
if (cachedToken && Date.now() < cachedExpiresAt) {
|
|
65
|
+
return cachedToken;
|
|
66
|
+
}
|
|
67
|
+
const creds = readCredentials();
|
|
68
|
+
if (creds) {
|
|
69
|
+
const extracted = extractToken(creds);
|
|
70
|
+
if (extracted) {
|
|
71
|
+
cachedToken = extracted.token;
|
|
72
|
+
cachedExpiresAt = extracted.expiresAt;
|
|
73
|
+
log.debug("Claude Code credentials loaded successfully");
|
|
74
|
+
return cachedToken;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (fallbackKey && fallbackKey.length > 0) {
|
|
78
|
+
log.warn("Claude Code credentials not found, using fallback api_key from config");
|
|
79
|
+
return fallbackKey;
|
|
80
|
+
}
|
|
81
|
+
throw new Error("No Claude Code credentials found. Run 'claude login' or set api_key in config.");
|
|
82
|
+
}
|
|
83
|
+
function refreshClaudeCodeApiKey() {
|
|
84
|
+
cachedToken = null;
|
|
85
|
+
cachedExpiresAt = 0;
|
|
86
|
+
const creds = readCredentials();
|
|
87
|
+
if (creds) {
|
|
88
|
+
const extracted = extractToken(creds);
|
|
89
|
+
if (extracted) {
|
|
90
|
+
cachedToken = extracted.token;
|
|
91
|
+
cachedExpiresAt = extracted.expiresAt;
|
|
92
|
+
log.info("Claude Code credentials refreshed from disk");
|
|
93
|
+
return cachedToken;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
log.warn("Failed to refresh Claude Code credentials from disk");
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
function isClaudeCodeTokenValid() {
|
|
100
|
+
return cachedToken !== null && Date.now() < cachedExpiresAt;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export {
|
|
104
|
+
getClaudeCodeApiKey,
|
|
105
|
+
refreshClaudeCodeApiKey,
|
|
106
|
+
isClaudeCodeTokenValid
|
|
107
|
+
};
|