sensorium-mcp 2.16.29 → 2.16.30

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 (177) hide show
  1. package/dist/config.d.ts +1 -11
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +3 -49
  4. package/dist/config.js.map +1 -1
  5. package/dist/dashboard/presets.d.ts +18 -0
  6. package/dist/dashboard/presets.d.ts.map +1 -0
  7. package/dist/dashboard/presets.js +78 -0
  8. package/dist/dashboard/presets.js.map +1 -0
  9. package/dist/dashboard/routes.d.ts +33 -0
  10. package/dist/dashboard/routes.d.ts.map +1 -0
  11. package/dist/dashboard/routes.js +283 -0
  12. package/dist/dashboard/routes.js.map +1 -0
  13. package/dist/dashboard.d.ts +6 -29
  14. package/dist/dashboard.d.ts.map +1 -1
  15. package/dist/dashboard.js +6 -1158
  16. package/dist/dashboard.js.map +1 -1
  17. package/dist/data/file-storage.d.ts +19 -0
  18. package/dist/data/file-storage.d.ts.map +1 -0
  19. package/dist/data/file-storage.js +58 -0
  20. package/dist/data/file-storage.js.map +1 -0
  21. package/dist/data/memory/bootstrap.d.ts +40 -0
  22. package/dist/data/memory/bootstrap.d.ts.map +1 -0
  23. package/dist/data/memory/bootstrap.js +240 -0
  24. package/dist/data/memory/bootstrap.js.map +1 -0
  25. package/dist/data/memory/consolidation.d.ts +12 -0
  26. package/dist/data/memory/consolidation.d.ts.map +1 -0
  27. package/dist/data/memory/consolidation.js +248 -0
  28. package/dist/data/memory/consolidation.js.map +1 -0
  29. package/dist/data/memory/episodes.d.ts +34 -0
  30. package/dist/data/memory/episodes.d.ts.map +1 -0
  31. package/dist/data/memory/episodes.js +89 -0
  32. package/dist/data/memory/episodes.js.map +1 -0
  33. package/dist/data/memory/index.d.ts +14 -0
  34. package/dist/data/memory/index.d.ts.map +1 -0
  35. package/dist/data/memory/index.js +14 -0
  36. package/dist/data/memory/index.js.map +1 -0
  37. package/dist/data/memory/procedures.d.ts +42 -0
  38. package/dist/data/memory/procedures.d.ts.map +1 -0
  39. package/dist/data/memory/procedures.js +122 -0
  40. package/dist/data/memory/procedures.js.map +1 -0
  41. package/dist/data/memory/schema.d.ts +11 -0
  42. package/dist/data/memory/schema.d.ts.map +1 -0
  43. package/dist/data/memory/schema.js +327 -0
  44. package/dist/data/memory/schema.js.map +1 -0
  45. package/dist/data/memory/semantic.d.ts +94 -0
  46. package/dist/data/memory/semantic.d.ts.map +1 -0
  47. package/dist/data/memory/semantic.js +385 -0
  48. package/dist/data/memory/semantic.js.map +1 -0
  49. package/dist/data/memory/voice-sig.d.ts +33 -0
  50. package/dist/data/memory/voice-sig.d.ts.map +1 -0
  51. package/dist/data/memory/voice-sig.js +48 -0
  52. package/dist/data/memory/voice-sig.js.map +1 -0
  53. package/dist/data/templates.d.ts +19 -0
  54. package/dist/data/templates.d.ts.map +1 -0
  55. package/dist/data/templates.js +46 -0
  56. package/dist/data/templates.js.map +1 -0
  57. package/dist/dispatcher.d.ts +5 -97
  58. package/dist/dispatcher.d.ts.map +1 -1
  59. package/dist/dispatcher.js +5 -525
  60. package/dist/dispatcher.js.map +1 -1
  61. package/dist/drive.d.ts.map +1 -1
  62. package/dist/drive.js +3 -1
  63. package/dist/drive.js.map +1 -1
  64. package/dist/index.d.ts +4 -23
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +11 -289
  67. package/dist/index.js.map +1 -1
  68. package/dist/integrations/openai/chat.d.ts +29 -0
  69. package/dist/integrations/openai/chat.d.ts.map +1 -0
  70. package/dist/integrations/openai/chat.js +84 -0
  71. package/dist/integrations/openai/chat.js.map +1 -0
  72. package/dist/integrations/openai/index.d.ts +6 -0
  73. package/dist/integrations/openai/index.d.ts.map +1 -0
  74. package/dist/integrations/openai/index.js +6 -0
  75. package/dist/integrations/openai/index.js.map +1 -0
  76. package/dist/integrations/openai/speech.d.ts +21 -0
  77. package/dist/integrations/openai/speech.d.ts.map +1 -0
  78. package/dist/integrations/openai/speech.js +75 -0
  79. package/dist/integrations/openai/speech.js.map +1 -0
  80. package/dist/integrations/openai/video.d.ts +15 -0
  81. package/dist/integrations/openai/video.d.ts.map +1 -0
  82. package/dist/integrations/openai/video.js +131 -0
  83. package/dist/integrations/openai/video.js.map +1 -0
  84. package/dist/integrations/openai/vision.d.ts +23 -0
  85. package/dist/integrations/openai/vision.d.ts.map +1 -0
  86. package/dist/integrations/openai/vision.js +116 -0
  87. package/dist/integrations/openai/vision.js.map +1 -0
  88. package/dist/integrations/openai/voice-emotion.d.ts +41 -0
  89. package/dist/integrations/openai/voice-emotion.d.ts.map +1 -0
  90. package/dist/integrations/openai/voice-emotion.js +50 -0
  91. package/dist/integrations/openai/voice-emotion.js.map +1 -0
  92. package/dist/integrations/telegram/types.d.ts +112 -0
  93. package/dist/integrations/telegram/types.d.ts.map +1 -0
  94. package/dist/integrations/telegram/types.js +6 -0
  95. package/dist/integrations/telegram/types.js.map +1 -0
  96. package/dist/memory.d.ts +6 -205
  97. package/dist/memory.d.ts.map +1 -1
  98. package/dist/memory.js +6 -1373
  99. package/dist/memory.js.map +1 -1
  100. package/dist/openai.d.ts +11 -102
  101. package/dist/openai.d.ts.map +1 -1
  102. package/dist/openai.js +14 -421
  103. package/dist/openai.js.map +1 -1
  104. package/dist/response-builders.d.ts +1 -11
  105. package/dist/response-builders.d.ts.map +1 -1
  106. package/dist/response-builders.js +2 -38
  107. package/dist/response-builders.js.map +1 -1
  108. package/dist/server/factory.d.ts +17 -0
  109. package/dist/server/factory.d.ts.map +1 -0
  110. package/dist/server/factory.js +279 -0
  111. package/dist/server/factory.js.map +1 -0
  112. package/dist/services/dispatcher/broker.d.ts +83 -0
  113. package/dist/services/dispatcher/broker.d.ts.map +1 -0
  114. package/dist/services/dispatcher/broker.js +175 -0
  115. package/dist/services/dispatcher/broker.js.map +1 -0
  116. package/dist/services/dispatcher/index.d.ts +7 -0
  117. package/dist/services/dispatcher/index.d.ts.map +1 -0
  118. package/dist/services/dispatcher/index.js +7 -0
  119. package/dist/services/dispatcher/index.js.map +1 -0
  120. package/dist/services/dispatcher/lock.d.ts +25 -0
  121. package/dist/services/dispatcher/lock.d.ts.map +1 -0
  122. package/dist/services/dispatcher/lock.js +111 -0
  123. package/dist/services/dispatcher/lock.js.map +1 -0
  124. package/dist/services/dispatcher/poller.d.ts +19 -0
  125. package/dist/services/dispatcher/poller.d.ts.map +1 -0
  126. package/dist/services/dispatcher/poller.js +269 -0
  127. package/dist/services/dispatcher/poller.js.map +1 -0
  128. package/dist/telegram.d.ts +2 -88
  129. package/dist/telegram.d.ts.map +1 -1
  130. package/dist/telegram.js +2 -0
  131. package/dist/telegram.js.map +1 -1
  132. package/dist/tool-definitions.d.ts +1 -14
  133. package/dist/tool-definitions.d.ts.map +1 -1
  134. package/dist/tool-definitions.js +1 -404
  135. package/dist/tool-definitions.js.map +1 -1
  136. package/dist/tools/definitions.d.ts +15 -0
  137. package/dist/tools/definitions.d.ts.map +1 -0
  138. package/dist/tools/definitions.js +404 -0
  139. package/dist/tools/definitions.js.map +1 -0
  140. package/dist/tools/start-session-tool.d.ts.map +1 -1
  141. package/dist/tools/start-session-tool.js +2 -0
  142. package/dist/tools/start-session-tool.js.map +1 -1
  143. package/dist/tools/wait/drive-handler.d.ts +61 -0
  144. package/dist/tools/wait/drive-handler.d.ts.map +1 -0
  145. package/dist/tools/wait/drive-handler.js +138 -0
  146. package/dist/tools/wait/drive-handler.js.map +1 -0
  147. package/dist/tools/wait/index.d.ts +8 -0
  148. package/dist/tools/wait/index.d.ts.map +1 -0
  149. package/dist/tools/wait/index.js +8 -0
  150. package/dist/tools/wait/index.js.map +1 -0
  151. package/dist/tools/wait/media-processor.d.ts +52 -0
  152. package/dist/tools/wait/media-processor.d.ts.map +1 -0
  153. package/dist/tools/wait/media-processor.js +261 -0
  154. package/dist/tools/wait/media-processor.js.map +1 -0
  155. package/dist/tools/wait/message-delivery.d.ts +63 -0
  156. package/dist/tools/wait/message-delivery.d.ts.map +1 -0
  157. package/dist/tools/wait/message-delivery.js +281 -0
  158. package/dist/tools/wait/message-delivery.js.map +1 -0
  159. package/dist/tools/wait/poll-loop.d.ts +72 -0
  160. package/dist/tools/wait/poll-loop.d.ts.map +1 -0
  161. package/dist/tools/wait/poll-loop.js +280 -0
  162. package/dist/tools/wait/poll-loop.js.map +1 -0
  163. package/dist/tools/wait/reaction-handler.d.ts +49 -0
  164. package/dist/tools/wait/reaction-handler.d.ts.map +1 -0
  165. package/dist/tools/wait/reaction-handler.js +126 -0
  166. package/dist/tools/wait/reaction-handler.js.map +1 -0
  167. package/dist/tools/wait/task-handler.d.ts +40 -0
  168. package/dist/tools/wait/task-handler.d.ts.map +1 -0
  169. package/dist/tools/wait/task-handler.js +41 -0
  170. package/dist/tools/wait/task-handler.js.map +1 -0
  171. package/dist/tools/wait-tool.d.ts +3 -69
  172. package/dist/tools/wait-tool.d.ts.map +1 -1
  173. package/dist/tools/wait-tool.js +3 -876
  174. package/dist/tools/wait-tool.js.map +1 -1
  175. package/package.json +1 -1
  176. package/templates/daily-review.default.md +26 -0
  177. package/templates/drive-dispatcher.default.md +2 -0
