crewly 1.20.169 → 1.20.170

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 (106) hide show
  1. package/config/skills/agent/core/reply/SKILL.md +71 -0
  2. package/config/skills/agent/core/reply/execute.sh +81 -0
  3. package/config/skills/agent/core/reply/execute.test.sh +87 -0
  4. package/dist/backend/backend/src/constants.d.ts +62 -0
  5. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  6. package/dist/backend/backend/src/constants.js +68 -0
  7. package/dist/backend/backend/src/constants.js.map +1 -1
  8. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts +36 -0
  9. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts.map +1 -0
  10. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js +182 -0
  11. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js.map +1 -0
  12. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts +30 -0
  13. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  14. package/dist/backend/backend/src/controllers/chat/chat.controller.js +171 -0
  15. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  16. package/dist/backend/backend/src/controllers/chat/chat.routes.d.ts.map +1 -1
  17. package/dist/backend/backend/src/controllers/chat/chat.routes.js +4 -0
  18. package/dist/backend/backend/src/controllers/chat/chat.routes.js.map +1 -1
  19. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts +55 -0
  20. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  21. package/dist/backend/backend/src/controllers/slack/slack.controller.js +1 -1
  22. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  23. package/dist/backend/backend/src/index.d.ts +10 -0
  24. package/dist/backend/backend/src/index.d.ts.map +1 -1
  25. package/dist/backend/backend/src/index.js +114 -1
  26. package/dist/backend/backend/src/index.js.map +1 -1
  27. package/dist/backend/backend/src/routes/modules/system.routes.d.ts.map +1 -1
  28. package/dist/backend/backend/src/routes/modules/system.routes.js +6 -0
  29. package/dist/backend/backend/src/routes/modules/system.routes.js.map +1 -1
  30. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +18 -0
  31. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  32. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +48 -3
  33. package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  34. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts +271 -0
  35. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -0
  36. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js +605 -0
  37. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -0
  38. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts +179 -0
  39. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts.map +1 -0
  40. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js +327 -0
  41. package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js.map +1 -0
  42. package/dist/backend/backend/src/services/orc/agent-reply-target.d.ts +95 -0
  43. package/dist/backend/backend/src/services/orc/agent-reply-target.d.ts.map +1 -0
  44. package/dist/backend/backend/src/services/orc/agent-reply-target.js +85 -0
  45. package/dist/backend/backend/src/services/orc/agent-reply-target.js.map +1 -0
  46. package/dist/backend/backend/src/services/orc/orc-reply-route.service.d.ts +20 -0
  47. package/dist/backend/backend/src/services/orc/orc-reply-route.service.d.ts.map +1 -1
  48. package/dist/backend/backend/src/services/orc/orc-reply-route.service.js +34 -1
  49. package/dist/backend/backend/src/services/orc/orc-reply-route.service.js.map +1 -1
  50. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  51. package/dist/backend/backend/src/services/slack/slack-initializer.js +5 -0
  52. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  53. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +13 -0
  54. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  55. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +40 -0
  56. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  57. package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  58. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +2 -0
  59. package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  60. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +33 -0
  61. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  62. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +68 -0
  63. package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  64. package/dist/backend/backend/src/services/slack/slack.service.d.ts +16 -0
  65. package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
  66. package/dist/backend/backend/src/services/slack/slack.service.js +22 -5
  67. package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
  68. package/dist/backend/backend/src/types/slack.types.d.ts +6 -0
  69. package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
  70. package/dist/backend/backend/src/types/slack.types.js.map +1 -1
  71. package/dist/backend/build-info.json +2 -2
  72. package/dist/cli/backend/src/constants.d.ts +62 -0
  73. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  74. package/dist/cli/backend/src/constants.js +68 -0
  75. package/dist/cli/backend/src/constants.js.map +1 -1
  76. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +18 -0
  77. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
  78. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +48 -3
  79. package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
  80. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts +271 -0
  81. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -0
  82. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js +605 -0
  83. package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -0
  84. package/dist/cli/backend/src/services/orc/orc-reply-route.service.d.ts +20 -0
  85. package/dist/cli/backend/src/services/orc/orc-reply-route.service.d.ts.map +1 -1
  86. package/dist/cli/backend/src/services/orc/orc-reply-route.service.js +34 -1
  87. package/dist/cli/backend/src/services/orc/orc-reply-route.service.js.map +1 -1
  88. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts +13 -0
  89. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  90. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +40 -0
  91. package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  92. package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
  93. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +2 -0
  94. package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
  95. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +33 -0
  96. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
  97. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +68 -0
  98. package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
  99. package/dist/cli/backend/src/services/slack/slack.service.d.ts +16 -0
  100. package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -1
  101. package/dist/cli/backend/src/services/slack/slack.service.js +22 -5
  102. package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -1
  103. package/dist/cli/backend/src/types/slack.types.d.ts +6 -0
  104. package/dist/cli/backend/src/types/slack.types.d.ts.map +1 -1
  105. package/dist/cli/backend/src/types/slack.types.js.map +1 -1
  106. package/package.json +1 -1
