@gonzih/cc-tg 0.9.42 → 0.9.44
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 +3 -0
- package/dist/bot.js +4 -0
- package/dist/index.js +18 -9
- package/dist/notifier.d.ts +13 -1
- package/dist/notifier.js +13 -1
- package/package.json +1 -1
package/dist/bot.d.ts
CHANGED
|
@@ -12,6 +12,9 @@ export interface BotOptions {
|
|
|
12
12
|
groupChatIds?: number[];
|
|
13
13
|
redis?: Redis;
|
|
14
14
|
namespace?: string;
|
|
15
|
+
/** Called when a message is routed to a non-default namespace so the notifier
|
|
16
|
+
* can forward the response back to the originating Telegram chat. */
|
|
17
|
+
registerRoutedChatId?: (namespace: string, chatId: number) => void;
|
|
15
18
|
}
|
|
16
19
|
/** Prepend [MM-DD HH:mm] so Claude knows when the message was received. Not shown in Telegram. */
|
|
17
20
|
export declare function stampPrompt(text: string, now?: Date): string;
|
package/dist/bot.js
CHANGED
|
@@ -454,6 +454,8 @@ export class CcTgBot {
|
|
|
454
454
|
// Acknowledge routing immediately so user knows the message was delegated
|
|
455
455
|
await this.replyToChat(chatId, `→ #${routing.namespace}`, threadId);
|
|
456
456
|
this.writeChatMessage("user", "telegram", text, chatId);
|
|
457
|
+
// Register the originating chatId so responses come back to this chat
|
|
458
|
+
this.opts.registerRoutedChatId?.(routing.namespace, chatId);
|
|
457
459
|
try {
|
|
458
460
|
await ensureMetaAgent(routing.namespace, routing.repoUrl, (toolName, args) => this.callCcAgentTool(toolName, args ?? {}), this.redis);
|
|
459
461
|
await routeToMetaAgent(routing.namespace, routing.strippedMessage, this.redis);
|
|
@@ -478,6 +480,8 @@ export class CcTgBot {
|
|
|
478
480
|
const repoUrl = `https://github.com/${defaultOrg}/${namespace}`;
|
|
479
481
|
await this.replyToChat(chatId, `→ #${namespace} (meta-agent)`, threadId);
|
|
480
482
|
this.writeChatMessage("user", "telegram", text, chatId);
|
|
483
|
+
// Register the originating chatId so responses come back to this chat
|
|
484
|
+
this.opts.registerRoutedChatId?.(namespace, chatId);
|
|
481
485
|
try {
|
|
482
486
|
await ensureMetaAgent(namespace, repoUrl, (toolName, args) => this.callCcAgentTool(toolName, args ?? {}), this.redis);
|
|
483
487
|
await routeToMetaAgent(namespace, text, this.redis);
|
package/dist/index.js
CHANGED
|
@@ -130,6 +130,20 @@ sharedRedis.once("ready", () => {
|
|
|
130
130
|
});
|
|
131
131
|
console.log(`[cc-tg] version:reported ${pkg.version}`);
|
|
132
132
|
});
|
|
133
|
+
// Notifier — always subscribe to cca:notify and cca:chat:incoming channels.
|
|
134
|
+
// CC_AGENT_NOTIFY_CHAT_ID pins a fixed Telegram chatId; without it the last
|
|
135
|
+
// active chatId is used dynamically for the chat bridge.
|
|
136
|
+
// Created before the bot so we can pass registerRoutedChatId into BotOptions.
|
|
137
|
+
// Callbacks are wired via closures that delegate to the bot after it is created.
|
|
138
|
+
const notifyChatId = process.env.CC_AGENT_NOTIFY_CHAT_ID
|
|
139
|
+
? Number(process.env.CC_AGENT_NOTIFY_CHAT_ID)
|
|
140
|
+
: null;
|
|
141
|
+
// Mutable placeholder closures — filled in once `bot` is created below.
|
|
142
|
+
let getLastActiveChatIdFn = () => undefined;
|
|
143
|
+
let handleUserMessageFn;
|
|
144
|
+
const notifierBot = new TelegramBot(telegramToken, { polling: false });
|
|
145
|
+
const notifier = startNotifier(notifierBot, notifyChatId, namespace, sharedRedis, (cid, text) => handleUserMessageFn?.(cid, text), () => getLastActiveChatIdFn());
|
|
146
|
+
console.log(`[notifier] started for namespace=${namespace} chatId=${notifyChatId ?? "dynamic"}`);
|
|
133
147
|
const bot = new CcTgBot({
|
|
134
148
|
telegramToken,
|
|
135
149
|
claudeToken,
|
|
@@ -138,7 +152,11 @@ const bot = new CcTgBot({
|
|
|
138
152
|
groupChatIds,
|
|
139
153
|
redis: sharedRedis,
|
|
140
154
|
namespace,
|
|
155
|
+
registerRoutedChatId: (ns, chatId) => notifier.registerRoutedChatId(ns, chatId),
|
|
141
156
|
});
|
|
157
|
+
// Wire closures now that bot is constructed
|
|
158
|
+
getLastActiveChatIdFn = () => bot.getLastActiveChatId();
|
|
159
|
+
handleUserMessageFn = (cid, text) => { void bot.handleUserMessage(cid, text); };
|
|
142
160
|
if (process.env.CC_AGENT_OPS_PORT) {
|
|
143
161
|
const botInfo = await bot.getMe();
|
|
144
162
|
const registry = new Registry(sharedRedis);
|
|
@@ -161,15 +179,6 @@ if (process.env.CC_AGENT_OPS_PORT) {
|
|
|
161
179
|
});
|
|
162
180
|
console.log(`[ops] control server on port ${process.env.CC_AGENT_OPS_PORT}`);
|
|
163
181
|
}
|
|
164
|
-
// Notifier — always subscribe to cca:notify and cca:chat:incoming channels.
|
|
165
|
-
// CC_AGENT_NOTIFY_CHAT_ID pins a fixed Telegram chatId; without it the last
|
|
166
|
-
// active chatId is used dynamically for the chat bridge.
|
|
167
|
-
const notifyChatId = process.env.CC_AGENT_NOTIFY_CHAT_ID
|
|
168
|
-
? Number(process.env.CC_AGENT_NOTIFY_CHAT_ID)
|
|
169
|
-
: null;
|
|
170
|
-
const notifierBot = new TelegramBot(telegramToken, { polling: false });
|
|
171
|
-
startNotifier(notifierBot, notifyChatId, namespace, sharedRedis, (cid, text) => bot.handleUserMessage(cid, text), () => bot.getLastActiveChatId());
|
|
172
|
-
console.log(`[notifier] started for namespace=${namespace} chatId=${notifyChatId ?? "dynamic"}`);
|
|
173
182
|
process.on("SIGINT", () => {
|
|
174
183
|
console.log("\nShutting down...");
|
|
175
184
|
bot.stop();
|
package/dist/notifier.d.ts
CHANGED
|
@@ -34,6 +34,16 @@ export declare function parseNotification(raw: string): string;
|
|
|
34
34
|
* Fire-and-forget — errors are logged but not thrown.
|
|
35
35
|
*/
|
|
36
36
|
export declare function writeChatLog(redis: Redis, namespace: string, msg: ChatMessage): void;
|
|
37
|
+
export interface NotifierHandle {
|
|
38
|
+
/**
|
|
39
|
+
* Register the originating Telegram chat ID for a routed namespace.
|
|
40
|
+
* When the meta-agent for `namespace` publishes a response, it will be
|
|
41
|
+
* forwarded to `chatId` instead of the global fixed/dynamic chatId.
|
|
42
|
+
* Call this before routing each message to ensure the response returns
|
|
43
|
+
* to the correct chat.
|
|
44
|
+
*/
|
|
45
|
+
registerRoutedChatId: (namespace: string, chatId: number) => void;
|
|
46
|
+
}
|
|
37
47
|
/**
|
|
38
48
|
* Start the notifier.
|
|
39
49
|
*
|
|
@@ -43,5 +53,7 @@ export declare function writeChatLog(redis: Redis, namespace: string, msg: ChatM
|
|
|
43
53
|
* @param redis - ioredis client in normal mode (will be duplicated for pub/sub)
|
|
44
54
|
* @param handleUserMessage - Optional callback to feed UI messages into the active Claude session
|
|
45
55
|
* @param getActiveChatId - Optional callback to resolve chatId dynamically (used when chatId is null)
|
|
56
|
+
*
|
|
57
|
+
* @returns NotifierHandle with registerRoutedChatId for per-namespace response routing
|
|
46
58
|
*/
|
|
47
|
-
export declare function startNotifier(bot: TelegramBot, chatId: number | null, namespace: string, redis: Redis, handleUserMessage?: (chatId: number, text: string) => void, getActiveChatId?: () => number | undefined):
|
|
59
|
+
export declare function startNotifier(bot: TelegramBot, chatId: number | null, namespace: string, redis: Redis, handleUserMessage?: (chatId: number, text: string) => void, getActiveChatId?: () => number | undefined): NotifierHandle;
|
package/dist/notifier.js
CHANGED
|
@@ -99,8 +99,13 @@ export function writeChatLog(redis, namespace, msg) {
|
|
|
99
99
|
* @param redis - ioredis client in normal mode (will be duplicated for pub/sub)
|
|
100
100
|
* @param handleUserMessage - Optional callback to feed UI messages into the active Claude session
|
|
101
101
|
* @param getActiveChatId - Optional callback to resolve chatId dynamically (used when chatId is null)
|
|
102
|
+
*
|
|
103
|
+
* @returns NotifierHandle with registerRoutedChatId for per-namespace response routing
|
|
102
104
|
*/
|
|
103
105
|
export function startNotifier(bot, chatId, namespace, redis, handleUserMessage, getActiveChatId) {
|
|
106
|
+
// Per-namespace chatId registry: when a message is routed to a non-default namespace,
|
|
107
|
+
// the originating Telegram chatId is registered here so responses go back to the right chat.
|
|
108
|
+
const routedChatIds = new Map();
|
|
104
109
|
const sub = redis.duplicate({
|
|
105
110
|
retryStrategy: (times) => {
|
|
106
111
|
const delay = Math.min(1000 * Math.pow(2, times - 1), 30_000);
|
|
@@ -177,7 +182,9 @@ export function startNotifier(bot, chatId, namespace, redis, handleUserMessage,
|
|
|
177
182
|
const content = parsed.content;
|
|
178
183
|
if (!content)
|
|
179
184
|
return;
|
|
180
|
-
|
|
185
|
+
// Per-namespace chatId wins (set by registerRoutedChatId when a message is routed).
|
|
186
|
+
// Falls back to the global fixed chatId or the last-active dynamic chatId.
|
|
187
|
+
const targetChatId = routedChatIds.get(ns) ?? chatId ?? getActiveChatId?.();
|
|
181
188
|
if (targetChatId == null) {
|
|
182
189
|
log("warn", `meta-agent output: no chatId for namespace=${ns}, dropping line`);
|
|
183
190
|
return;
|
|
@@ -326,4 +333,9 @@ export function startNotifier(bot, chatId, namespace, redis, handleUserMessage,
|
|
|
326
333
|
}
|
|
327
334
|
}
|
|
328
335
|
});
|
|
336
|
+
return {
|
|
337
|
+
registerRoutedChatId: (ns, cid) => {
|
|
338
|
+
routedChatIds.set(ns, cid);
|
|
339
|
+
},
|
|
340
|
+
};
|
|
329
341
|
}
|