@@ -1,101 +1,9 @@
1
1
  /**
2
- * Shared Telegram update dispatcher.
2
+ * Shared Telegram update dispatcher — thin re-export façade.
3
3
  *
4
- * Problem: Telegram's getUpdates API is exclusive only one poller per bot
5
- * token. When multiple MCP server instances run concurrently (multiple VS Code
6
- * windows), they fight for the poll lock with 409 Conflict errors and silently
7
- * lose updates meant for other sessions.
8
- *
9
- * Solution: A file-system–based message broker.
10
- *
11
- * 1. One MCP instance becomes the **poller** (elected via a lock file).
12
- * It calls getUpdates and writes incoming messages to per-thread JSON
13
- * files under ~/.remote-copilot-mcp/threads/<threadId>.jsonl.
14
- * 2. All MCP instances (including the poller) **read** from their own
15
- * thread file to retrieve messages. This is contention-free because
16
- * each instance is scoped to its own thread ID.
17
- * 3. The lock file is automatically released if the poller process dies
18
- * (stale-lock detection via PID check). Another instance then takes over.
19
- *
20
- * The dispatcher exports two public functions:
21
- * - startDispatcher(telegram, chatId) — call once on MCP server startup.
22
- * - readThreadMessages(threadId) — non-blocking; returns and clears
23
- * pending messages for a thread.
24
- */
25
- import type { TelegramClient } from "./telegram.js";
26
- export interface StoredReaction {
27
- emoji: string;
28
- messageId: number;
29
- chatId: number;
30
- date: number;
31
- }
32
- /**
33
- * Read and clear the pending reaction (if any).
34
- * Returns null if no reaction is pending.
35
- */
36
- export declare function readPendingReaction(): StoredReaction | null;
37
- export interface StoredMessage {
38
- update_id: number;
39
- message: {
40
- message_id: number;
41
- chat_id: number;
42
- text?: string;
43
- caption?: string;
44
- message_thread_id?: number;
45
- photo?: Array<{
46
- file_id: string;
47
- width: number;
48
- height: number;
49
- }>;
50
- document?: {
51
- file_id: string;
52
- file_name?: string;
53
- mime_type?: string;
54
- };
55
- voice?: {
56
- file_id: string;
57
- duration: number;
58
- mime_type?: string;
59
- };
60
- video_note?: {
61
- file_id: string;
62
- length: number;
63
- duration: number;
64
- };
65
- sticker?: {
66
- file_id: string;
67
- emoji?: string;
68
- set_name?: string;
69
- };
70
- animation?: {
71
- file_id: string;
72
- duration?: number;
73
- thumbnail?: {
74
- file_id: string;
75
- };
76
- };
77
- date: number;
78
- };
79
- }
80
- /**
81
- * Read and clear all pending messages for a thread.
82
- * Uses rename for atomic read-and-clear to prevent message loss.
83
- */
84
- export declare function readThreadMessages(threadId: number | undefined): StoredMessage[];
85
- /**
86
- * Non-destructive peek at pending messages for a thread.
87
- * Unlike readThreadMessages, this does NOT consume the messages — they remain
88
- * in the thread file for the next readThreadMessages call.
89
- */
90
- export declare function peekThreadMessages(threadId: number | undefined): StoredMessage[];
91
- /**
92
- * Start the shared dispatcher.
93
- * - Ensures directories exist.
94
- * - Attempts to acquire the poller lock.
95
- * - If acquired, starts a polling loop that writes to per-thread files.
96
- * - If not acquired, this instance is a consumer only (reads from thread files).
97
- *
98
- * Returns: whether this instance became the poller.
4
+ * The implementation has been decomposed into focused modules under
5
+ * src/services/dispatcher/ (lock, broker, poller). This file preserves
6
+ * the original import paths so existing consumers are unaffected.
99
7
  */
