talon-agent 3.21.0 → 3.22.1
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/package.json +2 -2
- package/src/app.ts +15 -5
- package/src/backend/claude-sdk/handler.ts +20 -11
- package/src/backend/remote-server/mcp.ts +15 -2
- package/src/backend/shared/cache-telemetry.ts +42 -0
- package/src/backend/shared/index.ts +3 -2
- package/src/core/engine/dispatcher.ts +10 -0
- package/src/core/errors.ts +11 -0
- package/src/core/mcp-hub/children.ts +45 -1
- package/src/core/tasks/table.ts +14 -0
- package/src/core/tools/index.ts +2 -0
- package/src/core/tools/messaging.ts +154 -8
- package/src/core/tools/moderation.ts +131 -0
- package/src/core/tools/types.ts +1 -0
- package/src/frontend/discord/handlers/queue.ts +22 -2
- package/src/frontend/telegram/actions/index.ts +2 -0
- package/src/frontend/telegram/actions/media.ts +143 -31
- package/src/frontend/telegram/actions/messaging.ts +78 -13
- package/src/frontend/telegram/actions/moderation.ts +255 -0
- package/src/frontend/telegram/actions/shared.ts +64 -6
- package/src/frontend/telegram/handlers/delivery.ts +9 -4
- package/src/frontend/telegram/handlers/queue.ts +23 -3
- package/src/frontend/telegram/index.ts +16 -8
- package/src/frontend/telegram/join-requests.ts +53 -0
- package/src/frontend/telegram/middleware.ts +25 -0
- package/src/frontend/telegram/topics.ts +63 -0
- package/src/frontend/telegram/userbot.ts +11 -0
- package/src/util/watchdog.ts +12 -0
|
@@ -129,10 +129,17 @@ export async function disconnectUserClient(): Promise<void> {
|
|
|
129
129
|
const CHECK_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes
|
|
130
130
|
|
|
131
131
|
let reconnecting = false;
|
|
132
|
+
// Bumped by stopConnectionMonitor so a tick whose awaits straddle a shutdown
|
|
133
|
+
// can tell that its own client was torn down under it — the liveness probe
|
|
134
|
+
// rejecting because *we* disconnected must not trigger a reconnect, or
|
|
135
|
+
// shutdown resurrects the client it just closed.
|
|
136
|
+
let monitorGeneration = 0;
|
|
132
137
|
|
|
133
138
|
function startConnectionMonitor(): void {
|
|
134
139
|
if (reconnectTimer) return;
|
|
140
|
+
const gen = monitorGeneration;
|
|
135
141
|
reconnectTimer = setInterval(async () => {
|
|
142
|
+
if (gen !== monitorGeneration) return;
|
|
136
143
|
if (!client) return;
|
|
137
144
|
if (reconnecting) return; // prevent overlapping reconnect attempts
|
|
138
145
|
|
|
@@ -146,10 +153,12 @@ function startConnectionMonitor(): void {
|
|
|
146
153
|
await client.getMe();
|
|
147
154
|
return; // genuinely alive
|
|
148
155
|
} catch {
|
|
156
|
+
if (gen !== monitorGeneration) return; // monitor stopped mid-probe
|
|
149
157
|
logWarn("userbot", "Liveness check failed — treating socket as dead.");
|
|
150
158
|
}
|
|
151
159
|
}
|
|
152
160
|
|
|
161
|
+
if (!client) return; // torn down while the probe was in flight
|
|
153
162
|
reconnecting = true;
|
|
154
163
|
logWarn("userbot", "Connection lost, attempting reconnect...");
|
|
155
164
|
try {
|
|
@@ -160,6 +169,7 @@ function startConnectionMonitor(): void {
|
|
|
160
169
|
logWarn("userbot", "Reconnected but not authorized.");
|
|
161
170
|
}
|
|
162
171
|
} catch (err) {
|
|
172
|
+
if (gen !== monitorGeneration) return; // stopped while reconnecting
|
|
163
173
|
logError("userbot", "Reconnect failed", err);
|
|
164
174
|
// Try a full re-init on next check
|
|
165
175
|
if (storedApiId && storedApiHash) {
|
|
@@ -189,6 +199,7 @@ function startConnectionMonitor(): void {
|
|
|
189
199
|
}
|
|
190
200
|
|
|
191
201
|
function stopConnectionMonitor(): void {
|
|
202
|
+
monitorGeneration++;
|
|
192
203
|
if (reconnectTimer) {
|
|
193
204
|
clearInterval(reconnectTimer);
|
|
194
205
|
reconnectTimer = null;
|
package/src/util/watchdog.ts
CHANGED
|
@@ -30,6 +30,18 @@ export function recordMessageProcessed(): void {
|
|
|
30
30
|
resetStuckWarnBackoff();
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Record that a message's turn settled in failure. The loop is moving —
|
|
35
|
+
* the error was reported and the queue slot freed — so advance the stuck
|
|
36
|
+
* clock without counting a success. Without this, one failed turn leaves
|
|
37
|
+
* `lastProcessedAt` stale forever and the watchdog reports a wedged loop
|
|
38
|
+
* (and an unhealthy bridge) on a bot that is actually idle.
|
|
39
|
+
*/
|
|
40
|
+
export function recordMessageSettled(): void {
|
|
41
|
+
lastProcessedAt = Date.now();
|
|
42
|
+
resetStuckWarnBackoff();
|
|
43
|
+
}
|
|
44
|
+
|
|
33
45
|
/**
|
|
34
46
|
* Test-only: reset the activity clocks to "just processed, nothing pending"
|
|
35
47
|
* at the CURRENT Date.now(). Fake-timer suites need this because each test
|