appback-remoteagent 0.14.0 → 0.14.2
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/.env.example +1 -0
- package/dist/config.js +1 -1
- package/dist/index.js +23 -16
- package/dist/services/polling-policy.js +1 -4
- package/docs/BOT_POLLING_POLICY.md +1 -0
- package/docs/RELEASING.md +54 -7
- package/package.json +1 -1
package/.env.example
CHANGED
|
@@ -7,6 +7,7 @@ TELEGRAM_EMPTY_RESPONSE_RETRIES=1
|
|
|
7
7
|
TELEGRAM_RETRYABLE_ERROR_RETRIES=2
|
|
8
8
|
TELEGRAM_RETRYABLE_ERROR_DELAY_MS=5000
|
|
9
9
|
TELEGRAM_UNTAGGED_INTENT_RETRIES=2
|
|
10
|
+
TELEGRAM_POLLING_MAX_CONCURRENCY=8
|
|
10
11
|
TELEGRAM_SCHEDULER_TICK_MS=1000
|
|
11
12
|
TELEGRAM_TIERED_POLLING_MIN_BOTS=5
|
|
12
13
|
TELEGRAM_ACTIVE_POLL_INTERVAL_MS=3000
|
package/dist/config.js
CHANGED
|
@@ -133,7 +133,7 @@ export const config = {
|
|
|
133
133
|
telegramCommandMenuEnabled: readBoolean("TELEGRAM_COMMAND_MENU_ENABLED", true),
|
|
134
134
|
telegramPollingBackoffMinMs: readTimeout("TELEGRAM_POLLING_BACKOFF_MIN_MS", 60_000),
|
|
135
135
|
telegramPollingBackoffMaxMs: readTimeout("TELEGRAM_POLLING_BACKOFF_MAX_MS", 900_000),
|
|
136
|
-
telegramPollingMaxConcurrency: readTimeout("TELEGRAM_POLLING_MAX_CONCURRENCY",
|
|
136
|
+
telegramPollingMaxConcurrency: readTimeout("TELEGRAM_POLLING_MAX_CONCURRENCY", 8),
|
|
137
137
|
telegramSchedulerTickMs: readTimeout("TELEGRAM_SCHEDULER_TICK_MS", 1000),
|
|
138
138
|
telegramTieredPollingMinBots: readTimeout("TELEGRAM_TIERED_POLLING_MIN_BOTS", 5),
|
|
139
139
|
telegramActivePollIntervalMs: readTimeout("TELEGRAM_ACTIVE_POLL_INTERVAL_MS", 3000),
|
package/dist/index.js
CHANGED
|
@@ -161,28 +161,35 @@ async function startManualPollingScheduler(bots) {
|
|
|
161
161
|
let activePolls = [...runtimeStates.values()].filter((state) => state.inFlight).length;
|
|
162
162
|
const pollingStates = await botPollingState.list();
|
|
163
163
|
const rankByBotId = computeRecentMessageRanks(botIds, pollingStates);
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
break;
|
|
167
|
-
}
|
|
164
|
+
const dueBots = pollingBots
|
|
165
|
+
.map((bot) => {
|
|
168
166
|
const botId = String(bot.botInfo.id);
|
|
169
167
|
const runtime = runtimeStates.get(botId);
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
168
|
+
const state = pollingStates[botId];
|
|
169
|
+
const nextPollAt = state?.nextPollAt ? Date.parse(state.nextPollAt) : 0;
|
|
170
|
+
return {
|
|
171
|
+
bot,
|
|
172
|
+
botId,
|
|
173
|
+
runtime,
|
|
174
|
+
state,
|
|
175
|
+
rank: rankByBotId.get(botId) ?? pollingBots.length,
|
|
176
|
+
nextPollAt: Number.isFinite(nextPollAt) ? nextPollAt : 0,
|
|
177
|
+
};
|
|
178
|
+
})
|
|
179
|
+
.filter((entry) => entry.runtime && !entry.runtime.inFlight && entry.nextPollAt <= now)
|
|
180
|
+
.sort((left, right) => left.nextPollAt - right.nextPollAt || left.rank - right.rank);
|
|
181
|
+
for (const entry of dueBots) {
|
|
182
|
+
if (activePolls >= config.telegramPollingMaxConcurrency) {
|
|
183
|
+
break;
|
|
177
184
|
}
|
|
178
|
-
runtime.inFlight = true;
|
|
185
|
+
entry.runtime.inFlight = true;
|
|
179
186
|
activePolls += 1;
|
|
180
|
-
void pollTelegramBot(bot, runtime, {
|
|
187
|
+
void pollTelegramBot(entry.bot, entry.runtime, {
|
|
181
188
|
totalBots: pollingBots.length,
|
|
182
|
-
botRank:
|
|
183
|
-
state,
|
|
189
|
+
botRank: entry.rank,
|
|
190
|
+
state: entry.state,
|
|
184
191
|
}).finally(() => {
|
|
185
|
-
runtime.inFlight = false;
|
|
192
|
+
entry.runtime.inFlight = false;
|
|
186
193
|
});
|
|
187
194
|
}
|
|
188
195
|
await sleep(config.telegramSchedulerTickMs);
|
|
@@ -2,10 +2,7 @@ export function computeRecentMessageRanks(botIds, states) {
|
|
|
2
2
|
const ranked = botIds
|
|
3
3
|
.map((botId) => ({
|
|
4
4
|
botId,
|
|
5
|
-
timestamp: parseStateTime(states[botId]?.lastMessageAt)
|
|
6
|
-
?? parseStateTime(states[botId]?.lastUpdateAt)
|
|
7
|
-
?? parseStateTime(states[botId]?.lastPollAt)
|
|
8
|
-
?? 0,
|
|
5
|
+
timestamp: parseStateTime(states[botId]?.lastMessageAt) ?? 0,
|
|
9
6
|
}))
|
|
10
7
|
.sort((left, right) => right.timestamp - left.timestamp);
|
|
11
8
|
return new Map(ranked.map((entry, index) => [entry.botId, index + 1]));
|
|
@@ -30,3 +30,4 @@ RemoteAgent no longer uses deep sleep, wake, or a special main bot for polling c
|
|
|
30
30
|
- `/bot doctor` removes bots that Telegram reports as permanently dead.
|
|
31
31
|
- `/bot remove <username|id>` removes a configured bot from the runtime.
|
|
32
32
|
- Polling state is stored by Telegram bot id, not by display order.
|
|
33
|
+
- The default polling concurrency is 8 because Telegram long polling can hold each request for up to 30 seconds. Lower values can make later bots look unresponsive when many bots are configured.
|
package/docs/RELEASING.md
CHANGED
|
@@ -28,7 +28,7 @@ A release is only considered complete when all of the following are done in orde
|
|
|
28
28
|
4. Run `npm run build`
|
|
29
29
|
5. Commit the completed work
|
|
30
30
|
6. Push `main` to `origin/main`
|
|
31
|
-
7. Publish `appback-remoteagent@<version>` to npm
|
|
31
|
+
7. Publish `appback-remoteagent@<version>` to npm from server 30's npm credentials
|
|
32
32
|
8. Install that exact npm version on server 30 and server 26
|
|
33
33
|
9. Restart `remoteagent.service` on each target if runtime code changed
|
|
34
34
|
10. Verify the relevant runtime path, logs, or Telegram behavior on each target
|
|
@@ -64,18 +64,65 @@ git status
|
|
|
64
64
|
git add -A
|
|
65
65
|
git commit -m "Release 0.12.3"
|
|
66
66
|
git push origin main
|
|
67
|
-
npm
|
|
67
|
+
npm pack
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
## npm publish procedure
|
|
71
|
+
|
|
72
|
+
Use this package-specific path for `appback-remoteagent`.
|
|
73
|
+
|
|
74
|
+
Do not publish this package from machine 21 with the `21token`. That token is scoped for `@appbackhub` packages and cannot publish the unscoped `appback-remoteagent` package. It can authenticate but `npm publish` fails with:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
403 Forbidden - You may not perform that action with these credentials.
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The successful publish path is:
|
|
71
81
|
|
|
72
82
|
```bash
|
|
73
|
-
VERSION=0.
|
|
83
|
+
VERSION=0.14.0
|
|
84
|
+
npm pack
|
|
85
|
+
scp appback-remoteagent-$VERSION.tgz au2223@192.168.0.30:/tmp/appback-remoteagent-$VERSION.tgz
|
|
86
|
+
ssh au2223@192.168.0.30 "bash -lc 'npm publish /tmp/appback-remoteagent-$VERSION.tgz'"
|
|
87
|
+
npm view appback-remoteagent version
|
|
88
|
+
ssh au2223@192.168.0.30 'bash -lc "npm view appback-remoteagent version"'
|
|
89
|
+
rm -f appback-remoteagent-$VERSION.tgz
|
|
90
|
+
ssh au2223@192.168.0.30 "rm -f /tmp/appback-remoteagent-$VERSION.tgz"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If registry caching briefly returns the previous version after publish, wait a few seconds and rerun `npm view appback-remoteagent version` before installing to servers.
|
|
94
|
+
|
|
95
|
+
## Target deployment sequence
|
|
96
|
+
|
|
97
|
+
Server 30 uses a systemd service:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
VERSION=0.14.0
|
|
101
|
+
ssh au2223@192.168.0.30 "VERSION=$VERSION bash -s" <<'REMOTE'
|
|
102
|
+
set -euo pipefail
|
|
103
|
+
sudo -n env "PATH=$PATH" npm install -g appback-remoteagent@$VERSION
|
|
104
|
+
/home/au2223/.nvm/versions/node/v22.22.0/bin/remoteagent-install
|
|
105
|
+
sudo -n systemctl restart remoteagent
|
|
106
|
+
systemctl is-active remoteagent
|
|
107
|
+
journalctl -u remoteagent --since '2 minutes ago' --no-pager
|
|
108
|
+
REMOTE
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Server 26 currently uses user-level start/stop scripts, not a systemd `remoteagent.service`:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
VERSION=0.14.0
|
|
115
|
+
ssh ospadmin@192.168.0.26 "VERSION=$VERSION bash -s" <<'REMOTE'
|
|
116
|
+
set -euo pipefail
|
|
74
117
|
npm install -g appback-remoteagent@$VERSION
|
|
75
118
|
remoteagent-install
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
119
|
+
~/.remoteagent/stop-remoteagent.sh || true
|
|
120
|
+
sleep 2
|
|
121
|
+
~/.remoteagent/start-remoteagent.sh
|
|
122
|
+
sleep 3
|
|
123
|
+
pgrep -af "appback-remoteagent/dist/index.js"
|
|
124
|
+
tail -80 ~/.remoteagent/logs/agent.log
|
|
125
|
+
REMOTE
|
|
79
126
|
```
|
|
80
127
|
|
|
81
128
|
## Other Runtime Follow-up
|