visionclaw 0.1.219-dev.codex-issue-2805-worker-runtime.3 → 0.1.219-dev.codex-2941-task-board-on-main.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/dist/agent/browser-launcher.d.ts +19 -1
- package/dist/agent/browser-launcher.d.ts.map +1 -1
- package/dist/agent/browser-launcher.js +40 -0
- package/dist/agent/browser-launcher.js.map +1 -1
- package/dist/agent/command-handlers.js +2 -2
- package/dist/agent/command-handlers.js.map +1 -1
- package/dist/agent/engines/claude/session.d.ts +6 -0
- package/dist/agent/engines/claude/session.d.ts.map +1 -1
- package/dist/agent/engines/claude/session.js +34 -2
- package/dist/agent/engines/claude/session.js.map +1 -1
- package/dist/agent/engines/pi/tools.d.ts.map +1 -1
- package/dist/agent/engines/pi/tools.js +2 -1
- package/dist/agent/engines/pi/tools.js.map +1 -1
- package/dist/agent/fund-league-hold.d.ts.map +1 -1
- package/dist/agent/fund-league-hold.js +5 -1
- package/dist/agent/fund-league-hold.js.map +1 -1
- package/dist/agent/interrupt-handler.d.ts.map +1 -1
- package/dist/agent/interrupt-handler.js +4 -1
- package/dist/agent/interrupt-handler.js.map +1 -1
- package/dist/agent/lifecycle-trace.d.ts +3 -2
- package/dist/agent/lifecycle-trace.d.ts.map +1 -1
- package/dist/agent/lifecycle-trace.js +4 -9
- package/dist/agent/lifecycle-trace.js.map +1 -1
- package/dist/agent/lifecycle-transitions.d.ts +42 -0
- package/dist/agent/lifecycle-transitions.d.ts.map +1 -1
- package/dist/agent/lifecycle-transitions.js +62 -6
- package/dist/agent/lifecycle-transitions.js.map +1 -1
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +99 -27
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/public-activity.d.ts +1 -1
- package/dist/agent/public-activity.d.ts.map +1 -1
- package/dist/agent/public-activity.js.map +1 -1
- package/dist/agent/runtime-context.d.ts +2 -0
- package/dist/agent/runtime-context.d.ts.map +1 -1
- package/dist/agent/runtime-context.js +4 -0
- package/dist/agent/runtime-context.js.map +1 -1
- package/dist/agent/service-gate.d.ts.map +1 -1
- package/dist/agent/service-gate.js +4 -1
- package/dist/agent/service-gate.js.map +1 -1
- package/dist/agent/state.d.ts +14 -0
- package/dist/agent/state.d.ts.map +1 -1
- package/dist/agent/state.js +13 -5
- package/dist/agent/state.js.map +1 -1
- package/dist/agent/status.d.ts.map +1 -1
- package/dist/agent/status.js +4 -1
- package/dist/agent/status.js.map +1 -1
- package/dist/agent/system-prompt.d.ts.map +1 -1
- package/dist/agent/system-prompt.js +11 -1
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/agent/tool-call-watchdog.d.ts +7 -0
- package/dist/agent/tool-call-watchdog.d.ts.map +1 -1
- package/dist/agent/tool-call-watchdog.js +32 -2
- package/dist/agent/tool-call-watchdog.js.map +1 -1
- package/dist/agent/wake-cycle-runner.d.ts +11 -0
- package/dist/agent/wake-cycle-runner.d.ts.map +1 -1
- package/dist/agent/wake-cycle-runner.js +42 -9
- package/dist/agent/wake-cycle-runner.js.map +1 -1
- package/dist/channels/interface.d.ts +18 -0
- package/dist/channels/interface.d.ts.map +1 -1
- package/dist/channels/interface.js.map +1 -1
- package/dist/channels/qq-status.d.ts.map +1 -1
- package/dist/channels/qq-status.js +1 -0
- package/dist/channels/qq-status.js.map +1 -1
- package/dist/channels/telegram-status.d.ts +22 -4
- package/dist/channels/telegram-status.d.ts.map +1 -1
- package/dist/channels/telegram-status.js +216 -39
- package/dist/channels/telegram-status.js.map +1 -1
- package/dist/channels/telegram-task-board.d.ts +79 -0
- package/dist/channels/telegram-task-board.d.ts.map +1 -0
- package/dist/channels/telegram-task-board.js +384 -0
- package/dist/channels/telegram-task-board.js.map +1 -0
- package/dist/channels/telegram.d.ts +6 -1
- package/dist/channels/telegram.d.ts.map +1 -1
- package/dist/channels/telegram.js +31 -2
- package/dist/channels/telegram.js.map +1 -1
- package/dist/i18n/messages.d.ts +248 -0
- package/dist/i18n/messages.d.ts.map +1 -1
- package/dist/i18n/messages.js +79 -13
- package/dist/i18n/messages.js.map +1 -1
- package/dist/obs/tunnel.d.ts +9 -1
- package/dist/obs/tunnel.d.ts.map +1 -1
- package/dist/obs/tunnel.js +121 -54
- package/dist/obs/tunnel.js.map +1 -1
- package/dist/stt-client.d.ts +10 -0
- package/dist/stt-client.d.ts.map +1 -1
- package/dist/stt-client.js +64 -31
- package/dist/stt-client.js.map +1 -1
- package/dist/threads/foreground-task.d.ts +10 -2
- package/dist/threads/foreground-task.d.ts.map +1 -1
- package/dist/threads/foreground-task.js +18 -3
- package/dist/threads/foreground-task.js.map +1 -1
- package/dist/threads/foreman-host.d.ts +13 -1
- package/dist/threads/foreman-host.d.ts.map +1 -1
- package/dist/threads/foreman-host.js +79 -7
- package/dist/threads/foreman-host.js.map +1 -1
- package/dist/threads/foreman-protocol.d.ts +2 -0
- package/dist/threads/foreman-protocol.d.ts.map +1 -1
- package/dist/threads/foreman-protocol.js +3 -1
- package/dist/threads/foreman-protocol.js.map +1 -1
- package/dist/threads/process-group.js +7 -2
- package/dist/threads/process-group.js.map +1 -1
- package/dist/threads/relay-adapter.d.ts +2 -0
- package/dist/threads/relay-adapter.d.ts.map +1 -1
- package/dist/threads/relay-adapter.js +6 -0
- package/dist/threads/relay-adapter.js.map +1 -1
- package/dist/threads/task-settlement.d.ts +17 -0
- package/dist/threads/task-settlement.d.ts.map +1 -0
- package/dist/threads/task-settlement.js +34 -0
- package/dist/threads/task-settlement.js.map +1 -0
- package/dist/threads/thread-activity-controller.d.ts +21 -0
- package/dist/threads/thread-activity-controller.d.ts.map +1 -1
- package/dist/threads/thread-activity-controller.js +111 -3
- package/dist/threads/thread-activity-controller.js.map +1 -1
- package/dist/tools/browser-health.d.ts +2 -0
- package/dist/tools/browser-health.d.ts.map +1 -0
- package/dist/tools/browser-health.js +18 -0
- package/dist/tools/browser-health.js.map +1 -0
- package/dist/tools/browser-set-engine.js +1 -1
- package/dist/tools/browser-set-engine.js.map +1 -1
- package/dist/tools/delegation.d.ts +7 -0
- package/dist/tools/delegation.d.ts.map +1 -1
- package/dist/tools/delegation.js +30 -3
- package/dist/tools/delegation.js.map +1 -1
- package/dist/tools/fund-league.d.ts +4 -0
- package/dist/tools/fund-league.d.ts.map +1 -1
- package/dist/tools/fund-league.js +1 -1
- package/dist/tools/fund-league.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/upgrade.d.ts +2 -1
- package/dist/tools/upgrade.d.ts.map +1 -1
- package/dist/tools/upgrade.js +26 -8
- package/dist/tools/upgrade.js.map +1 -1
- package/dist/utils/restart.d.ts +6 -0
- package/dist/utils/restart.d.ts.map +1 -1
- package/dist/utils/restart.js +7 -1
- package/dist/utils/restart.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +19 -9
- package/dist/utils/version-check.js.map +1 -1
- package/dist-agent/bundle.cjs +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { getSharedProfileDir } from "../config/index.js";
|
|
4
|
+
import { t } from "../i18n/index.js";
|
|
5
|
+
import { logger } from "../logger.js";
|
|
6
|
+
import { isMessageNotModified, TelegramApiError, } from "./telegram-status.js";
|
|
7
|
+
const BOARD_STORE_FILE = "telegram-task-boards.json";
|
|
8
|
+
/** Coalesce bursts of task changes into one edit, well under Telegram's per-chat limit. */
|
|
9
|
+
const DEFAULT_FLUSH_DELAY_MS = 1_500;
|
|
10
|
+
const MAX_TITLE_LENGTH = 60;
|
|
11
|
+
/**
|
|
12
|
+
* The longest a new board waits for the front reply: while the turn that
|
|
13
|
+
* delegated is still running, its reply has not been sent yet, and a board
|
|
14
|
+
* posted first would be the user's first answer (#2941).
|
|
15
|
+
*/
|
|
16
|
+
const DEFAULT_MAX_REPLY_WAIT_MS = 60_000;
|
|
17
|
+
/**
|
|
18
|
+
* A live row the ledger no longer knows and that has not changed for this
|
|
19
|
+
* long is dropped, so one lost final update cannot keep the board pinned.
|
|
20
|
+
*/
|
|
21
|
+
const STALE_ROW_MS = 24 * 60 * 60_000;
|
|
22
|
+
/** How often a board with live rows is checked against the ledger. */
|
|
23
|
+
const DEFAULT_RECHECK_MS = 10 * 60_000;
|
|
24
|
+
const STATE_DOT = {
|
|
25
|
+
queued: "🟡",
|
|
26
|
+
running: "🔵",
|
|
27
|
+
waiting: "🟣",
|
|
28
|
+
completed: "✅",
|
|
29
|
+
failed: "🔴",
|
|
30
|
+
cancelled: "⚪",
|
|
31
|
+
};
|
|
32
|
+
function isTerminal(state) {
|
|
33
|
+
return state === "completed" || state === "failed" || state === "cancelled";
|
|
34
|
+
}
|
|
35
|
+
class RateLimited extends Error {
|
|
36
|
+
retryAfterMs;
|
|
37
|
+
constructor(retryAfterMs) {
|
|
38
|
+
super("Telegram rate limit");
|
|
39
|
+
this.retryAfterMs = retryAfterMs;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function readBatches(file) {
|
|
43
|
+
try {
|
|
44
|
+
const parsed = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
45
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return {};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function escapeHtml(value) {
|
|
52
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A Telegram date-time entity: every client shows it in the reader's own
|
|
56
|
+
* timezone, like the chat's own message times. The inner text is the
|
|
57
|
+
* fallback for clients without the entity, in the owner's configured zone.
|
|
58
|
+
*/
|
|
59
|
+
function formatTime(timestamp, timeZone) {
|
|
60
|
+
const date = new Date(timestamp);
|
|
61
|
+
if (Number.isNaN(date.getTime()))
|
|
62
|
+
return "--:--";
|
|
63
|
+
let fallback;
|
|
64
|
+
try {
|
|
65
|
+
fallback = new Intl.DateTimeFormat("en-GB", { hour: "2-digit", minute: "2-digit", hourCycle: "h23", ...(timeZone ? { timeZone } : {}) }).format(date);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
fallback = new Intl.DateTimeFormat("en-GB", { hour: "2-digit", minute: "2-digit", hourCycle: "h23" }).format(date);
|
|
69
|
+
}
|
|
70
|
+
return `<tg-time unix="${Math.floor(date.getTime() / 1000)}" format="t">${fallback}</tg-time>`;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Board HTML (parse_mode HTML): a one-line summary (what the pinned bar
|
|
74
|
+
* shows), then one row per task. `timeZone` is the owner's configured zone,
|
|
75
|
+
* used only for the fallback text of the time entities.
|
|
76
|
+
*/
|
|
77
|
+
export function renderTaskBoard(tasks, locale, timeZone) {
|
|
78
|
+
const count = (state) => tasks.filter((task) => task.state === state).length;
|
|
79
|
+
const active = tasks.filter((task) => !isTerminal(task.state)).length;
|
|
80
|
+
const summary = [
|
|
81
|
+
active > 0
|
|
82
|
+
? t(active === 1 ? "taskboard.summary.active_one" : "taskboard.summary.active", locale, String(active))
|
|
83
|
+
: t("taskboard.summary.done", locale),
|
|
84
|
+
...["completed", "failed", "cancelled"]
|
|
85
|
+
.filter((state) => count(state) > 0)
|
|
86
|
+
.map((state) => t(`taskboard.summary.${state}`, locale, String(count(state)))),
|
|
87
|
+
].join(" · ");
|
|
88
|
+
const rows = tasks.map((task) => {
|
|
89
|
+
const title = escapeHtml(Array.from(task.title).slice(0, MAX_TITLE_LENGTH).join(""));
|
|
90
|
+
return `${STATE_DOT[task.state]} ${title} · ${t(`taskboard.state.${task.state}`, locale)} · ${formatTime(task.at, timeZone)}`;
|
|
91
|
+
});
|
|
92
|
+
return [summary, ...rows].join("\n");
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The pinned background-task board of each Telegram chat (#2941). Foreground
|
|
96
|
+
* replies never carry task status: the board is sent and silently pinned
|
|
97
|
+
* once per batch, after the front reply, then only edited in place; a task
|
|
98
|
+
* that did not finish gets one short notice replying to the board (a
|
|
99
|
+
* finished one gets its result from General, or the Foreman fallback);
|
|
100
|
+
* when every task is terminal the board
|
|
101
|
+
* is unpinned and stays in the history. Telegram failures are logged, never
|
|
102
|
+
* thrown: the board must not break a turn.
|
|
103
|
+
*/
|
|
104
|
+
export class TelegramTaskBoard {
|
|
105
|
+
options;
|
|
106
|
+
storeFile;
|
|
107
|
+
flushDelayMs;
|
|
108
|
+
maxReplyWaitMs;
|
|
109
|
+
recheckMs;
|
|
110
|
+
/** Chats whose front turn is still running (its reply is not out yet). */
|
|
111
|
+
busyChats = new Set();
|
|
112
|
+
batches;
|
|
113
|
+
timers = new Map();
|
|
114
|
+
chains = new Map();
|
|
115
|
+
stopped = false;
|
|
116
|
+
constructor(options) {
|
|
117
|
+
this.options = options;
|
|
118
|
+
this.storeFile = options.storeFile ?? path.join(getSharedProfileDir(), BOARD_STORE_FILE);
|
|
119
|
+
this.flushDelayMs = options.flushDelayMs ?? DEFAULT_FLUSH_DELAY_MS;
|
|
120
|
+
this.maxReplyWaitMs = options.maxReplyWaitMs ?? DEFAULT_MAX_REPLY_WAIT_MS;
|
|
121
|
+
this.recheckMs = options.recheckMs ?? DEFAULT_RECHECK_MS;
|
|
122
|
+
this.batches = readBatches(this.storeFile);
|
|
123
|
+
// Boards left from before a restart: their final updates may have been
|
|
124
|
+
// missed while the process was down.
|
|
125
|
+
for (const key of Object.keys(this.batches))
|
|
126
|
+
this.schedule(key, key.includes("#closed:") ? 0 : this.recheckMs);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Whether the chat's current turn is still running. A new board waits for
|
|
130
|
+
* the turn to stop (its reply is sent by then), up to `maxReplyWaitMs`.
|
|
131
|
+
*/
|
|
132
|
+
setTurnRunning(address, running) {
|
|
133
|
+
const key = this.key(address);
|
|
134
|
+
if (running) {
|
|
135
|
+
this.busyChats.add(key);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (!this.busyChats.delete(key))
|
|
139
|
+
return;
|
|
140
|
+
const batch = this.batches[key];
|
|
141
|
+
if (!this.stopped && batch && batch.messageId === undefined)
|
|
142
|
+
this.reschedule(key, this.flushDelayMs);
|
|
143
|
+
}
|
|
144
|
+
update(address, task) {
|
|
145
|
+
if (this.stopped)
|
|
146
|
+
return;
|
|
147
|
+
const key = this.key(address);
|
|
148
|
+
let batch = this.batches[key];
|
|
149
|
+
const index = batch?.tasks.findIndex((entry) => entry.taskId === task.taskId) ?? -1;
|
|
150
|
+
// A terminal state only matters to a batch that already shows the task.
|
|
151
|
+
if (index < 0 && isTerminal(task.state))
|
|
152
|
+
return;
|
|
153
|
+
// A new task joining an existing board: first repair rows whose final
|
|
154
|
+
// update was lost. If none of them is still live, that board is closed
|
|
155
|
+
// (unpinned) and the new task starts a fresh one.
|
|
156
|
+
if (batch && index < 0 && this.reconcile(batch)) {
|
|
157
|
+
this.close(key, batch);
|
|
158
|
+
batch = undefined;
|
|
159
|
+
}
|
|
160
|
+
if (!batch) {
|
|
161
|
+
batch = {
|
|
162
|
+
chatId: address.chatId,
|
|
163
|
+
...(address.messageThreadId === undefined ? {} : { messageThreadId: address.messageThreadId }),
|
|
164
|
+
pinned: false,
|
|
165
|
+
tasks: [],
|
|
166
|
+
noticed: [],
|
|
167
|
+
createdAtMs: Date.now(),
|
|
168
|
+
};
|
|
169
|
+
this.batches[key] = batch;
|
|
170
|
+
}
|
|
171
|
+
if (index < 0) {
|
|
172
|
+
batch.tasks.push(task);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
const previous = batch.tasks[index];
|
|
176
|
+
if (previous.state === task.state && previous.title === task.title)
|
|
177
|
+
return;
|
|
178
|
+
batch.tasks[index] = task;
|
|
179
|
+
}
|
|
180
|
+
if (!isTerminal(task.state))
|
|
181
|
+
batch.noticed = batch.noticed.filter((taskId) => taskId !== task.taskId);
|
|
182
|
+
this.persist();
|
|
183
|
+
this.schedule(key, this.flushDelayMs);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Bring live rows in line with the ledger: a row the ledger reports in
|
|
187
|
+
* another state takes that state (quietly: its result was already handled
|
|
188
|
+
* there); an unknown row that has been idle too long is dropped. Returns
|
|
189
|
+
* whether every remaining row is terminal.
|
|
190
|
+
*/
|
|
191
|
+
reconcile(batch) {
|
|
192
|
+
const lookup = this.options.lookupTask;
|
|
193
|
+
const now = Date.now();
|
|
194
|
+
batch.tasks = batch.tasks.flatMap((row) => {
|
|
195
|
+
if (isTerminal(row.state))
|
|
196
|
+
return [row];
|
|
197
|
+
const live = lookup?.(row.taskId);
|
|
198
|
+
if (live) {
|
|
199
|
+
if (isTerminal(live.state) && !batch.noticed.includes(row.taskId))
|
|
200
|
+
batch.noticed.push(row.taskId);
|
|
201
|
+
return [live.state === row.state ? row : { ...live, title: row.title }];
|
|
202
|
+
}
|
|
203
|
+
const age = now - Date.parse(row.at);
|
|
204
|
+
return Number.isFinite(age) && age > STALE_ROW_MS ? [] : [row];
|
|
205
|
+
});
|
|
206
|
+
return batch.tasks.every((row) => isTerminal(row.state));
|
|
207
|
+
}
|
|
208
|
+
/** Finish a board under its own key, so a new board can start in the chat. */
|
|
209
|
+
close(key, batch) {
|
|
210
|
+
Reflect.deleteProperty(this.batches, key);
|
|
211
|
+
const closingKey = `${key}#closed:${batch.messageId ?? batch.createdAtMs ?? Date.now()}`;
|
|
212
|
+
this.batches[closingKey] = batch;
|
|
213
|
+
this.persist();
|
|
214
|
+
this.schedule(closingKey, 0);
|
|
215
|
+
}
|
|
216
|
+
stop() {
|
|
217
|
+
this.stopped = true;
|
|
218
|
+
for (const { timer } of this.timers.values())
|
|
219
|
+
clearTimeout(timer);
|
|
220
|
+
this.timers.clear();
|
|
221
|
+
}
|
|
222
|
+
key(address) {
|
|
223
|
+
return `${this.options.botIdentity}:${address.chatId}:${address.messageThreadId ?? ""}`;
|
|
224
|
+
}
|
|
225
|
+
reschedule(key, delayMs) {
|
|
226
|
+
const existing = this.timers.get(key);
|
|
227
|
+
if (existing)
|
|
228
|
+
clearTimeout(existing.timer);
|
|
229
|
+
this.timers.delete(key);
|
|
230
|
+
this.schedule(key, delayMs);
|
|
231
|
+
}
|
|
232
|
+
/** Flush the board after `delayMs`, unless a flush is already due sooner. */
|
|
233
|
+
schedule(key, delayMs) {
|
|
234
|
+
const dueAt = Date.now() + delayMs;
|
|
235
|
+
const existing = this.timers.get(key);
|
|
236
|
+
if (existing && existing.dueAt <= dueAt)
|
|
237
|
+
return;
|
|
238
|
+
if (existing)
|
|
239
|
+
clearTimeout(existing.timer);
|
|
240
|
+
const timer = setTimeout(() => {
|
|
241
|
+
this.timers.delete(key);
|
|
242
|
+
const next = (this.chains.get(key) ?? Promise.resolve()).then(() => this.flush(key));
|
|
243
|
+
this.chains.set(key, next);
|
|
244
|
+
void next.finally(() => {
|
|
245
|
+
if (this.chains.get(key) === next)
|
|
246
|
+
this.chains.delete(key);
|
|
247
|
+
});
|
|
248
|
+
}, delayMs);
|
|
249
|
+
timer.unref();
|
|
250
|
+
this.timers.set(key, { timer, dueAt });
|
|
251
|
+
}
|
|
252
|
+
async flush(key) {
|
|
253
|
+
const batch = this.batches[key];
|
|
254
|
+
if (this.stopped || !batch)
|
|
255
|
+
return;
|
|
256
|
+
if (batch.messageId === undefined && this.busyChats.has(key)) {
|
|
257
|
+
const waitedMs = Date.now() - (batch.createdAtMs ?? 0);
|
|
258
|
+
if (waitedMs < this.maxReplyWaitMs) {
|
|
259
|
+
this.schedule(key, this.maxReplyWaitMs - waitedMs);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// The periodic safety net: a board whose last live rows went stale closes.
|
|
264
|
+
this.reconcile(batch);
|
|
265
|
+
try {
|
|
266
|
+
await this.syncBoard(batch);
|
|
267
|
+
await this.sendNotices(batch);
|
|
268
|
+
if (batch.tasks.every((task) => isTerminal(task.state))) {
|
|
269
|
+
if (batch.pinned && batch.messageId !== undefined) {
|
|
270
|
+
const unpinned = await this.call("unpinChatMessage", { chat_id: batch.chatId, message_id: batch.messageId });
|
|
271
|
+
if (unpinned.ok)
|
|
272
|
+
this.logAction("unpinned", batch);
|
|
273
|
+
}
|
|
274
|
+
Reflect.deleteProperty(this.batches, key);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
if (error instanceof RateLimited)
|
|
279
|
+
this.schedule(key, error.retryAfterMs);
|
|
280
|
+
else
|
|
281
|
+
logger.warn(`Telegram task board update failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
282
|
+
}
|
|
283
|
+
finally {
|
|
284
|
+
this.persist();
|
|
285
|
+
}
|
|
286
|
+
// Live rows left: check them against the ledger again later.
|
|
287
|
+
if (this.options.lookupTask && this.batches[key] === batch)
|
|
288
|
+
this.schedule(key, this.recheckMs);
|
|
289
|
+
}
|
|
290
|
+
async syncBoard(batch) {
|
|
291
|
+
const text = renderTaskBoard(batch.tasks, this.options.locale(), this.options.timeZone?.());
|
|
292
|
+
if (batch.renderedText === text)
|
|
293
|
+
return;
|
|
294
|
+
if (batch.messageId === undefined) {
|
|
295
|
+
const sent = await this.call("sendMessage", {
|
|
296
|
+
chat_id: batch.chatId,
|
|
297
|
+
text,
|
|
298
|
+
parse_mode: "HTML",
|
|
299
|
+
disable_notification: true,
|
|
300
|
+
...this.topic(batch),
|
|
301
|
+
});
|
|
302
|
+
const messageId = sent.ok ? sent.result?.message_id : undefined;
|
|
303
|
+
if (typeof messageId !== "number")
|
|
304
|
+
return;
|
|
305
|
+
batch.messageId = messageId;
|
|
306
|
+
batch.renderedText = text;
|
|
307
|
+
this.logAction("created", batch);
|
|
308
|
+
// The only pin of this batch: after a failed pin or a manual unpin the board stays unpinned.
|
|
309
|
+
const pinned = await this.call("pinChatMessage", {
|
|
310
|
+
chat_id: batch.chatId,
|
|
311
|
+
message_id: messageId,
|
|
312
|
+
disable_notification: true,
|
|
313
|
+
});
|
|
314
|
+
batch.pinned = pinned.ok;
|
|
315
|
+
if (pinned.ok)
|
|
316
|
+
this.logAction("pinned", batch);
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
const edited = await this.call("editMessageText", { chat_id: batch.chatId, message_id: batch.messageId, text, parse_mode: "HTML" });
|
|
320
|
+
if (edited.ok || isMessageNotModified(edited.error))
|
|
321
|
+
batch.renderedText = text;
|
|
322
|
+
if (edited.ok)
|
|
323
|
+
this.logAction("edited", batch);
|
|
324
|
+
}
|
|
325
|
+
/** One info line per board action: ids and the task count only, never titles or text. */
|
|
326
|
+
logAction(action, batch) {
|
|
327
|
+
logger.info(`Telegram task board ${action}`, {
|
|
328
|
+
action,
|
|
329
|
+
chatId: batch.chatId,
|
|
330
|
+
messageId: batch.messageId,
|
|
331
|
+
tasks: batch.tasks.length,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
async sendNotices(batch) {
|
|
335
|
+
const locale = this.options.locale();
|
|
336
|
+
for (const task of batch.tasks) {
|
|
337
|
+
// A finished task's own message is General's result (or the Foreman
|
|
338
|
+
// fallback when General sends none); a "done" notice before it is noise.
|
|
339
|
+
if ((task.state !== "failed" && task.state !== "cancelled") || batch.noticed.includes(task.taskId))
|
|
340
|
+
continue;
|
|
341
|
+
const sent = await this.call("sendMessage", {
|
|
342
|
+
chat_id: batch.chatId,
|
|
343
|
+
text: t(`taskboard.notice.${task.state}`, locale, task.title, t(`task.failure.${task.failure ?? "error"}`, locale)),
|
|
344
|
+
...this.topic(batch),
|
|
345
|
+
...(batch.messageId === undefined
|
|
346
|
+
? {}
|
|
347
|
+
: { reply_parameters: { message_id: batch.messageId, allow_sending_without_reply: true } }),
|
|
348
|
+
});
|
|
349
|
+
if (sent.ok)
|
|
350
|
+
batch.noticed.push(task.taskId);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
topic(batch) {
|
|
354
|
+
return batch.messageThreadId === undefined ? {} : { message_thread_id: batch.messageThreadId };
|
|
355
|
+
}
|
|
356
|
+
/** One Bot API call. Rate limits abort the flush for a later retry; other failures are logged. */
|
|
357
|
+
async call(method, body) {
|
|
358
|
+
try {
|
|
359
|
+
const response = await this.options.transport.request(method, body);
|
|
360
|
+
return { ok: true, result: response.result };
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
if (error instanceof TelegramApiError && error.errorCode === 429) {
|
|
364
|
+
throw new RateLimited((error.parameters?.retry_after ?? 5) * 1000);
|
|
365
|
+
}
|
|
366
|
+
if (!isMessageNotModified(error)) {
|
|
367
|
+
logger.warn(`Telegram task board ${method} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
368
|
+
}
|
|
369
|
+
return { ok: false, error };
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
persist() {
|
|
373
|
+
try {
|
|
374
|
+
fs.mkdirSync(path.dirname(this.storeFile), { recursive: true, mode: 0o700 });
|
|
375
|
+
const tmp = `${this.storeFile}.${process.pid}.tmp`;
|
|
376
|
+
fs.writeFileSync(tmp, `${JSON.stringify(this.batches, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
|
|
377
|
+
fs.renameSync(tmp, this.storeFile);
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
logger.warn(`Telegram task board state was not saved: ${error instanceof Error ? error.message : String(error)}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
//# sourceMappingURL=telegram-task-board.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram-task-board.js","sourceRoot":"","sources":["../../src/channels/telegram-task-board.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
2
|
import { type VisionClawConfig } from "../config/types.js";
|
|
3
|
-
import { type InboundMessageHandler, type ChannelAdapter, type DeliveryContext, type DeliveryTarget, type MessageAttachment, type ReplyContext } from "./interface.js";
|
|
3
|
+
import { type BackgroundTaskView, type InboundMessageHandler, type ChannelAdapter, type DeliveryContext, type DeliveryTarget, type MessageAttachment, type ReplyContext } from "./interface.js";
|
|
4
4
|
import type { PublicThreadActivity } from "../agent/public-activity.js";
|
|
5
5
|
/**
|
|
6
6
|
* Telegram channel adapter.
|
|
@@ -19,6 +19,8 @@ export declare class TelegramAdapter extends EventEmitter implements ChannelAdap
|
|
|
19
19
|
* authorize admin commands and always trust the owner's direct chat. */
|
|
20
20
|
private _ownerUserId;
|
|
21
21
|
private statusPublisher;
|
|
22
|
+
private taskBoard;
|
|
23
|
+
private backgroundTaskLookup;
|
|
22
24
|
/** Cached plans from the most recent payment prompt, used by the callback handler */
|
|
23
25
|
constructor(config: VisionClawConfig);
|
|
24
26
|
/**
|
|
@@ -27,6 +29,9 @@ export declare class TelegramAdapter extends EventEmitter implements ChannelAdap
|
|
|
27
29
|
*/
|
|
28
30
|
setOwnerUserId(id: number): void;
|
|
29
31
|
publishThreadActivity(threadId: string, activity: PublicThreadActivity, _agentInstanceId: string, deliveryTarget?: DeliveryTarget): void;
|
|
32
|
+
setBackgroundTaskLookup(lookup: (taskId: string) => BackgroundTaskView | null): void;
|
|
33
|
+
publishBackgroundTask(target: DeliveryTarget, task: BackgroundTaskView): void;
|
|
34
|
+
private getTaskBoard;
|
|
30
35
|
/** Best-effort read of the owner's language preference for i18n. */
|
|
31
36
|
private getOwnerLocale;
|
|
32
37
|
/** Best-effort read of the owner's timezone preference for settings UI. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telegram.d.ts","sourceRoot":"","sources":["../../src/channels/telegram.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAU3C,OAAO,EACL,KAAK,gBAAgB,EAItB,MAAM,oBAAoB,CAAC;AAU5B,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EAEnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"telegram.d.ts","sourceRoot":"","sources":["../../src/channels/telegram.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,8 @@ import { applyEngineSwitchTarget, describeEngineTarget, isAlreadyOnEngineTarget,
|
|
|
12
12
|
import { LlmGatewayModelsError } from "../agent/llm-gateway-models.js";
|
|
13
13
|
import { unavailableTargetFromTelegram } from "./unavailable-target.js";
|
|
14
14
|
import { VOICE_TRANSCRIPTION_HANDLED_META_KEY, isAssistantTextDelivery, } from "./interface.js";
|
|
15
|
-
import { createTelegramStatusPublisher } from "./telegram-status.js";
|
|
15
|
+
import { createTelegramStatusPublisher, TelegramHttpTransport } from "./telegram-status.js";
|
|
16
|
+
import { TelegramTaskBoard } from "./telegram-task-board.js";
|
|
16
17
|
import { buildTelegramPreview, buildTelegramTitle, createTelegramAccessEntry, formatTelegramAccessSummary, getTelegramChatKind, serializeTelegramMessage, } from "./telegram-access.js";
|
|
17
18
|
import { syncBotCommands } from "../onboarding/bot-profile.js";
|
|
18
19
|
import { OnboardingServiceClient } from "../onboarding/onboarding-service-client.js";
|
|
@@ -128,6 +129,8 @@ export class TelegramAdapter extends EventEmitter {
|
|
|
128
129
|
* authorize admin commands and always trust the owner's direct chat. */
|
|
129
130
|
_ownerUserId = null;
|
|
130
131
|
statusPublisher = null;
|
|
132
|
+
taskBoard = null;
|
|
133
|
+
backgroundTaskLookup = null;
|
|
131
134
|
/** Cached plans from the most recent payment prompt, used by the callback handler */
|
|
132
135
|
constructor(config) {
|
|
133
136
|
super();
|
|
@@ -150,6 +153,30 @@ export class TelegramAdapter extends EventEmitter {
|
|
|
150
153
|
if (!target)
|
|
151
154
|
return;
|
|
152
155
|
void publisher.publish(threadId, activity, target);
|
|
156
|
+
// A new task board waits until this chat's turn has sent its reply.
|
|
157
|
+
this.getTaskBoard()?.setTurnRunning(target, activity.state === "running" || activity.state === "queued");
|
|
158
|
+
}
|
|
159
|
+
setBackgroundTaskLookup(lookup) {
|
|
160
|
+
this.backgroundTaskLookup = lookup;
|
|
161
|
+
}
|
|
162
|
+
publishBackgroundTask(target, task) {
|
|
163
|
+
const address = this.resolveActivityDeliveryTarget(target);
|
|
164
|
+
if (!address)
|
|
165
|
+
return;
|
|
166
|
+
this.getTaskBoard()?.update(address, task);
|
|
167
|
+
}
|
|
168
|
+
getTaskBoard() {
|
|
169
|
+
const botToken = this.config.channels.telegram?.botToken;
|
|
170
|
+
if (!this._botIdentity || !this.bot || !botToken)
|
|
171
|
+
return null;
|
|
172
|
+
this.taskBoard ??= new TelegramTaskBoard({
|
|
173
|
+
botIdentity: this._botIdentity,
|
|
174
|
+
transport: new TelegramHttpTransport(botToken),
|
|
175
|
+
locale: () => resolveLocale(this.getOwnerLocale()),
|
|
176
|
+
timeZone: () => this.getOwnerTimezone(),
|
|
177
|
+
lookupTask: (taskId) => this.backgroundTaskLookup?.(taskId),
|
|
178
|
+
});
|
|
179
|
+
return this.taskBoard;
|
|
153
180
|
}
|
|
154
181
|
/** Best-effort read of the owner's language preference for i18n. */
|
|
155
182
|
getOwnerLocale() {
|
|
@@ -1047,6 +1074,8 @@ export class TelegramAdapter extends EventEmitter {
|
|
|
1047
1074
|
async stop() {
|
|
1048
1075
|
this.statusPublisher?.stop();
|
|
1049
1076
|
this.statusPublisher = null;
|
|
1077
|
+
this.taskBoard?.stop();
|
|
1078
|
+
this.taskBoard = null;
|
|
1050
1079
|
if (this.bot) {
|
|
1051
1080
|
await this.bot.stopPolling({ cancel: true });
|
|
1052
1081
|
this.bot = null;
|
|
@@ -1066,7 +1095,7 @@ export class TelegramAdapter extends EventEmitter {
|
|
|
1066
1095
|
const botToken = this.config.channels.telegram?.botToken;
|
|
1067
1096
|
if (!ownerChatId || !botToken)
|
|
1068
1097
|
return null;
|
|
1069
|
-
this.statusPublisher ??= createTelegramStatusPublisher(botToken, ownerChatId, (threadId) => this.resolveStatusTarget(threadId));
|
|
1098
|
+
this.statusPublisher ??= createTelegramStatusPublisher(botToken, ownerChatId, (threadId) => this.resolveStatusTarget(threadId), () => resolveLocale(this.getOwnerLocale()));
|
|
1070
1099
|
return this.statusPublisher;
|
|
1071
1100
|
}
|
|
1072
1101
|
resolveActivityDeliveryTarget(target) {
|