100
- export declare function startDispatcher(telegram: TelegramClient, chatId: string): Promise<boolean>;
8
+ export * from './services/dispatcher/index.js';
101
9
  //# sourceMappingURL=dispatcher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../src/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAcH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAgBpD,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CAChB;AAUD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,GAAG,IAAI,CAQ3D;AA2JD,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,KAAK,CAAC,EAAE,KAAK,CAAC;YACV,OAAO,EAAE,MAAM,CAAC;YAChB,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,EAAE,MAAM,CAAC;SAClB,CAAC,CAAC;QACH,QAAQ,CAAC,EAAE;YACP,OAAO,EAAE,MAAM,CAAC;YAChB,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB,SAAS,CAAC,EAAE,MAAM,CAAC;SACtB,CAAC;QACF,KAAK,CAAC,EAAE;YACJ,OAAO,EAAE,MAAM,CAAC;YAChB,QAAQ,EAAE,MAAM,CAAC;YACjB,SAAS,CAAC,EAAE,MAAM,CAAC;SACtB,CAAC;QACF,UAAU,CAAC,EAAE;YACT,OAAO,EAAE,MAAM,CAAC;YAChB,MAAM,EAAE,MAAM,CAAC;YACf,QAAQ,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,OAAO,CAAC,EAAE;YACN,OAAO,EAAE,MAAM,CAAC;YAChB,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,QAAQ,CAAC,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,SAAS,CAAC,EAAE;YACR,OAAO,EAAE,MAAM,CAAC;YAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,SAAS,CAAC,EAAE;gBACR,OAAO,EAAE,MAAM,CAAC;aACnB,CAAC;SACL,CAAC;QACF,IAAI,EAAE,MAAM,CAAC;KAChB,CAAC;CACL;AA+BD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,EAAE,CAmBhF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,EAAE,CAShF;AA+KD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACjC,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CA+GlB"}
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../src/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,gCAAgC,CAAC"}
@@ -1,529 +1,9 @@
1
1
  /**
2
- * Shared Telegram update dispatcher.
2
+ * Shared Telegram update dispatcher — thin re-export façade.
3
3
  *
4
- * Problem: Telegram's getUpdates API is exclusive only one poller per bot
5
- * token. When multiple MCP server instances run concurrently (multiple VS Code
6
- * windows), they fight for the poll lock with 409 Conflict errors and silently
7
- * lose updates meant for other sessions.
8
- *
9
- * Solution: A file-system–based message broker.
10
- *
11
- * 1. One MCP instance becomes the **poller** (elected via a lock file).
12
- * It calls getUpdates and writes incoming messages to per-thread JSON
13
- * files under ~/.remote-copilot-mcp/threads/<threadId>.jsonl.
14
- * 2. All MCP instances (including the poller) **read** from their own
15
- * thread file to retrieve messages. This is contention-free because
16
- * each instance is scoped to its own thread ID.
17
- * 3. The lock file is automatically released if the poller process dies
18
- * (stale-lock detection via PID check). Another instance then takes over.
19
- *
20
- * The dispatcher exports two public functions:
21
- * - startDispatcher(telegram, chatId) — call once on MCP server startup.
22
- * - readThreadMessages(threadId) — non-blocking; returns and clears
23
- * pending messages for a thread.
24
- */
25
- import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, unlinkSync, writeFileSync } from "fs";
26
- import { homedir } from "os";
27
- import { join } from "path";
28
- import { log } from "./logger.js";
29
- import { errorMessage } from "./utils.js";
30
- // ---------------------------------------------------------------------------
31
- // Paths
32
- // ---------------------------------------------------------------------------
33
- const BASE_DIR = join(homedir(), ".remote-copilot-mcp");
34
- const THREADS_DIR = join(BASE_DIR, "threads");
35
- const LOCK_FILE = join(BASE_DIR, "poller.lock");
36
- const OFFSET_FILE = join(BASE_DIR, "offset");
37
- const REACTION_FILE = join(BASE_DIR, "pending_reaction.json");
38
- function writeReactionFile(reaction) {
39
- try {
40
- writeFileSync(REACTION_FILE, JSON.stringify(reaction), "utf8");
41
- }
42
- catch { /* non-fatal */ }
43
- }
44
- /**
45
- * Read and clear the pending reaction (if any).
46
- * Returns null if no reaction is pending.
47
- */
48
- export function readPendingReaction() {
49
- try {
50
- const raw = readFileSync(REACTION_FILE, "utf8");
51
- unlinkSync(REACTION_FILE);
52
- return JSON.parse(raw);
53
- }
54
- catch {
55
- return null;
56
- }
57
- }
58
- function ensureDirs() {
59
- mkdirSync(THREADS_DIR, { recursive: true });
60
- recoverOrphanedReads();
61
- }
62
- /**
63
- * On startup, scan for orphaned `.reading.PID` files left by hard-crashed
64
- * processes and append their content back to the original thread file
65
- * so those messages aren't permanently lost.
66
- */
67
- function recoverOrphanedReads() {
68
- try {
69
- const files = readdirSync(THREADS_DIR);
70
- for (const f of files) {
71
- const match = f.match(/^(.+)\.reading\.(\d+)$/);
72
- if (match) {
73
- const pid = Number.parseInt(match[2], 10);
74
- if (!isPidAlive(pid)) {
75
- const orphan = join(THREADS_DIR, f);
76
- const original = join(THREADS_DIR, match[1]);
77
- try {
78
- const content = readFileSync(orphan, "utf8");
79
- writeFileSync(original, content, { flag: "a", encoding: "utf8" });
80
- unlinkSync(orphan);
81
- log.info(`[dispatcher] Recovered orphaned file: ${f}`);
82
- }
83
- catch { /* best effort */ }
84
- }
85
- }
86
- }
87
- }
88
- catch { /* non-fatal */ }
89
- }
90
- // ---------------------------------------------------------------------------
91
- // Lock helpers
92
- // ---------------------------------------------------------------------------
93
- function readLock() {
94
- try {
95
- const raw = readFileSync(LOCK_FILE, "utf8");
96
- const parsed = JSON.parse(raw);
97
- if (typeof parsed.pid === "number" && typeof parsed.ts === "number") {
98
- return parsed;
99
- }
100
- return null;
101
- }
102
- catch {
103
- return null;
104
- }
105
- }
106
- /**
107
- * Write (refresh) the lock file, but only if we still own it.
108
- * Prevents a TOCTOU race where two pollers run simultaneously:
109
- * if another process stole the lock between our check and write,
110
- * we must not overwrite their lock.
111
- *
112
- * Returns true if the lock was refreshed, false if we lost ownership.
113
- */
114
- function refreshLock() {
115
- const current = readLock();
116
- if (current && current.pid !== process.pid) {
117
- return false; // Someone else owns the lock now.
118
- }
119
- writeFileSync(LOCK_FILE, JSON.stringify({ pid: process.pid, ts: Date.now() }), "utf8");
120
- return true;
121
- }
122
- function removeLock() {
123
- try {
124
- unlinkSync(LOCK_FILE);
125
- }
126
- catch {
127
- // Already gone.
128
- }
129
- }
130
- /** Check whether a PID is still alive. */
131
- function isPidAlive(pid) {
132
- try {
133
- process.kill(pid, 0); // Signal 0 = existence check, does not kill.
134
- return true;
135
- }
136
- catch {
137
- return false;
138
- }
139
- }
140
- /**
141
- * Try to become the poller using exclusive file creation to prevent TOCTOU races.
142
- * - If no lock file exists → atomically create it (flag: "wx").
143
- * - If lock file exists but the PID is dead → remove and retry.
144
- * - If lock file exists, PID is alive, but lock is stale → remove and retry.
145
- * - Otherwise → someone else is the poller.
146
- */
147
- const STALE_LOCK_MS = 90 * 1000; // 90 seconds
148
- function tryAcquireLock() {
149
- const existing = readLock();
150
- if (existing) {
151
- const alive = isPidAlive(existing.pid);
152
- const stale = Date.now() - existing.ts > STALE_LOCK_MS;
153
- if (alive && !stale) {
154
- return false; // Someone else is actively polling.
155
- }
156
- // Dead or stale — remove before attempting exclusive create.
157
- try {
158
- unlinkSync(LOCK_FILE);
159
- }
160
- catch { /* race-ok */ }
161
- }
162
- else if (existsSync(LOCK_FILE)) {
163
- // Lock file exists but is corrupt/empty (readLock returned null).
164
- // Remove it so the exclusive create below can succeed.
165
- try {
166
- unlinkSync(LOCK_FILE);
167
- }
168
- catch { /* race-ok */ }
169
- }
170
- // Atomic exclusive create: fails if another process created first.
171
- try {
172
- writeFileSync(LOCK_FILE, JSON.stringify({ pid: process.pid, ts: Date.now() }), { encoding: "utf8", flag: "wx" });
173
- return true;
174
- }
175
- catch {
176
- return false; // Another process won the race.
177
- }
178
- }
179
- // ---------------------------------------------------------------------------
180
- // Offset persistence (shared across all instances)
181
- // ---------------------------------------------------------------------------
182
- function readOffset() {
183
- try {
184
- const raw = readFileSync(OFFSET_FILE, "utf8").trim();
185
- const n = Number(raw);
186
- return Number.isFinite(n) ? n : 0;
187
- }
188
- catch {
189
- return 0;
190
- }
191
- }
192
- function writeOffset(offset) {
193
- try {
194
- const tmp = OFFSET_FILE + `.tmp.${process.pid}`;
195
- writeFileSync(tmp, String(offset), "utf8");
196
- renameSync(tmp, OFFSET_FILE); // atomic replace
197
- }
198
- catch {
199
- // Non-fatal.
200
- }
201
- }
202
- function threadFilePath(threadId) {
203
- return join(THREADS_DIR, `${threadId}.jsonl`);
204
- }
205
- /** Parse JSONL content into StoredMessage[], skipping corrupt lines. */
206
- function parseJsonlLines(raw, label) {
207
- if (!raw)
208
- return [];
209
- const results = [];
210
- for (const line of raw.split("\n")) {
211
- if (!line.trim())
212
- continue;
213
- try {
214
- results.push(JSON.parse(line));
215
- }
216
- catch {
217
- log.warn(`[dispatcher] Skipping corrupt JSONL line in ${label}`);
218
- }
219
- }
220
- return results;
221
- }
222
- /**
223
- * Append a message to a thread's JSONL file.
224
- * Throws on write failure so the caller can track which messages were persisted.
225
- */
226
- function appendToThread(threadId, msg) {
227
- const file = threadFilePath(threadId);
228
- const line = JSON.stringify(msg) + "\n";
229
- writeFileSync(file, line, { flag: "a", encoding: "utf8" });
230
- }
231
- /**
232
- * Read and clear all pending messages for a thread.
233
- * Uses rename for atomic read-and-clear to prevent message loss.
234
- */
235
- export function readThreadMessages(threadId) {
236
- const key = threadId ?? "general";
237
- const file = threadFilePath(key);
238
- const tmp = file + ".reading." + process.pid;
239
- try {
240
- renameSync(file, tmp);
241
- }
242
- catch {
243
- return [];
244
- }
245
- try {
246
- const raw = readFileSync(tmp, "utf8").trim();
247
- const messages = parseJsonlLines(raw, `${key}.jsonl`);
248
- try {
249
- unlinkSync(tmp);
250
- }
251
- catch { /* already gone */ }
252
- return messages;
253
- }
254
- catch {
255
- // Read failed — restore the original file to prevent message loss
256
- try {
257
- renameSync(tmp, file);
258
- }
259
- catch { /* best effort */ }
260
- return [];
261
- }
262
- }
263
- /**
264
- * Non-destructive peek at pending messages for a thread.
265
- * Unlike readThreadMessages, this does NOT consume the messages — they remain
266
- * in the thread file for the next readThreadMessages call.
267
- */
268
- export function peekThreadMessages(threadId) {
269
- const key = threadId ?? "general";
270
- const file = threadFilePath(key);
271
- try {
272
- const raw = readFileSync(file, "utf8").trim();
273
- return parseJsonlLines(raw, `${key}.jsonl`);
274
- }
275
- catch {
276
- return [];
277
- }
278
- }
279
- // ---------------------------------------------------------------------------
280
- // Poller loop
281
- // ---------------------------------------------------------------------------
282
- let pollerRunning = false;
283
- let pollAbortController;
284
- async function pollOnce(telegram, chatId) {
285
- if (!refreshLock()) {
286
- // We lost lock ownership — another process took over. Step down.
287
- pollerRunning = false;
288
- return;
289
- }
290
- const POLL_TIMEOUT_SECONDS = 10;
291
- let offset = readOffset();
292
- // Refresh the lock periodically during long polls / 409 retries
293
- // to prevent it from going stale (STALE_LOCK_MS = 90 s).
294
- const lockRefresher = setInterval(() => {
295
- if (!refreshLock()) {
296
- pollerRunning = false;
297
- pollAbortController?.abort();
298
- }
299
- }, 15_000);
300
- try {
301
- pollAbortController = new AbortController();
302
- const updates = await telegram.getUpdates(offset, POLL_TIMEOUT_SECONDS, pollAbortController.signal);
303
- // Refresh again after the (potentially 10-second) long poll returns.
304
- if (!refreshLock()) {
305
- pollerRunning = false;
306
- return;
307
- }
308
- if (updates.length === 0)
309
- return;
310
- // Track the highest offset for which ALL messages were successfully written.
311
- let committedOffset = offset;
312
- let allSucceeded = true;
313
- for (const u of updates) {
314
- // ── Reaction updates ──────────────────────────────────────
315
- if (u.message_reaction) {
316
- const emoji = u.message_reaction.new_reaction.find((r) => r.type === "emoji")?.emoji;
317
- if (emoji) {
318
- const reaction = {
319
- emoji,
320
- messageId: u.message_reaction.message_id,
321
- chatId: u.message_reaction.chat.id,
322
- date: u.message_reaction.date,
323
- };
324
- telegram.lastReaction = {
325
- emoji,
326
- messageId: u.message_reaction.message_id,
327
- date: u.message_reaction.date,
328
- };
329
- writeReactionFile(reaction);
330
- log.info(`[dispatcher] Reaction ${emoji} on message ${u.message_reaction.message_id}`);
331
- }
332
- committedOffset = u.update_id + 1;
333
- continue;
334
- }
335
- if (!u.message) {
336
- // Non-message update — skip but still advance past it.
337
- committedOffset = u.update_id + 1;
338
- continue;
339
- }
340
- if (String(u.message.chat.id) !== chatId) {
341
- committedOffset = u.update_id + 1;
342
- continue;
343
- }
344
- // Skip Telegram service messages (forum_topic_created, pinned_message,
345
- // new_chat_members, etc.) — they have no user content and would be
346
- // delivered as "unsupported message type" to the agent.
347
- const m = u.message;
348
- const hasContent = m.text || m.caption || m.photo || m.document || m.voice || m.video_note || m.sticker || m.animation;
349
- if (!hasContent) {
350
- committedOffset = u.update_id + 1;
351
- continue;
352
- }
353
- const threadId = u.message.message_thread_id ?? "general";
354
- const stored = {
355
- update_id: u.update_id,
356
- message: {
357
- message_id: u.message.message_id,
358
- chat_id: u.message.chat.id,
359
- text: u.message.text,
360
- caption: u.message.caption,
361
- message_thread_id: u.message.message_thread_id,
362
- photo: u.message.photo?.map((p) => ({
363
- file_id: p.file_id,
364
- width: p.width,
365
- height: p.height,
366
- })),
367
- document: u.message.document ? {
368
- file_id: u.message.document.file_id,
369
- file_name: u.message.document.file_name,
370
- mime_type: u.message.document.mime_type,
371
- } : undefined,
372
- voice: u.message.voice ? {
373
- file_id: u.message.voice.file_id,
374
- duration: u.message.voice.duration,
375
- mime_type: u.message.voice.mime_type,
376
- } : undefined,
377
- video_note: u.message.video_note ? {
378
- file_id: u.message.video_note.file_id,
379
- length: u.message.video_note.length,
380
- duration: u.message.video_note.duration,
381
- } : undefined,
382
- sticker: u.message.sticker ? {
383
- file_id: u.message.sticker.file_id,
384
- emoji: u.message.sticker.emoji,
385
- set_name: u.message.sticker.set_name,
386
- } : undefined,
387
- animation: u.message.animation ? {
388
- file_id: u.message.animation.file_id,
389
- duration: u.message.animation.duration,
390
- thumbnail: (u.message.animation.thumbnail ?? u.message.animation.thumb)
391
- ? { file_id: (u.message.animation.thumbnail ?? u.message.animation.thumb).file_id }
392
- : undefined,
393
- } : undefined,
394
- date: u.message.date,
395
- },
396
- };
397
- try {
398
- appendToThread(threadId, stored);
399
- committedOffset = u.update_id + 1;
400
- }
401
- catch (writeErr) {
402
- log.error(`[dispatcher] Failed to write message ${u.update_id} to thread ${threadId}: ${errorMessage(writeErr)}`);
403
- allSucceeded = false;
404
- break; // Stop processing — don't skip messages.
405
- }
406
- }
407
- // Only advance offset to the last successfully written message.
408
- if (committedOffset > offset) {
409
- writeOffset(committedOffset);
410
- }
411
- if (!allSucceeded) {
412
- log.warn("[dispatcher] Partial batch write. Will retry remaining messages on next poll.");
413
- }
414
- }
415
- catch (err) {
416
- // Ignore abort errors during shutdown.
417
- if (err instanceof DOMException && err.name === "AbortError")
418
- return;
419
- log.error(`[dispatcher] Poll error: ${errorMessage(err)}`);
420
- }
421
- finally {
422
- clearInterval(lockRefresher);
423
- }
424
- }
425
- /**
426
- * Start the shared dispatcher.
427
- * - Ensures directories exist.
428
- * - Attempts to acquire the poller lock.
429
- * - If acquired, starts a polling loop that writes to per-thread files.
430
- * - If not acquired, this instance is a consumer only (reads from thread files).
431
- *
432
- * Returns: whether this instance became the poller.
4
+ * The implementation has been decomposed into focused modules under
5
+ * src/services/dispatcher/ (lock, broker, poller). This file preserves
6
+ * the original import paths so existing consumers are unaffected.
433
7
  */
