@gonzih/cc-tg 0.8.1 → 0.9.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/dist/bot.d.ts +7 -0
- package/dist/bot.js +36 -0
- package/dist/notifier.d.ts +2 -2
- package/package.json +1 -1
package/dist/bot.d.ts
CHANGED
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
* One ClaudeProcess per chat_id — sessions are isolated per user.
|
|
4
4
|
*/
|
|
5
5
|
import TelegramBot from "node-telegram-bot-api";
|
|
6
|
+
import { Redis } from "ioredis";
|
|
6
7
|
export interface BotOptions {
|
|
7
8
|
telegramToken: string;
|
|
8
9
|
claudeToken?: string;
|
|
9
10
|
cwd?: string;
|
|
10
11
|
allowedUserIds?: number[];
|
|
11
12
|
groupChatIds?: number[];
|
|
13
|
+
redis?: Redis;
|
|
14
|
+
namespace?: string;
|
|
12
15
|
}
|
|
13
16
|
export declare class CcTgBot {
|
|
14
17
|
private bot;
|
|
@@ -18,8 +21,12 @@ export declare class CcTgBot {
|
|
|
18
21
|
private costStore;
|
|
19
22
|
private botUsername;
|
|
20
23
|
private botId;
|
|
24
|
+
private redis?;
|
|
25
|
+
private namespace;
|
|
21
26
|
constructor(opts: BotOptions);
|
|
22
27
|
private registerBotCommands;
|
|
28
|
+
/** Write a message to the Redis chat log. Fire-and-forget — no-op if Redis is not configured. */
|
|
29
|
+
private writeChatMessage;
|
|
23
30
|
/** Session key: "chatId:threadId" for topics, "chatId:main" for DMs/non-topic groups */
|
|
24
31
|
private sessionKey;
|
|
25
32
|
/**
|
package/dist/bot.js
CHANGED
|
@@ -14,6 +14,7 @@ import { transcribeVoice, isVoiceAvailable } from "./voice.js";
|
|
|
14
14
|
import { formatForTelegram, splitLongMessage } from "./formatter.js";
|
|
15
15
|
import { detectUsageLimit } from "./usage-limit.js";
|
|
16
16
|
import { getCurrentToken, rotateToken, getTokenIndex, getTokenCount } from "./tokens.js";
|
|
17
|
+
import { writeChatLog } from "./notifier.js";
|
|
17
18
|
const BOT_COMMANDS = [
|
|
18
19
|
{ command: "start", description: "Reset session and start fresh" },
|
|
19
20
|
{ command: "reset", description: "Reset Claude session" },
|
|
@@ -153,8 +154,12 @@ export class CcTgBot {
|
|
|
153
154
|
costStore;
|
|
154
155
|
botUsername = "";
|
|
155
156
|
botId = 0;
|
|
157
|
+
redis;
|
|
158
|
+
namespace;
|
|
156
159
|
constructor(opts) {
|
|
157
160
|
this.opts = opts;
|
|
161
|
+
this.redis = opts.redis;
|
|
162
|
+
this.namespace = opts.namespace ?? "default";
|
|
158
163
|
this.bot = new TelegramBot(opts.telegramToken, { polling: true });
|
|
159
164
|
this.bot.on("message", (msg) => this.handleTelegram(msg));
|
|
160
165
|
this.bot.on("polling_error", (err) => console.error("[tg]", err.message));
|
|
@@ -173,6 +178,20 @@ export class CcTgBot {
|
|
|
173
178
|
.then(() => console.log("[tg] bot commands registered"))
|
|
174
179
|
.catch((err) => console.error("[tg] setMyCommands failed:", err.message));
|
|
175
180
|
}
|
|
181
|
+
/** Write a message to the Redis chat log. Fire-and-forget — no-op if Redis is not configured. */
|
|
182
|
+
writeChatMessage(role, source, content, chatId) {
|
|
183
|
+
if (!this.redis)
|
|
184
|
+
return;
|
|
185
|
+
const msg = {
|
|
186
|
+
id: `${source}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
187
|
+
source,
|
|
188
|
+
role,
|
|
189
|
+
content,
|
|
190
|
+
timestamp: new Date().toISOString(),
|
|
191
|
+
chatId,
|
|
192
|
+
};
|
|
193
|
+
writeChatLog(this.redis, this.namespace, msg);
|
|
194
|
+
}
|
|
176
195
|
/** Session key: "chatId:threadId" for topics, "chatId:main" for DMs/non-topic groups */
|
|
177
196
|
sessionKey(chatId, threadId) {
|
|
178
197
|
return `${chatId}:${threadId ?? 'main'}`;
|
|
@@ -350,6 +369,7 @@ export class CcTgBot {
|
|
|
350
369
|
session.currentPrompt = prompt;
|
|
351
370
|
session.claude.sendPrompt(prompt);
|
|
352
371
|
this.startTyping(chatId, session);
|
|
372
|
+
this.writeChatMessage("user", "telegram", text, chatId);
|
|
353
373
|
}
|
|
354
374
|
catch (err) {
|
|
355
375
|
await this.replyToChat(chatId, `Error sending to Claude: ${err.message}`, threadId);
|
|
@@ -367,6 +387,7 @@ export class CcTgBot {
|
|
|
367
387
|
session.currentPrompt = enriched;
|
|
368
388
|
session.claude.sendPrompt(enriched);
|
|
369
389
|
this.startTyping(chatId, session);
|
|
390
|
+
this.writeChatMessage("user", "ui", text, chatId);
|
|
370
391
|
}
|
|
371
392
|
catch (err) {
|
|
372
393
|
await this.replyToChat(chatId, `Error sending to Claude: ${err.message}`);
|
|
@@ -495,6 +516,20 @@ export class CcTgBot {
|
|
|
495
516
|
console.log(logParts.join(" "));
|
|
496
517
|
// Track files written by Write/Edit tool calls
|
|
497
518
|
this.trackWrittenFiles(msg, session, sessionCwd);
|
|
519
|
+
// Publish tool call events to the chat log
|
|
520
|
+
if (msg.type === "assistant") {
|
|
521
|
+
const message = msg.payload.message;
|
|
522
|
+
const content = message?.content;
|
|
523
|
+
if (Array.isArray(content)) {
|
|
524
|
+
for (const block of content) {
|
|
525
|
+
if (block.type !== "tool_use")
|
|
526
|
+
continue;
|
|
527
|
+
const name = block.name;
|
|
528
|
+
const input = block.input;
|
|
529
|
+
this.writeChatMessage("tool", "cc-tg", `[tool] ${name}: ${JSON.stringify(input ?? {}).slice(0, 120)}`, chatId);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
498
533
|
this.handleClaudeMessage(chatId, session, msg);
|
|
499
534
|
});
|
|
500
535
|
claude.on("stderr", (data) => {
|
|
@@ -611,6 +646,7 @@ export class CcTgBot {
|
|
|
611
646
|
session.flushTimer = null;
|
|
612
647
|
if (!raw)
|
|
613
648
|
return;
|
|
649
|
+
this.writeChatMessage("assistant", "cc-tg", raw, chatId);
|
|
614
650
|
const text = session.isRetry ? `✅ Claude is back!\n\n${raw}` : raw;
|
|
615
651
|
session.isRetry = false;
|
|
616
652
|
// Format for Telegram HTML and split if needed (max 4096 chars)
|
package/dist/notifier.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ import { Redis } from "ioredis";
|
|
|
13
13
|
import TelegramBot from "node-telegram-bot-api";
|
|
14
14
|
export interface ChatMessage {
|
|
15
15
|
id: string;
|
|
16
|
-
source: "telegram" | "ui" | "claude";
|
|
17
|
-
role: "user" | "assistant";
|
|
16
|
+
source: "telegram" | "ui" | "claude" | "cc-tg";
|
|
17
|
+
role: "user" | "assistant" | "tool";
|
|
18
18
|
content: string;
|
|
19
19
|
timestamp: string;
|
|
20
20
|
chatId: number;
|