teleton 0.7.4 → 0.8.0
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 +43 -30
- package/dist/chunk-3RG5ZIWI.js +10 -0
- package/dist/{chunk-U7FQYCBQ.js → chunk-7TECSLJ4.js} +2 -2
- package/dist/{chunk-LAQOUFOJ.js → chunk-H36RFKRI.js} +7583 -11185
- package/dist/{chunk-RO62LO6Z.js → chunk-IJBWWQE4.js} +4 -0
- package/dist/{chunk-BGC2IUM5.js → chunk-JHYZYFZJ.js} +69 -20
- package/dist/{chunk-QOQWUUA4.js → chunk-OJCLKU5Z.js} +68 -2
- package/dist/{chunk-OCLG5GKI.js → chunk-P36I6OIV.js} +2 -2
- package/dist/chunk-PHSAHTK4.js +314 -0
- package/dist/{chunk-5PLZ3KSO.js → chunk-QVBSUYVX.js} +14 -42
- package/dist/{chunk-4DU3C27M.js → chunk-R4YSJ4EY.js} +5 -1
- package/dist/chunk-RQBAMUCV.js +10281 -0
- package/dist/{chunk-XDYDA2KV.js → chunk-SD4NLLYG.js} +293 -64
- package/dist/chunk-TVRZJIZX.js +292 -0
- package/dist/{chunk-EK7M5K26.js → chunk-U56QTM46.js} +3 -3
- package/dist/{chunk-XBKSS6DM.js → chunk-VFA7QMCZ.js} +5 -3
- package/dist/{chunk-VAUJSSD3.js → chunk-XQUHC3JZ.js} +1 -1
- package/dist/cli/index.js +96 -33
- package/dist/{client-RTNALK7W.js → client-LNZTDQSA.js} +6 -7
- package/dist/{get-my-gifts-TPVUGUWT.js → get-my-gifts-OMGKOEPM.js} +1 -1
- package/dist/index.js +15 -17
- package/dist/{memory-JQZ6MTRU.js → memory-AS7WKGTW.js} +7 -8
- package/dist/{migrate-GS5ACQDA.js → migrate-POHWYEIW.js} +7 -8
- package/dist/{multipart-parser-S3YC6NRJ.js → multipart-parser-UFQLJOV2.js} +2 -2
- package/dist/{paths-TMNTEDDD.js → paths-XA2RJH4S.js} +1 -1
- package/dist/{server-TCJOBV3D.js → server-H3QA252W.js} +39 -12
- package/dist/{setup-server-YHYJLAMA.js → setup-server-QXED3D2L.js} +24 -12
- package/dist/store-GAFULOOX.js +34 -0
- package/dist/{task-dependency-resolver-WKZWJLLM.js → task-dependency-resolver-3FIKQ7Z6.js} +3 -3
- package/dist/{task-executor-PD3H4MLO.js → task-executor-RUTFG6VG.js} +2 -2
- package/dist/{tasks-QSCWSMPS.js → tasks-BEZ4QRI2.js} +1 -1
- package/dist/{tool-adapter-Y3TCEQOC.js → tool-adapter-IH5VGBOO.js} +1 -1
- package/dist/{tool-index-6HBRVXVG.js → tool-index-H3SHOJC3.js} +6 -6
- package/dist/{transcript-UDJZP6NK.js → transcript-IMNE6KU3.js} +2 -2
- package/dist/web/assets/index-BrVqauzj.css +1 -0
- package/dist/web/assets/index-DYeEkvJ6.js +72 -0
- package/dist/web/assets/{index.es-CqZHj0tz.js → index.es-DkU1GvWU.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +2 -2
- package/dist/BigInteger-DQ33LTTE.js +0 -5
- package/dist/chunk-JQDLW7IE.js +0 -107
- package/dist/chunk-QGM4M3NI.js +0 -37
- package/dist/chunk-RMLQS3X6.js +0 -161
- package/dist/chunk-TSKJCWQQ.js +0 -1263
- package/dist/chunk-UCN6TI25.js +0 -143
- package/dist/chunk-YFG2QHLA.js +0 -3585
- package/dist/web/assets/index-B6M9knfJ.css +0 -1
- package/dist/web/assets/index-DAGeQfVZ.js +0 -72
- package/scripts/patch-gramjs.sh +0 -46
- package/scripts/postinstall.mjs +0 -16
|
@@ -21,9 +21,11 @@ var DEBOUNCE_MAX_MULTIPLIER = 3;
|
|
|
21
21
|
var DEBOUNCE_MAX_BUFFER_SIZE = 20;
|
|
22
22
|
var CONTEXT_MAX_RECENT_MESSAGES = 10;
|
|
23
23
|
var CONTEXT_MAX_RELEVANT_CHUNKS = 5;
|
|
24
|
+
var FEED_MESSAGE_MAX_CHARS = 2e3;
|
|
24
25
|
var HYBRID_SEARCH_MIN_SCORE = 0.15;
|
|
25
26
|
var CONTEXT_OVERFLOW_SUMMARY_MESSAGES = 15;
|
|
26
27
|
var RATE_LIMIT_MAX_RETRIES = 3;
|
|
28
|
+
var SERVER_ERROR_MAX_RETRIES = 3;
|
|
27
29
|
var KNOWLEDGE_CHUNK_SIZE = 500;
|
|
28
30
|
var PAYMENT_TOLERANCE_RATIO = 0.99;
|
|
29
31
|
var TELEGRAM_CONNECTION_RETRIES = 5;
|
|
@@ -79,9 +81,11 @@ export {
|
|
|
79
81
|
DEBOUNCE_MAX_BUFFER_SIZE,
|
|
80
82
|
CONTEXT_MAX_RECENT_MESSAGES,
|
|
81
83
|
CONTEXT_MAX_RELEVANT_CHUNKS,
|
|
84
|
+
FEED_MESSAGE_MAX_CHARS,
|
|
82
85
|
HYBRID_SEARCH_MIN_SCORE,
|
|
83
86
|
CONTEXT_OVERFLOW_SUMMARY_MESSAGES,
|
|
84
87
|
RATE_LIMIT_MAX_RETRIES,
|
|
88
|
+
SERVER_ERROR_MAX_RETRIES,
|
|
85
89
|
KNOWLEDGE_CHUNK_SIZE,
|
|
86
90
|
PAYMENT_TOLERANCE_RATIO,
|
|
87
91
|
TELEGRAM_CONNECTION_RETRIES,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
COINGECKO_API_URL,
|
|
3
3
|
tonapiFetch
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VFA7QMCZ.js";
|
|
5
5
|
import {
|
|
6
6
|
TELEGRAM_MAX_MESSAGE_LENGTH
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-IJBWWQE4.js";
|
|
8
8
|
import {
|
|
9
9
|
fetchWithTimeout
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-XQUHC3JZ.js";
|
|
11
11
|
import {
|
|
12
12
|
TELETON_ROOT,
|
|
13
13
|
WORKSPACE_PATHS,
|
|
@@ -17,20 +17,21 @@ import {
|
|
|
17
17
|
createLogger
|
|
18
18
|
} from "./chunk-RCMD3U65.js";
|
|
19
19
|
|
|
20
|
-
// src/ton/wallet-service.ts
|
|
21
|
-
import { mnemonicNew, mnemonicToPrivateKey, mnemonicValidate } from "@ton/crypto";
|
|
22
|
-
import { WalletContractV5R1, TonClient, fromNano } from "@ton/ton";
|
|
23
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
24
|
-
import { join, dirname } from "path";
|
|
25
|
-
|
|
26
20
|
// src/ton/endpoint.ts
|
|
27
21
|
var ENDPOINT_CACHE_TTL_MS = 6e4;
|
|
28
22
|
var ORBS_HOST = "ton.access.orbs.network";
|
|
29
23
|
var ORBS_TOPOLOGY_URL = `https://${ORBS_HOST}/mngr/nodes?npm_version=2.3.3`;
|
|
30
|
-
var
|
|
24
|
+
var TONCENTER_URL = `https://toncenter.com/api/v2/jsonRPC`;
|
|
31
25
|
var _cache = null;
|
|
26
|
+
var _toncenterApiKey;
|
|
27
|
+
function setToncenterApiKey(key) {
|
|
28
|
+
_toncenterApiKey = key;
|
|
29
|
+
}
|
|
30
|
+
function getToncenterApiKey() {
|
|
31
|
+
return _toncenterApiKey;
|
|
32
|
+
}
|
|
32
33
|
async function discoverOrbsEndpoint() {
|
|
33
|
-
const res = await fetch(ORBS_TOPOLOGY_URL);
|
|
34
|
+
const res = await fetch(ORBS_TOPOLOGY_URL, { signal: AbortSignal.timeout(5e3) });
|
|
34
35
|
const nodes = await res.json();
|
|
35
36
|
const healthy = nodes.filter(
|
|
36
37
|
(n) => n.Healthy === "1" && n.Weight > 0 && n.Mngr?.health?.["v2-mainnet"]
|
|
@@ -53,10 +54,28 @@ async function getCachedHttpEndpoint() {
|
|
|
53
54
|
return _cache.url;
|
|
54
55
|
}
|
|
55
56
|
let url;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
+
}
|
|
60
79
|
}
|
|
61
80
|
_cache = { url, ts: Date.now() };
|
|
62
81
|
return url;
|
|
@@ -66,6 +85,10 @@ function invalidateEndpointCache() {
|
|
|
66
85
|
}
|
|
67
86
|
|
|
68
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";
|
|
91
|
+
import { join, dirname } from "path";
|
|
69
92
|
var log = createLogger("TON");
|
|
70
93
|
var WALLET_FILE = join(TELETON_ROOT, "wallet.json");
|
|
71
94
|
var _walletCache;
|
|
@@ -147,7 +170,8 @@ async function getCachedTonClient() {
|
|
|
147
170
|
if (_tonClientCache && _tonClientCache.endpoint === endpoint) {
|
|
148
171
|
return _tonClientCache.client;
|
|
149
172
|
}
|
|
150
|
-
const
|
|
173
|
+
const apiKey = getToncenterApiKey();
|
|
174
|
+
const client = new TonClient({ endpoint, ...apiKey && { apiKey } });
|
|
151
175
|
_tonClientCache = { client, endpoint };
|
|
152
176
|
return client;
|
|
153
177
|
}
|
|
@@ -217,8 +241,8 @@ async function getTonPrice() {
|
|
|
217
241
|
|
|
218
242
|
// src/config/schema.ts
|
|
219
243
|
import { z } from "zod";
|
|
220
|
-
var DMPolicy = z.enum(["allowlist", "open", "disabled"]);
|
|
221
|
-
var GroupPolicy = z.enum(["open", "allowlist", "disabled"]);
|
|
244
|
+
var DMPolicy = z.enum(["allowlist", "open", "admin-only", "disabled"]);
|
|
245
|
+
var GroupPolicy = z.enum(["open", "allowlist", "admin-only", "disabled"]);
|
|
222
246
|
var SessionResetPolicySchema = z.object({
|
|
223
247
|
daily_reset_enabled: z.boolean().default(true).describe("Enable daily session reset"),
|
|
224
248
|
daily_reset_hour: z.number().min(0).max(23).default(4).describe("Hour of day (0-23) to reset sessions"),
|
|
@@ -236,6 +260,10 @@ var AgentConfigSchema = z.object({
|
|
|
236
260
|
"openrouter",
|
|
237
261
|
"moonshot",
|
|
238
262
|
"mistral",
|
|
263
|
+
"cerebras",
|
|
264
|
+
"zai",
|
|
265
|
+
"minimax",
|
|
266
|
+
"huggingface",
|
|
239
267
|
"cocoon",
|
|
240
268
|
"local"
|
|
241
269
|
]).default("anthropic"),
|
|
@@ -332,7 +360,7 @@ var _McpObject = z.object({
|
|
|
332
360
|
});
|
|
333
361
|
var McpConfigSchema = _McpObject.default(_McpObject.parse({}));
|
|
334
362
|
var _ToolRagObject = z.object({
|
|
335
|
-
enabled: z.boolean().default(
|
|
363
|
+
enabled: z.boolean().default(true).describe("Enable semantic tool retrieval (Tool RAG)"),
|
|
336
364
|
top_k: z.number().default(25).describe("Max tools to retrieve per LLM call"),
|
|
337
365
|
always_include: z.array(z.string()).default([
|
|
338
366
|
"telegram_send_message",
|
|
@@ -346,6 +374,24 @@ var _ToolRagObject = z.object({
|
|
|
346
374
|
skip_unlimited_providers: z.boolean().default(false).describe("Skip Tool RAG for providers with no tool limit (e.g. Anthropic)")
|
|
347
375
|
});
|
|
348
376
|
var ToolRagConfigSchema = _ToolRagObject.default(_ToolRagObject.parse({}));
|
|
377
|
+
var _ExecLimitsObject = z.object({
|
|
378
|
+
timeout: z.number().min(1).max(3600).default(120).describe("Max seconds per command execution"),
|
|
379
|
+
max_output: z.number().min(1e3).max(5e5).default(5e4).describe("Max chars of stdout/stderr captured per command")
|
|
380
|
+
});
|
|
381
|
+
var _ExecAuditObject = z.object({
|
|
382
|
+
log_commands: z.boolean().default(true).describe("Log every command to SQLite audit table")
|
|
383
|
+
});
|
|
384
|
+
var _ExecObject = z.object({
|
|
385
|
+
mode: z.enum(["off", "yolo"]).default("off").describe("Exec mode: off (disabled) or yolo (full system access)"),
|
|
386
|
+
scope: z.enum(["admin-only", "allowlist", "all"]).default("admin-only").describe("Who can trigger exec tools"),
|
|
387
|
+
allowlist: z.array(z.number()).default([]).describe("Telegram user IDs allowed to use exec (when scope = allowlist)"),
|
|
388
|
+
limits: _ExecLimitsObject.default(_ExecLimitsObject.parse({})),
|
|
389
|
+
audit: _ExecAuditObject.default(_ExecAuditObject.parse({}))
|
|
390
|
+
});
|
|
391
|
+
var _CapabilitiesObject = z.object({
|
|
392
|
+
exec: _ExecObject.default(_ExecObject.parse({}))
|
|
393
|
+
});
|
|
394
|
+
var CapabilitiesConfigSchema = _CapabilitiesObject.default(_CapabilitiesObject.parse({}));
|
|
349
395
|
var ConfigSchema = z.object({
|
|
350
396
|
meta: MetaConfigSchema.default(MetaConfigSchema.parse({})),
|
|
351
397
|
agent: AgentConfigSchema,
|
|
@@ -357,12 +403,14 @@ var ConfigSchema = z.object({
|
|
|
357
403
|
logging: LoggingConfigSchema,
|
|
358
404
|
dev: DevConfigSchema,
|
|
359
405
|
tool_rag: ToolRagConfigSchema,
|
|
406
|
+
capabilities: CapabilitiesConfigSchema,
|
|
360
407
|
mcp: McpConfigSchema,
|
|
361
408
|
plugins: z.record(z.string(), z.unknown()).default({}).describe("Per-plugin config (key = plugin name with underscores)"),
|
|
362
409
|
cocoon: z.object({
|
|
363
410
|
port: z.number().min(1).max(65535).default(1e4).describe("HTTP port of the cocoon-cli proxy")
|
|
364
411
|
}).optional().describe("Cocoon Network \u2014 expects external cocoon-cli running on this port"),
|
|
365
412
|
tonapi_key: z.string().optional().describe("TonAPI key for higher rate limits (from @tonapi_bot)"),
|
|
413
|
+
toncenter_api_key: z.string().optional().describe("TonCenter API key for dedicated RPC endpoint (free at https://toncenter.com)"),
|
|
366
414
|
tavily_api_key: z.string().optional().describe("Tavily API key for web search & extract (free at https://tavily.com)")
|
|
367
415
|
});
|
|
368
416
|
|
|
@@ -464,7 +512,8 @@ export {
|
|
|
464
512
|
ensureWorkspace,
|
|
465
513
|
isNewWorkspace,
|
|
466
514
|
loadTemplate,
|
|
467
|
-
|
|
515
|
+
setToncenterApiKey,
|
|
516
|
+
invalidateEndpointCache,
|
|
468
517
|
generateWallet,
|
|
469
518
|
saveWallet,
|
|
470
519
|
loadWallet,
|
|
@@ -118,11 +118,11 @@ var MODEL_OPTIONS = {
|
|
|
118
118
|
{ value: "x-ai/grok-4", name: "Grok 4", description: "256K ctx, $3/M" }
|
|
119
119
|
],
|
|
120
120
|
moonshot: [
|
|
121
|
-
{ value: "
|
|
121
|
+
{ value: "k2p5", name: "Kimi K2.5", description: "Free, 262K ctx, multimodal" },
|
|
122
122
|
{
|
|
123
123
|
value: "kimi-k2-thinking",
|
|
124
124
|
name: "Kimi K2 Thinking",
|
|
125
|
-
description: "Free,
|
|
125
|
+
description: "Free, 262K ctx, reasoning"
|
|
126
126
|
}
|
|
127
127
|
],
|
|
128
128
|
mistral: [
|
|
@@ -146,6 +146,72 @@ var MODEL_OPTIONS = {
|
|
|
146
146
|
name: "Magistral Small",
|
|
147
147
|
description: "Reasoning, 128K ctx, $0.50/M"
|
|
148
148
|
}
|
|
149
|
+
],
|
|
150
|
+
cerebras: [
|
|
151
|
+
{
|
|
152
|
+
value: "qwen-3-235b-a22b-instruct-2507",
|
|
153
|
+
name: "Qwen 3 235B",
|
|
154
|
+
description: "131K ctx, $0.60/$1.20"
|
|
155
|
+
},
|
|
156
|
+
{ value: "gpt-oss-120b", name: "GPT OSS 120B", description: "Reasoning, 131K ctx, $0.25/M" },
|
|
157
|
+
{ value: "zai-glm-4.7", name: "ZAI GLM-4.7", description: "131K ctx, $2.25/M" },
|
|
158
|
+
{ value: "llama3.1-8b", name: "Llama 3.1 8B", description: "Fast & cheap, 32K ctx, $0.10/M" }
|
|
159
|
+
],
|
|
160
|
+
zai: [
|
|
161
|
+
{ value: "glm-4.7", name: "GLM-4.7", description: "204K ctx, $0.60/$2.20" },
|
|
162
|
+
{ value: "glm-5", name: "GLM-5", description: "Best quality, 204K ctx, $1.00/$3.20" },
|
|
163
|
+
{ value: "glm-4.6", name: "GLM-4.6", description: "204K ctx, $0.60/$2.20" },
|
|
164
|
+
{ value: "glm-4.7-flash", name: "GLM-4.7 Flash", description: "FREE, 200K ctx" },
|
|
165
|
+
{ value: "glm-4.5-flash", name: "GLM-4.5 Flash", description: "FREE, 131K ctx" },
|
|
166
|
+
{ value: "glm-4.5v", name: "GLM-4.5V", description: "Vision, 64K ctx, $0.60/$1.80" }
|
|
167
|
+
],
|
|
168
|
+
minimax: [
|
|
169
|
+
{ value: "MiniMax-M2.5", name: "MiniMax M2.5", description: "204K ctx, $0.30/$1.20" },
|
|
170
|
+
{
|
|
171
|
+
value: "MiniMax-M2.5-highspeed",
|
|
172
|
+
name: "MiniMax M2.5 Fast",
|
|
173
|
+
description: "204K ctx, $0.60/$2.40"
|
|
174
|
+
},
|
|
175
|
+
{ value: "MiniMax-M2.1", name: "MiniMax M2.1", description: "204K ctx, $0.30/$1.20" },
|
|
176
|
+
{ value: "MiniMax-M2", name: "MiniMax M2", description: "196K ctx, $0.30/$1.20" }
|
|
177
|
+
],
|
|
178
|
+
huggingface: [
|
|
179
|
+
{
|
|
180
|
+
value: "deepseek-ai/DeepSeek-V3.2",
|
|
181
|
+
name: "DeepSeek V3.2",
|
|
182
|
+
description: "163K ctx, $0.28/$0.40"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
value: "deepseek-ai/DeepSeek-R1-0528",
|
|
186
|
+
name: "DeepSeek R1",
|
|
187
|
+
description: "Reasoning, 163K ctx, $3/$5"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
value: "Qwen/Qwen3-235B-A22B-Thinking-2507",
|
|
191
|
+
name: "Qwen3 235B",
|
|
192
|
+
description: "Reasoning, 262K ctx, $0.30/$3"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
value: "Qwen/Qwen3-Coder-480B-A35B-Instruct",
|
|
196
|
+
name: "Qwen3 Coder 480B",
|
|
197
|
+
description: "Coding, 262K ctx, $2/$2"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
value: "Qwen/Qwen3-Next-80B-A3B-Instruct",
|
|
201
|
+
name: "Qwen3 Next 80B",
|
|
202
|
+
description: "262K ctx, $0.25/$1"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
value: "moonshotai/Kimi-K2.5",
|
|
206
|
+
name: "Kimi K2.5",
|
|
207
|
+
description: "262K ctx, $0.60/$3"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
value: "zai-org/GLM-4.7-Flash",
|
|
211
|
+
name: "GLM-4.7 Flash",
|
|
212
|
+
description: "FREE, 200K ctx"
|
|
213
|
+
},
|
|
214
|
+
{ value: "zai-org/GLM-5", name: "GLM-5", description: "202K ctx, $1/$3.20" }
|
|
149
215
|
]
|
|
150
216
|
};
|
|
151
217
|
function getModelsForProvider(provider) {
|
|
@@ -24,7 +24,7 @@ function getTranscriptPath(sessionId) {
|
|
|
24
24
|
}
|
|
25
25
|
function ensureSessionsDir() {
|
|
26
26
|
if (!existsSync(SESSIONS_DIR)) {
|
|
27
|
-
mkdirSync(SESSIONS_DIR, { recursive: true });
|
|
27
|
+
mkdirSync(SESSIONS_DIR, { recursive: true, mode: 448 });
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
function appendToTranscript(sessionId, message) {
|
|
@@ -32,7 +32,7 @@ function appendToTranscript(sessionId, message) {
|
|
|
32
32
|
const transcriptPath = getTranscriptPath(sessionId);
|
|
33
33
|
const line = JSON.stringify(message) + "\n";
|
|
34
34
|
try {
|
|
35
|
-
appendFileSync(transcriptPath, line, "utf-8");
|
|
35
|
+
appendFileSync(transcriptPath, line, { encoding: "utf-8", mode: 384 });
|
|
36
36
|
} catch (error) {
|
|
37
37
|
log.error({ err: error }, `Failed to append to transcript ${sessionId}`);
|
|
38
38
|
}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createLogger
|
|
3
|
+
} from "./chunk-RCMD3U65.js";
|
|
4
|
+
|
|
5
|
+
// src/config/providers.ts
|
|
6
|
+
var PROVIDER_REGISTRY = {
|
|
7
|
+
anthropic: {
|
|
8
|
+
id: "anthropic",
|
|
9
|
+
displayName: "Anthropic (Claude)",
|
|
10
|
+
envVar: "ANTHROPIC_API_KEY",
|
|
11
|
+
keyPrefix: "sk-ant-",
|
|
12
|
+
keyHint: "sk-ant-api03-...",
|
|
13
|
+
consoleUrl: "https://console.anthropic.com/",
|
|
14
|
+
defaultModel: "claude-opus-4-6",
|
|
15
|
+
utilityModel: "claude-haiku-4-5-20251001",
|
|
16
|
+
toolLimit: null,
|
|
17
|
+
piAiProvider: "anthropic"
|
|
18
|
+
},
|
|
19
|
+
"claude-code": {
|
|
20
|
+
id: "claude-code",
|
|
21
|
+
displayName: "Claude Code (Auto)",
|
|
22
|
+
envVar: "ANTHROPIC_API_KEY",
|
|
23
|
+
keyPrefix: "sk-ant-",
|
|
24
|
+
keyHint: "Auto-detected from Claude Code",
|
|
25
|
+
consoleUrl: "https://console.anthropic.com/",
|
|
26
|
+
defaultModel: "claude-opus-4-6",
|
|
27
|
+
utilityModel: "claude-haiku-4-5-20251001",
|
|
28
|
+
toolLimit: null,
|
|
29
|
+
piAiProvider: "anthropic"
|
|
30
|
+
},
|
|
31
|
+
openai: {
|
|
32
|
+
id: "openai",
|
|
33
|
+
displayName: "OpenAI (GPT-4o)",
|
|
34
|
+
envVar: "OPENAI_API_KEY",
|
|
35
|
+
keyPrefix: "sk-",
|
|
36
|
+
keyHint: "sk-proj-...",
|
|
37
|
+
consoleUrl: "https://platform.openai.com/api-keys",
|
|
38
|
+
defaultModel: "gpt-4o",
|
|
39
|
+
utilityModel: "gpt-4o-mini",
|
|
40
|
+
toolLimit: 128,
|
|
41
|
+
piAiProvider: "openai"
|
|
42
|
+
},
|
|
43
|
+
google: {
|
|
44
|
+
id: "google",
|
|
45
|
+
displayName: "Google (Gemini)",
|
|
46
|
+
envVar: "GOOGLE_API_KEY",
|
|
47
|
+
keyPrefix: null,
|
|
48
|
+
keyHint: "AIza...",
|
|
49
|
+
consoleUrl: "https://aistudio.google.com/apikey",
|
|
50
|
+
defaultModel: "gemini-2.5-flash",
|
|
51
|
+
utilityModel: "gemini-2.0-flash-lite",
|
|
52
|
+
toolLimit: 128,
|
|
53
|
+
piAiProvider: "google"
|
|
54
|
+
},
|
|
55
|
+
xai: {
|
|
56
|
+
id: "xai",
|
|
57
|
+
displayName: "xAI (Grok)",
|
|
58
|
+
envVar: "XAI_API_KEY",
|
|
59
|
+
keyPrefix: "xai-",
|
|
60
|
+
keyHint: "xai-...",
|
|
61
|
+
consoleUrl: "https://console.x.ai/",
|
|
62
|
+
defaultModel: "grok-3",
|
|
63
|
+
utilityModel: "grok-3-mini-fast",
|
|
64
|
+
toolLimit: 128,
|
|
65
|
+
piAiProvider: "xai"
|
|
66
|
+
},
|
|
67
|
+
groq: {
|
|
68
|
+
id: "groq",
|
|
69
|
+
displayName: "Groq",
|
|
70
|
+
envVar: "GROQ_API_KEY",
|
|
71
|
+
keyPrefix: "gsk_",
|
|
72
|
+
keyHint: "gsk_...",
|
|
73
|
+
consoleUrl: "https://console.groq.com/keys",
|
|
74
|
+
defaultModel: "llama-3.3-70b-versatile",
|
|
75
|
+
utilityModel: "llama-3.1-8b-instant",
|
|
76
|
+
toolLimit: 128,
|
|
77
|
+
piAiProvider: "groq"
|
|
78
|
+
},
|
|
79
|
+
openrouter: {
|
|
80
|
+
id: "openrouter",
|
|
81
|
+
displayName: "OpenRouter",
|
|
82
|
+
envVar: "OPENROUTER_API_KEY",
|
|
83
|
+
keyPrefix: "sk-or-",
|
|
84
|
+
keyHint: "sk-or-v1-...",
|
|
85
|
+
consoleUrl: "https://openrouter.ai/keys",
|
|
86
|
+
defaultModel: "anthropic/claude-opus-4.5",
|
|
87
|
+
utilityModel: "google/gemini-2.5-flash-lite",
|
|
88
|
+
toolLimit: 128,
|
|
89
|
+
piAiProvider: "openrouter"
|
|
90
|
+
},
|
|
91
|
+
moonshot: {
|
|
92
|
+
id: "moonshot",
|
|
93
|
+
displayName: "Moonshot (Kimi K2.5)",
|
|
94
|
+
envVar: "MOONSHOT_API_KEY",
|
|
95
|
+
keyPrefix: "sk-",
|
|
96
|
+
keyHint: "sk-...",
|
|
97
|
+
consoleUrl: "https://platform.moonshot.ai/",
|
|
98
|
+
defaultModel: "k2p5",
|
|
99
|
+
utilityModel: "k2p5",
|
|
100
|
+
toolLimit: 128,
|
|
101
|
+
piAiProvider: "kimi-coding"
|
|
102
|
+
},
|
|
103
|
+
mistral: {
|
|
104
|
+
id: "mistral",
|
|
105
|
+
displayName: "Mistral AI",
|
|
106
|
+
envVar: "MISTRAL_API_KEY",
|
|
107
|
+
keyPrefix: null,
|
|
108
|
+
keyHint: "...",
|
|
109
|
+
consoleUrl: "https://console.mistral.ai/api-keys",
|
|
110
|
+
defaultModel: "devstral-small-2507",
|
|
111
|
+
utilityModel: "ministral-8b-latest",
|
|
112
|
+
toolLimit: 128,
|
|
113
|
+
piAiProvider: "mistral"
|
|
114
|
+
},
|
|
115
|
+
cerebras: {
|
|
116
|
+
id: "cerebras",
|
|
117
|
+
displayName: "Cerebras",
|
|
118
|
+
envVar: "CEREBRAS_API_KEY",
|
|
119
|
+
keyPrefix: "csk-",
|
|
120
|
+
keyHint: "csk-...",
|
|
121
|
+
consoleUrl: "https://cloud.cerebras.ai/",
|
|
122
|
+
defaultModel: "qwen-3-235b-a22b-instruct-2507",
|
|
123
|
+
utilityModel: "llama3.1-8b",
|
|
124
|
+
toolLimit: 128,
|
|
125
|
+
piAiProvider: "cerebras"
|
|
126
|
+
},
|
|
127
|
+
zai: {
|
|
128
|
+
id: "zai",
|
|
129
|
+
displayName: "ZAI (Zhipu)",
|
|
130
|
+
envVar: "ZAI_API_KEY",
|
|
131
|
+
keyPrefix: null,
|
|
132
|
+
keyHint: "...",
|
|
133
|
+
consoleUrl: "https://z.ai/manage-apikey/apikey-list",
|
|
134
|
+
defaultModel: "glm-4.7",
|
|
135
|
+
utilityModel: "glm-4.7-flash",
|
|
136
|
+
toolLimit: 128,
|
|
137
|
+
piAiProvider: "zai"
|
|
138
|
+
},
|
|
139
|
+
minimax: {
|
|
140
|
+
id: "minimax",
|
|
141
|
+
displayName: "MiniMax",
|
|
142
|
+
envVar: "MINIMAX_API_KEY",
|
|
143
|
+
keyPrefix: null,
|
|
144
|
+
keyHint: "Save your key \u2014 shown only once!",
|
|
145
|
+
consoleUrl: "https://platform.minimax.io/",
|
|
146
|
+
defaultModel: "MiniMax-M2.5",
|
|
147
|
+
utilityModel: "MiniMax-M2",
|
|
148
|
+
toolLimit: 128,
|
|
149
|
+
piAiProvider: "minimax"
|
|
150
|
+
},
|
|
151
|
+
huggingface: {
|
|
152
|
+
id: "huggingface",
|
|
153
|
+
displayName: "HuggingFace",
|
|
154
|
+
envVar: "HF_TOKEN",
|
|
155
|
+
keyPrefix: "hf_",
|
|
156
|
+
keyHint: "hf_...",
|
|
157
|
+
consoleUrl: "https://huggingface.co/settings/tokens",
|
|
158
|
+
defaultModel: "deepseek-ai/DeepSeek-V3.2",
|
|
159
|
+
utilityModel: "Qwen/Qwen3-Next-80B-A3B-Instruct",
|
|
160
|
+
toolLimit: 128,
|
|
161
|
+
piAiProvider: "huggingface"
|
|
162
|
+
},
|
|
163
|
+
cocoon: {
|
|
164
|
+
id: "cocoon",
|
|
165
|
+
displayName: "Cocoon Network (Decentralized)",
|
|
166
|
+
envVar: "",
|
|
167
|
+
keyPrefix: null,
|
|
168
|
+
keyHint: "No API key needed \u2014 pays in TON",
|
|
169
|
+
consoleUrl: "https://cocoon.network",
|
|
170
|
+
defaultModel: "Qwen/Qwen3-32B",
|
|
171
|
+
utilityModel: "Qwen/Qwen3-32B",
|
|
172
|
+
toolLimit: 128,
|
|
173
|
+
piAiProvider: "cocoon"
|
|
174
|
+
},
|
|
175
|
+
local: {
|
|
176
|
+
id: "local",
|
|
177
|
+
displayName: "Local (Ollama, vLLM, LM Studio...)",
|
|
178
|
+
envVar: "",
|
|
179
|
+
keyPrefix: null,
|
|
180
|
+
keyHint: "No API key needed",
|
|
181
|
+
consoleUrl: "",
|
|
182
|
+
defaultModel: "auto",
|
|
183
|
+
utilityModel: "auto",
|
|
184
|
+
toolLimit: 128,
|
|
185
|
+
piAiProvider: "local"
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
function getProviderMetadata(provider) {
|
|
189
|
+
const meta = PROVIDER_REGISTRY[provider];
|
|
190
|
+
if (!meta) {
|
|
191
|
+
throw new Error(`Unknown provider: ${provider}`);
|
|
192
|
+
}
|
|
193
|
+
return meta;
|
|
194
|
+
}
|
|
195
|
+
function getSupportedProviders() {
|
|
196
|
+
return Object.values(PROVIDER_REGISTRY);
|
|
197
|
+
}
|
|
198
|
+
function validateApiKeyFormat(provider, key) {
|
|
199
|
+
const meta = PROVIDER_REGISTRY[provider];
|
|
200
|
+
if (!meta) return `Unknown provider: ${provider}`;
|
|
201
|
+
if (provider === "cocoon" || provider === "local" || provider === "claude-code") return void 0;
|
|
202
|
+
if (!key || key.trim().length === 0) return "API key is required";
|
|
203
|
+
if (meta.keyPrefix && !key.startsWith(meta.keyPrefix)) {
|
|
204
|
+
return `Invalid format (should start with ${meta.keyPrefix})`;
|
|
205
|
+
}
|
|
206
|
+
return void 0;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/providers/claude-code-credentials.ts
|
|
210
|
+
import { readFileSync, existsSync } from "fs";
|
|
211
|
+
import { execSync } from "child_process";
|
|
212
|
+
import { homedir } from "os";
|
|
213
|
+
import { join } from "path";
|
|
214
|
+
var log = createLogger("ClaudeCodeCreds");
|
|
215
|
+
var cachedToken = null;
|
|
216
|
+
var cachedExpiresAt = 0;
|
|
217
|
+
function getClaudeConfigDir() {
|
|
218
|
+
return process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
|
|
219
|
+
}
|
|
220
|
+
function getCredentialsFilePath() {
|
|
221
|
+
return join(getClaudeConfigDir(), ".credentials.json");
|
|
222
|
+
}
|
|
223
|
+
function readCredentialsFile() {
|
|
224
|
+
const filePath = getCredentialsFilePath();
|
|
225
|
+
if (!existsSync(filePath)) return null;
|
|
226
|
+
try {
|
|
227
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
228
|
+
return JSON.parse(raw);
|
|
229
|
+
} catch (e) {
|
|
230
|
+
log.warn({ err: e, path: filePath }, "Failed to parse Claude Code credentials file");
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function readKeychainCredentials() {
|
|
235
|
+
const serviceNames = ["Claude Code-credentials", "Claude Code"];
|
|
236
|
+
for (const service of serviceNames) {
|
|
237
|
+
try {
|
|
238
|
+
const raw = execSync(`security find-generic-password -s "${service}" -w`, {
|
|
239
|
+
encoding: "utf-8",
|
|
240
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
241
|
+
}).trim();
|
|
242
|
+
return JSON.parse(raw);
|
|
243
|
+
} catch {
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
function readCredentials() {
|
|
249
|
+
if (process.platform === "darwin") {
|
|
250
|
+
const keychainCreds = readKeychainCredentials();
|
|
251
|
+
if (keychainCreds) return keychainCreds;
|
|
252
|
+
log.debug("Keychain read failed, falling back to credentials file");
|
|
253
|
+
}
|
|
254
|
+
return readCredentialsFile();
|
|
255
|
+
}
|
|
256
|
+
function extractToken(creds) {
|
|
257
|
+
const oauth = creds.claudeAiOauth;
|
|
258
|
+
if (!oauth?.accessToken) {
|
|
259
|
+
log.warn("Claude Code credentials found but missing accessToken");
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
token: oauth.accessToken,
|
|
264
|
+
expiresAt: oauth.expiresAt ?? 0
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function getClaudeCodeApiKey(fallbackKey) {
|
|
268
|
+
if (cachedToken && Date.now() < cachedExpiresAt) {
|
|
269
|
+
return cachedToken;
|
|
270
|
+
}
|
|
271
|
+
const creds = readCredentials();
|
|
272
|
+
if (creds) {
|
|
273
|
+
const extracted = extractToken(creds);
|
|
274
|
+
if (extracted) {
|
|
275
|
+
cachedToken = extracted.token;
|
|
276
|
+
cachedExpiresAt = extracted.expiresAt;
|
|
277
|
+
log.debug("Claude Code credentials loaded successfully");
|
|
278
|
+
return cachedToken;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (fallbackKey && fallbackKey.length > 0) {
|
|
282
|
+
log.warn("Claude Code credentials not found, using fallback api_key from config");
|
|
283
|
+
return fallbackKey;
|
|
284
|
+
}
|
|
285
|
+
throw new Error("No Claude Code credentials found. Run 'claude login' or set api_key in config.");
|
|
286
|
+
}
|
|
287
|
+
function refreshClaudeCodeApiKey() {
|
|
288
|
+
cachedToken = null;
|
|
289
|
+
cachedExpiresAt = 0;
|
|
290
|
+
const creds = readCredentials();
|
|
291
|
+
if (creds) {
|
|
292
|
+
const extracted = extractToken(creds);
|
|
293
|
+
if (extracted) {
|
|
294
|
+
cachedToken = extracted.token;
|
|
295
|
+
cachedExpiresAt = extracted.expiresAt;
|
|
296
|
+
log.info("Claude Code credentials refreshed from disk");
|
|
297
|
+
return cachedToken;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
log.warn("Failed to refresh Claude Code credentials from disk");
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
function isClaudeCodeTokenValid() {
|
|
304
|
+
return cachedToken !== null && Date.now() < cachedExpiresAt;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export {
|
|
308
|
+
getProviderMetadata,
|
|
309
|
+
getSupportedProviders,
|
|
310
|
+
validateApiKeyFormat,
|
|
311
|
+
getClaudeCodeApiKey,
|
|
312
|
+
refreshClaudeCodeApiKey,
|
|
313
|
+
isClaudeCodeTokenValid
|
|
314
|
+
};
|