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.
Files changed (144) hide show
  1. package/dist/agent/browser-launcher.d.ts +19 -1
  2. package/dist/agent/browser-launcher.d.ts.map +1 -1
  3. package/dist/agent/browser-launcher.js +40 -0
  4. package/dist/agent/browser-launcher.js.map +1 -1
  5. package/dist/agent/command-handlers.js +2 -2
  6. package/dist/agent/command-handlers.js.map +1 -1
  7. package/dist/agent/engines/claude/session.d.ts +6 -0
  8. package/dist/agent/engines/claude/session.d.ts.map +1 -1
  9. package/dist/agent/engines/claude/session.js +34 -2
  10. package/dist/agent/engines/claude/session.js.map +1 -1
  11. package/dist/agent/engines/pi/tools.d.ts.map +1 -1
  12. package/dist/agent/engines/pi/tools.js +2 -1
  13. package/dist/agent/engines/pi/tools.js.map +1 -1
  14. package/dist/agent/fund-league-hold.d.ts.map +1 -1
  15. package/dist/agent/fund-league-hold.js +5 -1
  16. package/dist/agent/fund-league-hold.js.map +1 -1
  17. package/dist/agent/interrupt-handler.d.ts.map +1 -1
  18. package/dist/agent/interrupt-handler.js +4 -1
  19. package/dist/agent/interrupt-handler.js.map +1 -1
  20. package/dist/agent/lifecycle-trace.d.ts +3 -2
  21. package/dist/agent/lifecycle-trace.d.ts.map +1 -1
  22. package/dist/agent/lifecycle-trace.js +4 -9
  23. package/dist/agent/lifecycle-trace.js.map +1 -1
  24. package/dist/agent/lifecycle-transitions.d.ts +42 -0
  25. package/dist/agent/lifecycle-transitions.d.ts.map +1 -1
  26. package/dist/agent/lifecycle-transitions.js +62 -6
  27. package/dist/agent/lifecycle-transitions.js.map +1 -1
  28. package/dist/agent/loop.d.ts.map +1 -1
  29. package/dist/agent/loop.js +99 -27
  30. package/dist/agent/loop.js.map +1 -1
  31. package/dist/agent/public-activity.d.ts +1 -1
  32. package/dist/agent/public-activity.d.ts.map +1 -1
  33. package/dist/agent/public-activity.js.map +1 -1
  34. package/dist/agent/runtime-context.d.ts +2 -0
  35. package/dist/agent/runtime-context.d.ts.map +1 -1
  36. package/dist/agent/runtime-context.js +4 -0
  37. package/dist/agent/runtime-context.js.map +1 -1
  38. package/dist/agent/service-gate.d.ts.map +1 -1
  39. package/dist/agent/service-gate.js +4 -1
  40. package/dist/agent/service-gate.js.map +1 -1
  41. package/dist/agent/state.d.ts +14 -0
  42. package/dist/agent/state.d.ts.map +1 -1
  43. package/dist/agent/state.js +13 -5
  44. package/dist/agent/state.js.map +1 -1
  45. package/dist/agent/status.d.ts.map +1 -1
  46. package/dist/agent/status.js +4 -1
  47. package/dist/agent/status.js.map +1 -1
  48. package/dist/agent/system-prompt.d.ts.map +1 -1
  49. package/dist/agent/system-prompt.js +11 -1
  50. package/dist/agent/system-prompt.js.map +1 -1
  51. package/dist/agent/tool-call-watchdog.d.ts +7 -0
  52. package/dist/agent/tool-call-watchdog.d.ts.map +1 -1
  53. package/dist/agent/tool-call-watchdog.js +32 -2
  54. package/dist/agent/tool-call-watchdog.js.map +1 -1
  55. package/dist/agent/wake-cycle-runner.d.ts +11 -0
  56. package/dist/agent/wake-cycle-runner.d.ts.map +1 -1
  57. package/dist/agent/wake-cycle-runner.js +42 -9
  58. package/dist/agent/wake-cycle-runner.js.map +1 -1
  59. package/dist/channels/interface.d.ts +18 -0
  60. package/dist/channels/interface.d.ts.map +1 -1
  61. package/dist/channels/interface.js.map +1 -1
  62. package/dist/channels/qq-status.d.ts.map +1 -1
  63. package/dist/channels/qq-status.js +1 -0
  64. package/dist/channels/qq-status.js.map +1 -1
  65. package/dist/channels/telegram-status.d.ts +22 -4
  66. package/dist/channels/telegram-status.d.ts.map +1 -1
  67. package/dist/channels/telegram-status.js +216 -39
  68. package/dist/channels/telegram-status.js.map +1 -1
  69. package/dist/channels/telegram-task-board.d.ts +79 -0
  70. package/dist/channels/telegram-task-board.d.ts.map +1 -0
  71. package/dist/channels/telegram-task-board.js +384 -0
  72. package/dist/channels/telegram-task-board.js.map +1 -0
  73. package/dist/channels/telegram.d.ts +6 -1
  74. package/dist/channels/telegram.d.ts.map +1 -1
  75. package/dist/channels/telegram.js +31 -2
  76. package/dist/channels/telegram.js.map +1 -1
  77. package/dist/i18n/messages.d.ts +248 -0
  78. package/dist/i18n/messages.d.ts.map +1 -1
  79. package/dist/i18n/messages.js +79 -13
  80. package/dist/i18n/messages.js.map +1 -1
  81. package/dist/obs/tunnel.d.ts +9 -1
  82. package/dist/obs/tunnel.d.ts.map +1 -1
  83. package/dist/obs/tunnel.js +121 -54
  84. package/dist/obs/tunnel.js.map +1 -1
  85. package/dist/stt-client.d.ts +10 -0
  86. package/dist/stt-client.d.ts.map +1 -1
  87. package/dist/stt-client.js +64 -31
  88. package/dist/stt-client.js.map +1 -1
  89. package/dist/threads/foreground-task.d.ts +10 -2
  90. package/dist/threads/foreground-task.d.ts.map +1 -1
  91. package/dist/threads/foreground-task.js +18 -3
  92. package/dist/threads/foreground-task.js.map +1 -1
  93. package/dist/threads/foreman-host.d.ts +13 -1
  94. package/dist/threads/foreman-host.d.ts.map +1 -1
  95. package/dist/threads/foreman-host.js +79 -7
  96. package/dist/threads/foreman-host.js.map +1 -1
  97. package/dist/threads/foreman-protocol.d.ts +2 -0
  98. package/dist/threads/foreman-protocol.d.ts.map +1 -1
  99. package/dist/threads/foreman-protocol.js +3 -1
  100. package/dist/threads/foreman-protocol.js.map +1 -1
  101. package/dist/threads/process-group.js +7 -2
  102. package/dist/threads/process-group.js.map +1 -1
  103. package/dist/threads/relay-adapter.d.ts +2 -0
  104. package/dist/threads/relay-adapter.d.ts.map +1 -1
  105. package/dist/threads/relay-adapter.js +6 -0
  106. package/dist/threads/relay-adapter.js.map +1 -1
  107. package/dist/threads/task-settlement.d.ts +17 -0
  108. package/dist/threads/task-settlement.d.ts.map +1 -0
  109. package/dist/threads/task-settlement.js +34 -0
  110. package/dist/threads/task-settlement.js.map +1 -0
  111. package/dist/threads/thread-activity-controller.d.ts +21 -0
  112. package/dist/threads/thread-activity-controller.d.ts.map +1 -1
  113. package/dist/threads/thread-activity-controller.js +111 -3
  114. package/dist/threads/thread-activity-controller.js.map +1 -1
  115. package/dist/tools/browser-health.d.ts +2 -0
  116. package/dist/tools/browser-health.d.ts.map +1 -0
  117. package/dist/tools/browser-health.js +18 -0
  118. package/dist/tools/browser-health.js.map +1 -0
  119. package/dist/tools/browser-set-engine.js +1 -1
  120. package/dist/tools/browser-set-engine.js.map +1 -1
  121. package/dist/tools/delegation.d.ts +7 -0
  122. package/dist/tools/delegation.d.ts.map +1 -1
  123. package/dist/tools/delegation.js +30 -3
  124. package/dist/tools/delegation.js.map +1 -1
  125. package/dist/tools/fund-league.d.ts +4 -0
  126. package/dist/tools/fund-league.d.ts.map +1 -1
  127. package/dist/tools/fund-league.js +1 -1
  128. package/dist/tools/fund-league.js.map +1 -1
  129. package/dist/tools/index.d.ts.map +1 -1
  130. package/dist/tools/index.js +2 -0
  131. package/dist/tools/index.js.map +1 -1
  132. package/dist/tools/upgrade.d.ts +2 -1
  133. package/dist/tools/upgrade.d.ts.map +1 -1
  134. package/dist/tools/upgrade.js +26 -8
  135. package/dist/tools/upgrade.js.map +1 -1
  136. package/dist/utils/restart.d.ts +6 -0
  137. package/dist/utils/restart.d.ts.map +1 -1
  138. package/dist/utils/restart.js +7 -1
  139. package/dist/utils/restart.js.map +1 -1
  140. package/dist/utils/version-check.d.ts.map +1 -1
  141. package/dist/utils/version-check.js +19 -9
  142. package/dist/utils/version-check.js.map +1 -1
  143. package/dist-agent/bundle.cjs +2 -2
  144. 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("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
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":"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"}
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,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EAEnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAiJxE;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,YAAa,YAAW,cAAc;IACzE,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,IAAI,cAAc;IAC3B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,GAAG,CAA4B;IACvC,yFAAyF;IACzF,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAAoD;IAC1E;6EACyE;IACzE,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,oBAAoB,CAAgE;IAC5F,qFAAqF;gBAEzE,MAAM,EAAE,gBAAgB;IAKpC;;;OAGG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIhC,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,cAAc,GAAG,IAAI;IAYxI,uBAAuB,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,IAAI,GAAG,IAAI;IAIpF,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,kBAAkB,GAAG,IAAI;IAM7E,OAAO,CAAC,YAAY;IAapB,oEAAoE;IACpE,OAAO,CAAC,cAAc;IAQtB,2EAA2E;IAC3E,OAAO,CAAC,gBAAgB;IAQxB;;;;;OAKG;IACH,wBAAwB,IAAI,IAAI;IAgBhC;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCrD;;;;OAIG;YACW,uBAAuB;YA0BvB,qBAAqB;YA6DrB,sBAAsB;YAwCtB,uBAAuB;YAsCvB,mBAAmB;YAyCnB,mBAAmB;IAuEjC,6DAA6D;IAC7D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CACuK;IAEpN;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;;OAGG;YACW,qBAAqB;IAQnC,OAAO,CAAC,oBAAoB;IAwL5B,OAAO,CAAC,gBAAgB;IAOxB;;;;;;OAMG;IACH,OAAO,CAAC,yBAAyB;IAUjC;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAYvB;;;;;;;;;OASG;IACH,OAAO,CAAC,6BAA6B;IAWrC,OAAO,CAAC,0BAA0B;IAIlC,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,uBAAuB;YAIjB,qBAAqB;YAmCrB,4BAA4B;YA0C5B,yBAAyB;IAqBvC,OAAO,CAAC,yBAAyB;IAejC,OAAO,CAAC,eAAe;YA4BT,YAAY;YA4BZ,UAAU;YA4BV,mBAAmB;IAgBjC;;;;OAIG;IACH,OAAO,CAAC,cAAc;YAWR,cAAc;YAcd,mBAAmB;YAYnB,oBAAoB;IAkBlC,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,kBAAkB;IAa1B,qFAAqF;IACrF,OAAO,CAAC,iBAAiB,CAA0E;YAErF,gBAAgB;YAahB,qBAAqB;IA6CnC;;;OAGG;YACW,iBAAiB;YAejB,YAAY;YAgDZ,sBAAsB;IA2B9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,6BAA6B;IAQrC,OAAO,CAAC,mBAAmB;IAoBrB,WAAW,CACf,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,iBAAiB,EAAE,EACjC,OAAO,CAAC,EAAE,YAAY,EACtB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,IAAI,CAAC;IA8GV,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB5E;;;OAGG;YACW,qBAAqB;IAmKnC;;OAEG;YACW,eAAe;YAYf,QAAQ;IA0BtB,uDAAuD;IACvD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAa7B;IAEX,gDAAgD;IAChD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAG7B;IAEX;;OAEG;IACG,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAgBhB;;;OAGG;IACG,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3D;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoChD;;OAEG;YACW,gBAAgB;IAuB9B;;OAEG;YACW,gBAAgB;IAsC9B;;;OAGG;YACW,yBAAyB;IA+FvC;;OAEG;YACW,iBAAiB;IAmD/B;;;OAGG;YACW,qBAAqB;CA0CpC"}
@@ -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) {