434
- export async function startDispatcher(telegram, chatId) {
435
- ensureDirs();
436
- const isPoller = tryAcquireLock();
437
- const CONSUMER_RETRY_MS = 10_000;
438
- // Shared cleanup + loop helpers.
439
- let cleanupRegistered = false;
440
- const registerCleanup = () => {
441
- if (cleanupRegistered)
442
- return;
443
- cleanupRegistered = true;
444
- const cleanup = () => {
445
- pollerRunning = false;
446
- pollAbortController?.abort();
447
- removeLock();
448
- };
449
- process.on("exit", cleanup);
450
- process.on("SIGINT", () => { cleanup(); process.exit(0); });
451
- process.on("SIGTERM", () => { cleanup(); process.exit(0); });
452
- };
453
- const installConsumerRetry = () => {
454
- const timer = setInterval(() => {
455
- if (tryAcquireLock()) {
456
- clearInterval(timer);
457
- log.info("[dispatcher] Promoted to poller (previous poller seems inactive).");
458
- pollerRunning = true;
459
- startLoop();
460
- registerCleanup();
461
- }
462
- }, CONSUMER_RETRY_MS);
463
- timer.unref();
464
- };
465
- const startLoop = () => {
466
- const loop = async () => {
467
- while (pollerRunning) {
468
- const currentLock = readLock();
469
- if (currentLock && currentLock.pid !== process.pid) {
470
- log.info(`[dispatcher] Lock taken by PID ${currentLock.pid}. Stepping down to consumer.`);
471
- pollerRunning = false;
472
- installConsumerRetry();
473
- break;
474
- }
475
- try {
476
- await pollOnce(telegram, chatId);
477
- }
478
- catch (err) {
479
- log.error(`[dispatcher] Unexpected poll error: ${errorMessage(err)}`);
480
- await new Promise((r) => setTimeout(r, 5000));
481
- }
482
- await new Promise((r) => setTimeout(r, 500));
483
- }
484
- };
485
- void loop();
486
- };
487
- if (isPoller) {
488
- log.info("[dispatcher] This instance is the poller.");
489
- // On first run with no offset file, skip all old updates in one call
490
- // by fetching the latest update_id and setting the offset past it.
491
- // Awaited so the poll loop never sees offset=0.
492
- if (!existsSync(OFFSET_FILE)) {
493
- log.info("[dispatcher] No offset file. Skipping old updates...\n");
494
- try {
495
- // Use a short timeout to prevent blocking startup if another
496
- // poller is active (409 retry loop could stall for 60+ seconds).
497
- const drainAbort = new AbortController();
498
- const drainTimeout = setTimeout(() => drainAbort.abort(), 10_000);
499
- const latest = await telegram.getUpdates(-1, 0, drainAbort.signal);
500
- clearTimeout(drainTimeout);
501
- if (latest.length > 0) {
502
- const skipTo = latest[latest.length - 1].update_id + 1;
503
- writeOffset(skipTo);
504
- log.info(`[dispatcher] Skipped to offset ${skipTo}.`);
505
- }
506
- else {
507
- writeOffset(0);
508
- }
509
- }
510
- catch (err) {
511
- // Don't write offset=0 — leave it at whatever the current value is.
512
- // If the file still doesn't exist, readOffset() returns 0 which is
513
- // acceptable because the drain simply failed to optimise.
514
- log.warn(`[dispatcher] Warning: drain failed: ${errorMessage(err)}. Poll loop will start from offset 0.`);
515
- }
516
- }
517
- pollerRunning = true;
518
- startLoop();
519
- registerCleanup();
520
- }
521
- else {
522
- log.info("[dispatcher] Another instance is the poller. This instance is a consumer only.");
523
- // Periodically try to become the poller in case the current one dies
524
- // but its PID remains alive (zombie process, stuck socket, etc.).
525
- installConsumerRetry();
526
- }
527
- return isPoller;
528
- }
8
+ export * from './services/dispatcher/index.js';
529
9
  //# sourceMappingURL=dispatcher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../src/dispatcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../src/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,gCAAgC,CAAC"}