@@ -0,0 +1,605 @@
1
+ /**
2
+ * Unanswered-owner-message watchdog.
3
+ *
4
+ * Every owner message delivered to an agent on this machine ends in either an
5
+ * answer the owner can see, or ONE plain-words note in the same thread saying
6
+ * who it is waiting on and why. Four different bugs on 2026-09-30 each lost an
7
+ * owner message silently; each was fixed on its own, but nothing guaranteed
8
+ * the end-to-end property. This does.
9
+ *
10
+ * Timeline per message (constants in OWNER_MESSAGE_WATCHDOG_CONSTANTS):
11
+ * - an answer (or a settled placeholder, or `reply --none`) clears it;
12
+ * - a placeholder showing while the agent is mid-turn extends the wait, up
13
+ * to BUSY_EXTEND_CAP_MS, then a note;
14
+ * - T1 → one re-delivery ("nudge") to the responsible agent, waking it;
15
+ * an agent that cannot be reached skips straight to the note;
16
+ * - T2 → one note, and the message is no longer tracked.
17
+ *
18
+ * The service is transport-agnostic: what counts as "delivered", "answered",
19
+ * "busy" and how to nudge / post a note are injected (see the wiring module).
20
+ *
21
+ * @module services/messaging/owner-message-watchdog.service
22
+ * @see specs/2026-09-30-owner-message-guarantee.md
23
+ */
24
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'fs';
25
+ import * as path from 'path';
26
+ import { OWNER_MESSAGE_WATCHDOG_CONSTANTS as C } from '../../constants.js';
27
+ import { LoggerService } from '../core/logger.service.js';
28
+ /**
29
+ * Whether a whole message is a bare acknowledgement ("好", "ok", "👍", "谢谢")
30
+ * that needs no answer.
31
+ *
32
+ * @param text - The owner's message
33
+ * @returns True for an acknowledgement from ACK_WORDS
34
+ */
35
+ export function isAcknowledgement(text) {
36
+ const normalised = (text ?? '')
37
+ .toLowerCase()
38
+ .replace(/[\s。,,.!!??~~、;;::"'“”‘’()()\[\]【】-]+/g, '')
39
+ .trim();
40
+ if (!normalised)
41
+ return true;
42
+ return C.ACK_WORDS.some((w) => w.replace(/\s+/g, '') === normalised);
43
+ }
44
+ /**
45
+ * The dedupe key of a message.
46
+ *
47
+ * @param input - Track input (or entry)
48
+ * @returns `slack:<channel>:<ts>` / `chat:<channel>:<messageId>`, or null when underspecified
49
+ */
50
+ export function ownerMessageKey(input) {
51
+ if (input.surface === 'slack') {
52
+ const ts = input.sourceTs ?? input.threadTs;
53
+ return input.slackChannelId && ts ? `slack:${input.slackChannelId}:${ts}` : null;
54
+ }
55
+ return input.chatChannelId && input.messageId ? `chat:${input.chatChannelId}:${input.messageId}` : null;
56
+ }
57
+ /**
58
+ * Tracks owner messages until they are answered, nudging and then noting.
59
+ */
60
+ export class OwnerMessageWatchdogService {
61
+ deps;
62
+ logger;
63
+ entries = new Map();
64
+ /** Recently finished keys, oldest first (Map keeps insertion order). */
65
+ resolved = new Map();
66
+ /** Thread → when an answer was last seen there (answers can beat the tracking call). */
67
+ recentAnswers = new Map();
68
+ timer = null;
69
+ ticking = false;
70
+ /**
71
+ * @param deps - Injected behaviour (see {@link OwnerMessageWatchdogDeps})
72
+ */
73
+ constructor(deps) {
74
+ this.deps = deps;
75
+ this.logger = LoggerService.getInstance().createComponentLogger('OwnerMessageWatchdog');
76
+ this.load();
77
+ }
78
+ now() {
79
+ return this.deps.now ? this.deps.now() : Date.now();
80
+ }
81
+ /** Start the periodic evaluation. */
82
+ start() {
83
+ if (this.timer)
84
+ return;
85
+ this.timer = setInterval(() => void this.tick(), C.TICK_MS);
86
+ if (typeof this.timer.unref === 'function')
87
+ this.timer.unref();
88
+ }
89
+ /** Stop the periodic evaluation. */
90
+ stop() {
91
+ if (this.timer)
92
+ clearInterval(this.timer);
93
+ this.timer = null;
94
+ }
95
+ // -------------------------------------------------------------------------
96
+ // Inbound
97
+ // -------------------------------------------------------------------------
98
+ /**
99
+ * Start watching an owner message that was delivered to at least one agent.
100
+ * A second delivery of the same message (a hand-off, a re-dispatch) updates
101
+ * the entry rather than adding one; a message already answered is ignored.
102
+ *
103
+ * @param input - The message and who holds it
104
+ * @returns The entry, or null when it is not tracked (ack, answered, underspecified)
105
+ */
106
+ track(input) {
107
+ const key = ownerMessageKey(input);
108
+ if (!key)
109
+ return null;
110
+ if (!input.responsible)
111
+ return null;
112
+ if (isAcknowledgement(input.text)) {
113
+ this.logger.debug('Owner acknowledgement — no answer owed', { key });
114
+ return null;
115
+ }
116
+ if (this.resolved.has(key))
117
+ return null;
118
+ const existing = this.entries.get(key);
119
+ const receivedAt = input.receivedAt ?? this.now();
120
+ if (!existing) {
121
+ const answeredAt = this.recentAnswers.get(threadKeyOf(input));
122
+ if (answeredAt !== undefined && answeredAt >= receivedAt) {
123
+ this.logger.debug('Owner message already answered before it was tracked', { key });
124
+ this.remember(key);
125
+ return null;
126
+ }
127
+ }
128
+ if (existing) {
129
+ existing.recipients = [...new Set([...existing.recipients, ...input.recipients, input.responsible])];
130
+ // A hand-off names the agent that now owns it.
131
+ if (input.required || !existing.required)
132
+ existing.responsible = input.responsible;
133
+ existing.required = existing.required || input.required;
134
+ if (!existing.chatChannelId && input.chatChannelId)
135
+ existing.chatChannelId = input.chatChannelId;
136
+ if (!existing.chatThreadId && input.chatThreadId)
137
+ existing.chatThreadId = input.chatThreadId;
138
+ this.persist();
139
+ return existing;
140
+ }
141
+ const entry = {
142
+ key,
143
+ surface: input.surface,
144
+ ...(input.slackChannelId ? { slackChannelId: input.slackChannelId } : {}),
145
+ ...(input.threadTs ? { threadTs: input.threadTs } : {}),
146
+ ...(input.sourceTs ? { sourceTs: input.sourceTs } : {}),
147
+ ...(input.chatChannelId ? { chatChannelId: input.chatChannelId } : {}),
148
+ ...(input.chatThreadId ? { chatThreadId: input.chatThreadId } : {}),
149
+ ...(input.messageId ? { messageId: input.messageId } : {}),
150
+ responsible: input.responsible,
151
+ recipients: [...new Set([...input.recipients, input.responsible])],
152
+ required: input.required,
153
+ preview: clip(input.text),
154
+ receivedAt,
155
+ stage: 'waiting',
156
+ };
157
+ this.entries.set(key, entry);
158
+ if (this.entries.size > C.MAX_ENTRIES) {
159
+ const oldest = this.entries.keys().next().value;
160
+ if (oldest !== undefined) {
161
+ this.logger.warn('Owner message watchdog is full — dropping the oldest tracked message', { key: oldest });
162
+ this.entries.delete(oldest);
163
+ }
164
+ }
165
+ this.persist();
166
+ this.logger.info('Tracking owner message until it is answered', {
167
+ key,
168
+ surface: entry.surface,
169
+ responsible: entry.responsible,
170
+ recipients: entry.recipients,
171
+ required: entry.required,
172
+ });
173
+ return entry;
174
+ }
175
+ // -------------------------------------------------------------------------
176
+ // Answers
177
+ // -------------------------------------------------------------------------
178
+ /**
179
+ * Something the owner can see was posted in a Slack thread (an answer, a
180
+ * file, a settled placeholder, a colleague on another machine).
181
+ *
182
+ * @param slackChannelId - Slack channel / DM
183
+ * @param threadTs - Thread root (undefined = top level: clears nothing)
184
+ * @param why - For the log
185
+ * @returns How many entries were cleared
186
+ */
187
+ noteSlackAnswer(slackChannelId, threadTs, why) {
188
+ if (!threadTs)
189
+ return 0;
190
+ this.noteRecentAnswer(`slack:${slackChannelId}:${threadTs}`);
191
+ let n = 0;
192
+ for (const entry of [...this.entries.values()]) {
193
+ if (entry.surface !== 'slack' || entry.slackChannelId !== slackChannelId)
194
+ continue;
195
+ if ((entry.threadTs ?? entry.sourceTs) !== threadTs)
196
+ continue;
197
+ this.finish(entry, `answered (${why})`);
198
+ n += 1;
199
+ }
200
+ return n;
201
+ }
202
+ /**
203
+ * An agent (or the orchestrator) spoke in a Crewly chat channel.
204
+ *
205
+ * @param chatChannelId - chat-v2 channel
206
+ * @param threadId - Thread of the turn (null/undefined = top level)
207
+ * @param interim - An interim note: shown, but the answer is still owed
208
+ * @returns How many entries were cleared
209
+ */
210
+ noteChatAnswer(chatChannelId, threadId, interim) {
211
+ if (!interim)
212
+ this.noteRecentAnswer(`chat:${chatChannelId}:${threadId ?? ''}`);
213
+ let n = 0;
214
+ for (const entry of [...this.entries.values()]) {
215
+ if (entry.surface !== 'chat' || entry.chatChannelId !== chatChannelId)
216
+ continue;
217
+ // A huddle answer belongs in the message's thread; a DM has one conversation.
218
+ if (entry.chatThreadId && threadId !== entry.chatThreadId)
219
+ continue;
220
+ if (interim) {
221
+ entry.interimAt = this.now();
222
+ this.persist();
223
+ continue;
224
+ }
225
+ this.finish(entry, 'answered (chat)');
226
+ n += 1;
227
+ }
228
+ return n;
229
+ }
230
+ /**
231
+ * The responsible agent said no answer is needed (`reply --none`) for what
232
+ * it was asked in this conversation.
233
+ *
234
+ * @param agentSession - The agent
235
+ * @param where - Conversation (and thread) of its turn origin
236
+ * @returns How many entries were closed
237
+ */
238
+ closeByAgent(agentSession, where) {
239
+ let n = 0;
240
+ // Only the agent that must answer can waive the answer: a colleague that
241
+ // was merely told about the message saying "not for me" settles nothing.
242
+ for (const entry of this.owedBy(agentSession).filter((e) => e.responsible === agentSession)) {
243
+ const sameChat = where.chatChannelId && entry.chatChannelId === where.chatChannelId;
244
+ const sameSlack = where.slackChannelId &&
245
+ entry.slackChannelId === where.slackChannelId &&
246
+ (!where.threadTs || (entry.threadTs ?? entry.sourceTs) === where.threadTs);
247
+ if (!sameChat && !sameSlack)
248
+ continue;
249
+ this.finish(entry, `closed by ${agentSession}: no answer needed`);
250
+ n += 1;
251
+ }
252
+ return n;
253
+ }
254
+ /**
255
+ * An agent's working status changed. After a nudge, an optional-only
256
+ * message whose agent then finished a whole turn without answering is
257
+ * that agent's judgement ("not for me") — closed quietly at the next tick.
258
+ *
259
+ * @param agentSession - The agent
260
+ * @param busy - True when a turn started, false when it ended
261
+ */
262
+ noteAgentTurn(agentSession, busy) {
263
+ for (const entry of this.entries.values()) {
264
+ if (entry.stage !== 'nudged' || entry.responsible !== agentSession)
265
+ continue;
266
+ if (busy)
267
+ entry.busyAfterNudge = true;
268
+ else if (entry.busyAfterNudge)
269
+ entry.turnDoneAfterNudge = true;
270
+ }
271
+ }
272
+ /**
273
+ * Open messages an agent holds (responsible or recipient), oldest first.
274
+ *
275
+ * @param agentSession - The agent
276
+ * @returns Entries
277
+ */
278
+ owedBy(agentSession) {
279
+ return [...this.entries.values()]
280
+ .filter((e) => e.responsible === agentSession || e.recipients.includes(agentSession))
281
+ .sort((a, b) => a.receivedAt - b.receivedAt);
282
+ }
283
+ /**
284
+ * Debug listing of what is still waiting.
285
+ *
286
+ * @returns One row per tracked message, oldest first
287
+ */
288
+ list() {
289
+ const now = this.now();
290
+ return [...this.entries.values()]
291
+ .sort((a, b) => a.receivedAt - b.receivedAt)
292
+ .map((e) => ({
293
+ key: e.key,
294
+ surface: e.surface,
295
+ where: e.surface === 'slack'
296
+ ? `${e.slackChannelId}:${e.threadTs ?? e.sourceTs ?? ''}`
297
+ : `${e.chatChannelId}${e.chatThreadId ? `#${e.chatThreadId}` : ''}`,
298
+ responsible: e.responsible,
299
+ recipients: e.recipients,
300
+ required: e.required,
301
+ ageMinutes: Math.floor((now - e.receivedAt) / 60000),
302
+ stage: e.stage,
303
+ ...(e.nudgedAt !== undefined ? { nudgedMinutesAgo: Math.floor((now - e.nudgedAt) / 60000) } : {}),
304
+ ...(e.nudgeBlocked ? { nudgeBlocked: e.nudgeBlocked } : {}),
305
+ preview: e.preview,
306
+ }));
307
+ }
308
+ /** Number of tracked messages. */
309
+ get size() {
310
+ return this.entries.size;
311
+ }
312
+ // -------------------------------------------------------------------------
313
+ // Timeline
314
+ // -------------------------------------------------------------------------
315
+ /**
316
+ * Evaluate every tracked message once. Safe to call concurrently (a second
317
+ * call while one runs is a no-op).
318
+ *
319
+ * @returns When the evaluation is done
320
+ */
321
+ async tick() {
322
+ if (this.ticking)
323
+ return;
324
+ this.ticking = true;
325
+ try {
326
+ for (const entry of [...this.entries.values()]) {
327
+ if (!this.entries.has(entry.key))
328
+ continue;
329
+ try {
330
+ await this.evaluate(entry);
331
+ }
332
+ catch (err) {
333
+ this.logger.warn('Owner message watchdog step failed', {
334
+ key: entry.key,
335
+ error: err instanceof Error ? err.message : String(err),
336
+ });
337
+ }
338
+ }
339
+ }
340
+ finally {
341
+ this.ticking = false;
342
+ }
343
+ }
344
+ async evaluate(entry) {
345
+ const now = this.now();
346
+ const age = now - entry.receivedAt;
347
+ if (age > C.STALE_DROP_MS) {
348
+ this.logger.warn('Owner message unanswered for hours (restored after downtime) — dropped without a note', {
349
+ key: entry.key,
350
+ responsible: entry.responsible,
351
+ ageMinutes: Math.floor(age / 60000),
352
+ });
353
+ this.finish(entry, 'stale');
354
+ return;
355
+ }
356
+ // Working on it where the owner can see it: leave it alone, up to the cap.
357
+ if (this.isVisiblyWorking(entry)) {
358
+ if (age >= C.BUSY_EXTEND_CAP_MS) {
359
+ await this.note(entry, 'cap');
360
+ return;
361
+ }
362
+ if (age >= C.NUDGE_AFTER_MS && !entry.extendedLogged) {
363
+ entry.extendedLogged = true;
364
+ this.logger.info('Owner message still being worked on (placeholder showing, agent busy) — waiting longer', {
365
+ key: entry.key,
366
+ responsible: entry.responsible,
367
+ ageMinutes: Math.floor(age / 60000),
368
+ });
369
+ }
370
+ return;
371
+ }
372
+ if (entry.stage === 'waiting') {
373
+ if (age < C.NUDGE_AFTER_MS)
374
+ return;
375
+ await this.runNudge(entry, age);
376
+ return;
377
+ }
378
+ // Nudged.
379
+ if (!entry.required && entry.turnDoneAfterNudge) {
380
+ this.logger.info('Reminded agent finished its turn without answering an un-addressed owner message — taken as "not for me"', {
381
+ key: entry.key,
382
+ responsible: entry.responsible,
383
+ });
384
+ this.finish(entry, 'nudged agent judged no answer needed');
385
+ return;
386
+ }
387
+ if (age >= C.NOTE_AFTER_MS && now - (entry.nudgedAt ?? 0) >= C.MIN_NOTE_GAP_AFTER_NUDGE_MS) {
388
+ await this.note(entry, 'silent');
389
+ }
390
+ }
391
+ isVisiblyWorking(entry) {
392
+ const visible = entry.surface === 'chat' ? entry.interimAt !== undefined : (this.deps.hasVisiblePlaceholder?.(entry) ?? false);
393
+ return visible && this.deps.isBusy(entry.responsible);
394
+ }
395
+ async runNudge(entry, age) {
396
+ const waited = Math.floor(age / 60000);
397
+ const login = this.deps.loginRequired?.(entry.responsible) ?? null;
398
+ let outcome;
399
+ if (login) {
400
+ outcome = { outcome: 'blocked', reason: 'login' };
401
+ }
402
+ else {
403
+ try {
404
+ outcome = await this.deps.nudge(entry, waited);
405
+ }
406
+ catch (err) {
407
+ outcome = { outcome: 'blocked', reason: 'error', detail: err instanceof Error ? err.message : String(err) };
408
+ }
409
+ }
410
+ if (!this.entries.has(entry.key))
411
+ return; // answered while nudging
412
+ entry.stage = 'nudged';
413
+ entry.nudgedAt = this.now();
414
+ entry.busyAfterNudge = false;
415
+ entry.turnDoneAfterNudge = false;
416
+ if (outcome.outcome === 'blocked') {
417
+ entry.nudgeBlocked = { reason: outcome.reason, ...(outcome.detail ? { detail: outcome.detail } : {}) };
418
+ this.logger.warn('Owner message unanswered and its agent cannot be reached — telling the owner now', {
419
+ key: entry.key,
420
+ responsible: entry.responsible,
421
+ reason: outcome.reason,
422
+ detail: outcome.detail,
423
+ waitedMinutes: waited,
424
+ });
425
+ this.persist();
426
+ await this.note(entry, 'blocked');
427
+ return;
428
+ }
429
+ this.persist();
430
+ this.logger.warn('Owner message unanswered — reminded the responsible agent', {
431
+ key: entry.key,
432
+ responsible: entry.responsible,
433
+ waitedMinutes: waited,
434
+ preview: entry.preview.slice(0, 80),
435
+ });
436
+ }
437
+ /**
438
+ * Post the one note and stop tracking.
439
+ *
440
+ * @param entry - The message
441
+ * @param kind - Why now
442
+ */
443
+ async note(entry, kind) {
444
+ const text = this.noteText(entry, kind);
445
+ let posted = false;
446
+ try {
447
+ posted = await this.deps.postNote(entry, text);
448
+ }
449
+ catch (err) {
450
+ this.logger.warn('Owner message note could not be posted', {
451
+ key: entry.key,
452
+ error: err instanceof Error ? err.message : String(err),
453
+ });
454
+ }
455
+ this.logger.warn('Owner message unanswered — told the owner who it is waiting on', {
456
+ key: entry.key,
457
+ responsible: entry.responsible,
458
+ kind,
459
+ posted,
460
+ ageMinutes: Math.floor((this.now() - entry.receivedAt) / 60000),
461
+ note: text,
462
+ });
463
+ this.finish(entry, `noted (${kind})`);
464
+ }
465
+ /**
466
+ * The note in plain words.
467
+ *
468
+ * @param entry - The message
469
+ * @param kind - Why now
470
+ * @returns The note text
471
+ */
472
+ noteText(entry, kind) {
473
+ const name = this.deps.displayNameOf?.(entry.responsible) || entry.responsible;
474
+ const waited = String(Math.max(1, Math.floor((this.now() - entry.receivedAt) / 60000)));
475
+ const login = this.deps.loginRequired?.(entry.responsible) ?? null;
476
+ if (login) {
477
+ return fill(C.NOTE_LOGIN_TEXT, { name, runtime: login.runtime, runtimeCmd: login.runtimeCmd });
478
+ }
479
+ if (kind === 'blocked' && entry.nudgeBlocked) {
480
+ const detail = entry.nudgeBlocked.detail ? clip(entry.nudgeBlocked.detail, 120) : '原因不明';
481
+ return fill(entry.nudgeBlocked.reason === 'asleep' ? C.NOTE_ASLEEP_TEXT : C.NOTE_ERROR_TEXT, { name, detail });
482
+ }
483
+ if (kind === 'cap')
484
+ return fill(C.NOTE_BUSY_CAP_TEXT, { name, waited });
485
+ return fill(C.NOTE_SILENT_TEXT, { name, waited });
486
+ }
487
+ noteRecentAnswer(threadKey) {
488
+ const now = this.now();
489
+ this.recentAnswers.delete(threadKey);
490
+ this.recentAnswers.set(threadKey, now);
491
+ for (const [k, at] of this.recentAnswers) {
492
+ if (now - at <= C.RECENT_ANSWER_KEEP_MS && this.recentAnswers.size <= C.MAX_RESOLVED_KEYS)
493
+ break;
494
+ this.recentAnswers.delete(k);
495
+ }
496
+ }
497
+ remember(key) {
498
+ this.resolved.delete(key);
499
+ this.resolved.set(key, this.now());
500
+ while (this.resolved.size > C.MAX_RESOLVED_KEYS) {
501
+ const oldest = this.resolved.keys().next().value;
502
+ if (oldest === undefined)
503
+ break;
504
+ this.resolved.delete(oldest);
505
+ }
506
+ }
507
+ finish(entry, why) {
508
+ if (!this.entries.delete(entry.key))
509
+ return;
510
+ this.remember(entry.key);
511
+ this.persist();
512
+ this.logger.info('Owner message no longer tracked', { key: entry.key, why });
513
+ }
514
+ // -------------------------------------------------------------------------
515
+ // Persistence
516
+ // -------------------------------------------------------------------------
517
+ persist() {
518
+ const file = this.deps.storePath;
519
+ if (!file)
520
+ return;
521
+ try {
522
+ mkdirSync(path.dirname(file), { recursive: true });
523
+ const tmp = `${file}.tmp`;
524
+ writeFileSync(tmp, JSON.stringify({ entries: [...this.entries.values()], resolved: [...this.resolved.entries()] }), { mode: 0o600 });
525
+ renameSync(tmp, file);
526
+ }
527
+ catch (err) {
528
+ this.logger.warn('Could not save the owner message watchdog state', {
529
+ error: err instanceof Error ? err.message : String(err),
530
+ });
531
+ }
532
+ }
533
+ load() {
534
+ const file = this.deps.storePath;
535
+ if (!file || !existsSync(file))
536
+ return;
537
+ try {
538
+ const raw = JSON.parse(readFileSync(file, 'utf8'));
539
+ for (const [k, at] of raw.resolved ?? [])
540
+ if (typeof k === 'string')
541
+ this.resolved.set(k, at);
542
+ for (const e of raw.entries ?? []) {
543
+ if (!e?.key || typeof e.receivedAt !== 'number' || !e.responsible)
544
+ continue;
545
+ // Turn tracking does not survive a restart (the agent's turn did not either).
546
+ e.busyAfterNudge = false;
547
+ e.turnDoneAfterNudge = false;
548
+ this.entries.set(e.key, e);
549
+ }
550
+ if (this.entries.size > 0) {
551
+ this.logger.info('Restored unanswered owner messages from before the restart', { count: this.entries.size });
552
+ }
553
+ }
554
+ catch (err) {
555
+ this.logger.warn('Could not load the owner message watchdog state', {
556
+ error: err instanceof Error ? err.message : String(err),
557
+ });
558
+ }
559
+ }
560
+ }
561
+ /**
562
+ * Where the answer to a message lands, as a recent-answer key.
563
+ *
564
+ * @param input - Track input
565
+ * @returns `slack:<channel>:<thread>` or `chat:<channel>:<thread or ''>`
566
+ */
567
+ function threadKeyOf(input) {
568
+ if (input.surface === 'slack')
569
+ return `slack:${input.slackChannelId}:${input.threadTs ?? input.sourceTs}`;
570
+ return `chat:${input.chatChannelId}:${input.chatThreadId ?? ''}`;
571
+ }
572
+ /**
573
+ * Clip text for logs / listings / nudges.
574
+ *
575
+ * @param text - Text
576
+ * @param max - Limit
577
+ * @returns Single-line clipped text
578
+ */
579
+ function clip(text, max = C.PREVIEW_CHARS) {
580
+ const one = (text ?? '').replace(/\s+/g, ' ').trim();
581
+ return one.length > max ? `${one.slice(0, max)}…` : one;
582
+ }
583
+ /**
584
+ * Fill `{name}` placeholders.
585
+ *
586
+ * @param template - Template
587
+ * @param values - Values
588
+ * @returns Filled text
589
+ */
590
+ function fill(template, values) {
591
+ return template.replace(/\{(\w+)\}/g, (m, k) => (k in values ? values[k] : m));
592
+ }
593
+ // ---------------------------------------------------------------------------
594
+ // Singleton
595
+ // ---------------------------------------------------------------------------
596
+ let instance = null;
597
+ /** @returns The wired watchdog, or null before it started (and in tests). */
598
+ export function getOwnerMessageWatchdog() {
599
+ return instance;
600
+ }
601
+ /** @param service - The watchdog to expose (null to clear) */
602
+ export function setOwnerMessageWatchdog(service) {
603
+ instance = service;
604
+ }
605
+ //# sourceMappingURL=owner-message-watchdog.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-message-watchdog.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/owner-message-watchdog.service.ts"],"names":[],"mappings":"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"}