crewly 1.20.168 → 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.
- package/config/constants.ts +4 -0
- package/config/skills/_common/lib.sh +5 -0
- package/config/skills/agent/core/reply/SKILL.md +71 -0
- package/config/skills/agent/core/reply/execute.sh +81 -0
- package/config/skills/agent/core/reply/execute.test.sh +87 -0
- package/dist/backend/backend/src/constants.d.ts +101 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +105 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts +36 -0
- package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js +182 -0
- package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts +30 -0
- package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.controller.js +171 -0
- package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.routes.js +4 -0
- package/dist/backend/backend/src/controllers/chat/chat.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts +55 -0
- package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.js +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts +10 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +119 -1
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/middleware/agent-origin.middleware.d.ts +45 -0
- package/dist/backend/backend/src/middleware/agent-origin.middleware.d.ts.map +1 -0
- package/dist/backend/backend/src/middleware/agent-origin.middleware.js +148 -0
- package/dist/backend/backend/src/middleware/agent-origin.middleware.js.map +1 -0
- package/dist/backend/backend/src/routes/modules/system.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/modules/system.routes.js +6 -0
- package/dist/backend/backend/src/routes/modules/system.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-process-origin.service.d.ts +86 -0
- package/dist/backend/backend/src/services/agent/agent-process-origin.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/agent-process-origin.service.js +114 -0
- package/dist/backend/backend/src/services/agent/agent-process-origin.service.js.map +1 -0
- package/dist/backend/backend/src/services/agent/codex-daemon.utils.d.ts +56 -0
- package/dist/backend/backend/src/services/agent/codex-daemon.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/services/agent/codex-daemon.utils.js +100 -0
- package/dist/backend/backend/src/services/agent/codex-daemon.utils.js.map +1 -0
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts +15 -0
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js +27 -0
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +18 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +48 -3
- package/dist/backend/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts +271 -0
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js +605 -0
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -0
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts +179 -0
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js +327 -0
- package/dist/backend/backend/src/services/messaging/owner-message-watchdog.wiring.js.map +1 -0
- package/dist/backend/backend/src/services/orc/agent-reply-target.d.ts +95 -0
- package/dist/backend/backend/src/services/orc/agent-reply-target.d.ts.map +1 -0
- package/dist/backend/backend/src/services/orc/agent-reply-target.js +85 -0
- package/dist/backend/backend/src/services/orc/agent-reply-target.js.map +1 -0
- package/dist/backend/backend/src/services/orc/orc-reply-route.service.d.ts +20 -0
- package/dist/backend/backend/src/services/orc/orc-reply-route.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/orc-reply-route.service.js +34 -1
- package/dist/backend/backend/src/services/orc/orc-reply-route.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js +5 -0
- package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +13 -0
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +40 -0
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js +2 -0
- package/dist/backend/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts +33 -0
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js +68 -0
- package/dist/backend/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.d.ts +16 -0
- package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.js +22 -5
- package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.service.d.ts +15 -5
- package/dist/backend/backend/src/services/system/auto-update.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.service.js +26 -21
- package/dist/backend/backend/src/services/system/auto-update.service.js.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.utils.d.ts +51 -0
- package/dist/backend/backend/src/services/system/auto-update.utils.d.ts.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.utils.js +103 -0
- package/dist/backend/backend/src/services/system/auto-update.utils.js.map +1 -1
- package/dist/backend/backend/src/types/slack.types.d.ts +6 -0
- package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/slack.types.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/backend/config/constants.d.ts +4 -0
- package/dist/backend/config/constants.d.ts.map +1 -1
- package/dist/backend/config/constants.js +4 -0
- package/dist/backend/config/constants.js.map +1 -1
- package/dist/cli/backend/src/constants.d.ts +101 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +105 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/agent/codex-daemon.utils.d.ts +56 -0
- package/dist/cli/backend/src/services/agent/codex-daemon.utils.d.ts.map +1 -0
- package/dist/cli/backend/src/services/agent/codex-daemon.utils.js +100 -0
- package/dist/cli/backend/src/services/agent/codex-daemon.utils.js.map +1 -0
- package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.d.ts +15 -0
- package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js +27 -0
- package/dist/cli/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts +18 -0
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js +48 -3
- package/dist/cli/backend/src/services/chat-v2/chat-v2.dispatcher.service.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts +271 -0
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js +605 -0
- package/dist/cli/backend/src/services/messaging/owner-message-watchdog.service.js.map +1 -0
- package/dist/cli/backend/src/services/orc/orc-reply-route.service.d.ts +20 -0
- package/dist/cli/backend/src/services/orc/orc-reply-route.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/orc/orc-reply-route.service.js +34 -1
- package/dist/cli/backend/src/services/orc/orc-reply-route.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts +13 -0
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js +40 -0
- package/dist/cli/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js +2 -0
- package/dist/cli/backend/src/services/slack/slack-team-channel.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts +33 -0
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js +68 -0
- package/dist/cli/backend/src/services/slack/slack-typing-placeholder.service.js.map +1 -1
- package/dist/cli/backend/src/services/slack/slack.service.d.ts +16 -0
- package/dist/cli/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/slack/slack.service.js +22 -5
- package/dist/cli/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/cli/backend/src/services/system/auto-update.utils.d.ts +51 -0
- package/dist/cli/backend/src/services/system/auto-update.utils.d.ts.map +1 -1
- package/dist/cli/backend/src/services/system/auto-update.utils.js +103 -0
- package/dist/cli/backend/src/services/system/auto-update.utils.js.map +1 -1
- package/dist/cli/backend/src/types/slack.types.d.ts +6 -0
- package/dist/cli/backend/src/types/slack.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/slack.types.js.map +1 -1
- package/dist/cli/config/constants.d.ts +4 -0
- package/dist/cli/config/constants.d.ts.map +1 -1
- package/dist/cli/config/constants.js +4 -0
- package/dist/cli/config/constants.js.map +1 -1
- 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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"}
|