crewly 1.20.256 → 1.20.258
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backend/backend/src/constants.d.ts +52 -4
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +56 -8
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +9 -0
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts +8 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +96 -0
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/apps/apps.wiring.d.ts +11 -0
- package/dist/backend/backend/src/services/apps/apps.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/apps/apps.wiring.js +22 -1
- package/dist/backend/backend/src/services/apps/apps.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-item-card.d.ts +38 -17
- package/dist/backend/backend/src/services/open-items/open-item-card.d.ts.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-item-card.js +118 -31
- package/dist/backend/backend/src/services/open-items/open-item-card.js.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items.service.d.ts +50 -0
- package/dist/backend/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items.service.js +95 -5
- package/dist/backend/backend/src/services/open-items/open-items.service.js.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/open-items/open-items.wiring.js +8 -0
- package/dist/backend/backend/src/services/open-items/open-items.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/orc/owner-completion-report.service.d.ts +257 -0
- package/dist/backend/backend/src/services/orc/owner-completion-report.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/orc/owner-completion-report.service.js +522 -0
- package/dist/backend/backend/src/services/orc/owner-completion-report.service.js.map +1 -0
- package/dist/backend/backend/src/services/orc/owner-completion-report.wiring.d.ts +76 -0
- package/dist/backend/backend/src/services/orc/owner-completion-report.wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/orc/owner-completion-report.wiring.js +130 -0
- package/dist/backend/backend/src/services/orc/owner-completion-report.wiring.js.map +1 -0
- package/dist/backend/backend/src/services/orc/owner-request-context.d.ts +119 -0
- package/dist/backend/backend/src/services/orc/owner-request-context.d.ts.map +1 -0
- package/dist/backend/backend/src/services/orc/owner-request-context.js +163 -0
- package/dist/backend/backend/src/services/orc/owner-request-context.js.map +1 -0
- package/dist/backend/backend/src/services/orc/work-item-destination.d.ts +31 -4
- package/dist/backend/backend/src/services/orc/work-item-destination.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/work-item-destination.js +28 -8
- package/dist/backend/backend/src/services/orc/work-item-destination.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts +1 -0
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js +8 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
- package/dist/backend/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js +34 -4
- package/dist/backend/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +52 -4
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +56 -8
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/open-items/open-item-card.d.ts +38 -17
- package/dist/cli/backend/src/services/open-items/open-item-card.d.ts.map +1 -1
- package/dist/cli/backend/src/services/open-items/open-item-card.js +118 -31
- package/dist/cli/backend/src/services/open-items/open-item-card.js.map +1 -1
- package/dist/cli/backend/src/services/open-items/open-items.service.d.ts +50 -0
- package/dist/cli/backend/src/services/open-items/open-items.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/open-items/open-items.service.js +95 -5
- package/dist/cli/backend/src/services/open-items/open-items.service.js.map +1 -1
- package/dist/cli/backend/src/services/orc/owner-request-context.d.ts +119 -0
- package/dist/cli/backend/src/services/orc/owner-request-context.d.ts.map +1 -0
- package/dist/cli/backend/src/services/orc/owner-request-context.js +163 -0
- package/dist/cli/backend/src/services/orc/owner-request-context.js.map +1 -0
- package/dist/cli/backend/src/services/orc/work-item-destination.d.ts +31 -4
- package/dist/cli/backend/src/services/orc/work-item-destination.d.ts.map +1 -1
- package/dist/cli/backend/src/services/orc/work-item-destination.js +28 -8
- package/dist/cli/backend/src/services/orc/work-item-destination.js.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts +19 -0
- package/dist/cli/backend/src/services/task-pool/task-pool.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js +34 -4
- package/dist/cli/backend/src/services/task-pool/task-pool.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finished owner-requested work is always reported back where the owner asked.
|
|
3
|
+
*
|
|
4
|
+
* Incident 2026-10-07: the owner commented in the schedule app about a "Zeng
|
|
5
|
+
* Ming three-stage opportunity map". Lyra answered in the comment's Slack
|
|
6
|
+
* thread "draft goes to you first", Ella opened CREW-305/309/310 and
|
|
7
|
+
* delegated them; everything was verified by 17:37Z and nobody told the
|
|
8
|
+
* owner. Nothing in the harness asked for that report.
|
|
9
|
+
*
|
|
10
|
+
* A CHAIN is every work item whose owner origin names the same place (an app
|
|
11
|
+
* comment, a Slack thread / DM, a chat conversation) and records who received
|
|
12
|
+
* the owner's request (`origin.receivedBy` — set only on work an agent created
|
|
13
|
+
* while handling the owner's message, and inherited by its delegations,
|
|
14
|
+
* verify items and retries). Trigger / cron / agent-internal work has no
|
|
15
|
+
* owner origin and never forms a chain.
|
|
16
|
+
*
|
|
17
|
+
* When the last open item of a chain is closed (verified / done; cancelled
|
|
18
|
+
* and failed items count as closed, at least one must have succeeded):
|
|
19
|
+
*
|
|
20
|
+
* 1. after SETTLE_MS of staying closed (the lead may still hand out the next
|
|
21
|
+
* step) — unless an agent already answered in the owner's place after
|
|
22
|
+
* the work finished — the responsible agent (`receivedBy`) gets ONE
|
|
23
|
+
* message asking it to report the result there;
|
|
24
|
+
* 2. no agent answer there within REPORT_WAIT_MS → one reminder;
|
|
25
|
+
* 3. still none after another REPORT_WAIT_MS → the harness posts a short
|
|
26
|
+
* factual summary there itself (as the agent's bot when it can).
|
|
27
|
+
*
|
|
28
|
+
* Each chain is handled once (persisted, so a restart neither repeats nor
|
|
29
|
+
* forgets a step). Work added to the same place after a chain was handled
|
|
30
|
+
* starts a new chain. Chains whose responsible agent is the orchestrator are
|
|
31
|
+
* skipped: OrcDeliveryEnforcer already keeps reminding the orc until it
|
|
32
|
+
* answers. The owner only reads; nothing here asks the owner to act.
|
|
33
|
+
*
|
|
34
|
+
* Harness text is English.
|
|
35
|
+
*
|
|
36
|
+
* @module services/orc/owner-completion-report.service
|
|
37
|
+
*/
|
|
38
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'fs';
|
|
39
|
+
import * as path from 'path';
|
|
40
|
+
import { ORCHESTRATOR_SESSION_NAME, OWNER_COMPLETION_REPORT_CONSTANTS as C } from '../../constants.js';
|
|
41
|
+
import { LoggerService } from '../core/logger.service.js';
|
|
42
|
+
import { originOfWorkItem } from './work-item-destination.js';
|
|
43
|
+
/** Statuses after which a work item is not going to do more. */
|
|
44
|
+
const CLOSED = new Set(['done', 'verified', 'cancelled', 'failed']);
|
|
45
|
+
/** Statuses that mean the work succeeded. */
|
|
46
|
+
const SUCCEEDED = new Set(['done', 'verified']);
|
|
47
|
+
/**
|
|
48
|
+
* The place key of an owner origin: one per app comment / Slack thread (or
|
|
49
|
+
* DM) / chat conversation thread.
|
|
50
|
+
*
|
|
51
|
+
* @param origin - Owner origin
|
|
52
|
+
* @returns Key, or null when the origin names no place
|
|
53
|
+
*/
|
|
54
|
+
export function ownerPlaceKey(origin) {
|
|
55
|
+
if (origin.appComment?.appId && origin.appComment.commentId)
|
|
56
|
+
return `app:${origin.appComment.appId}/${origin.appComment.commentId}`;
|
|
57
|
+
if (origin.slackChannelId)
|
|
58
|
+
return origin.threadTs ? `slack:${origin.slackChannelId}:${origin.threadTs}` : `slack:${origin.slackChannelId}`;
|
|
59
|
+
if (origin.conversationId)
|
|
60
|
+
return origin.chatThreadId ? `chat:${origin.conversationId}:${origin.chatThreadId}` : `chat:${origin.conversationId}`;
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The keys an answer in this place is recorded under (an app comment is also
|
|
65
|
+
* answered in its Slack thread).
|
|
66
|
+
*
|
|
67
|
+
* @param origin - Owner origin
|
|
68
|
+
* @param place - Its resolved place, when known
|
|
69
|
+
* @returns Answer keys
|
|
70
|
+
*/
|
|
71
|
+
export function answerKeysOf(origin, place) {
|
|
72
|
+
const keys = new Set();
|
|
73
|
+
const own = ownerPlaceKey(origin);
|
|
74
|
+
if (own)
|
|
75
|
+
keys.add(own);
|
|
76
|
+
const ch = place && place.kind !== 'chat' ? place.slackChannelId : origin.slackChannelId;
|
|
77
|
+
const ts = place && place.kind !== 'chat' ? place.threadTs : origin.threadTs;
|
|
78
|
+
if (ch)
|
|
79
|
+
keys.add(ts ? `slack:${ch}:${ts}` : `slack:${ch}`);
|
|
80
|
+
if (origin.conversationId)
|
|
81
|
+
keys.add(origin.chatThreadId ? `chat:${origin.conversationId}:${origin.chatThreadId}` : `chat:${origin.conversationId}`);
|
|
82
|
+
return [...keys];
|
|
83
|
+
}
|
|
84
|
+
const ms = (iso) => Date.parse(iso ?? '') || 0;
|
|
85
|
+
const endOf = (wi) => ms(wi.completedAt) || ms(wi.statusChangedAt) || ms(wi.createdAt);
|
|
86
|
+
const isVerifyItem = (wi) => typeof (wi.metadata ?? {}).verifyOf === 'string';
|
|
87
|
+
/**
|
|
88
|
+
* Group the pool into owner chains.
|
|
89
|
+
*
|
|
90
|
+
* @param items - Pool items
|
|
91
|
+
* @param handledThrough - Per place key: items created at or before this (epoch ms) belong to a chain already handled
|
|
92
|
+
* @returns Chains (only places with at least one item)
|
|
93
|
+
*/
|
|
94
|
+
export function collectOwnerChains(items, handledThrough) {
|
|
95
|
+
const groups = new Map();
|
|
96
|
+
for (const wi of items) {
|
|
97
|
+
const origin = originOfWorkItem(wi);
|
|
98
|
+
if (origin?.kind !== 'owner' || !origin.receivedBy)
|
|
99
|
+
continue;
|
|
100
|
+
const key = ownerPlaceKey(origin);
|
|
101
|
+
if (!key)
|
|
102
|
+
continue;
|
|
103
|
+
if (ms(wi.createdAt) <= (handledThrough[key] ?? -Infinity))
|
|
104
|
+
continue;
|
|
105
|
+
const g = groups.get(key) ?? { origin, items: [] };
|
|
106
|
+
g.items.push(wi);
|
|
107
|
+
groups.set(key, g);
|
|
108
|
+
}
|
|
109
|
+
const chains = [];
|
|
110
|
+
for (const [key, g] of groups) {
|
|
111
|
+
const sorted = [...g.items].sort((a, b) => ms(a.createdAt) - ms(b.createdAt));
|
|
112
|
+
const first = sorted[0];
|
|
113
|
+
const firstOrigin = originOfWorkItem(first) ?? g.origin;
|
|
114
|
+
const work = sorted.filter((w) => !isVerifyItem(w));
|
|
115
|
+
chains.push({
|
|
116
|
+
key,
|
|
117
|
+
origin: firstOrigin,
|
|
118
|
+
items: sorted,
|
|
119
|
+
open: sorted.some((w) => !CLOSED.has(w.status)),
|
|
120
|
+
succeeded: sorted.some((w) => SUCCEEDED.has(w.status)),
|
|
121
|
+
responsible: firstOrigin.receivedBy ?? first.target ?? '',
|
|
122
|
+
firstCreatedAt: ms(first.createdAt),
|
|
123
|
+
lastCreatedAt: Math.max(...sorted.map((w) => ms(w.createdAt))),
|
|
124
|
+
finishedAt: Math.max(...(work.length ? work : sorted).map(endOf)),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return chains;
|
|
128
|
+
}
|
|
129
|
+
/** Shorten to one line. */
|
|
130
|
+
function clip(text, max) {
|
|
131
|
+
const flat = String(text ?? '').replace(/\s+/g, ' ').trim();
|
|
132
|
+
return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The titles of a chain's work (verify items left out), for a message.
|
|
136
|
+
*
|
|
137
|
+
* @param items - Chain items
|
|
138
|
+
* @returns `"A", "B" and 2 more`
|
|
139
|
+
*/
|
|
140
|
+
export function titlesLine(items) {
|
|
141
|
+
const work = items.filter((w) => !isVerifyItem(w) && SUCCEEDED.has(w.status));
|
|
142
|
+
const titles = [...new Set((work.length ? work : items).map((w) => clip(w.title, C.TITLE_MAX_CHARS)).filter(Boolean))];
|
|
143
|
+
const shown = titles.slice(0, C.MAX_TITLES).map((t) => `"${t}"`);
|
|
144
|
+
const more = titles.length - shown.length;
|
|
145
|
+
return more > 0 ? `${shown.join(', ')} and ${more} more` : shown.join(', ');
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* What the finished items left behind: their result / output summaries and
|
|
149
|
+
* file paths, one line each.
|
|
150
|
+
*
|
|
151
|
+
* @param items - Chain items
|
|
152
|
+
* @returns Evidence lines (possibly empty)
|
|
153
|
+
*/
|
|
154
|
+
export function evidenceLines(items) {
|
|
155
|
+
const lines = [];
|
|
156
|
+
for (const wi of items) {
|
|
157
|
+
if (isVerifyItem(wi) || !SUCCEEDED.has(wi.status))
|
|
158
|
+
continue;
|
|
159
|
+
const bag = { ...(wi.output ?? {}), ...(wi.result ?? {}) };
|
|
160
|
+
const parts = [];
|
|
161
|
+
for (const k of ['summary', 'message', 'text', 'evidence']) {
|
|
162
|
+
if (typeof bag[k] === 'string' && bag[k].trim()) {
|
|
163
|
+
parts.push(bag[k]);
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
for (const k of ['files', 'artifacts', 'paths', 'evidencePaths', 'outputPaths']) {
|
|
168
|
+
const v = bag[k];
|
|
169
|
+
if (Array.isArray(v))
|
|
170
|
+
parts.push(v.filter((x) => typeof x === 'string').join(', '));
|
|
171
|
+
else if (typeof v === 'string')
|
|
172
|
+
parts.push(v);
|
|
173
|
+
}
|
|
174
|
+
if (!parts.length)
|
|
175
|
+
continue;
|
|
176
|
+
lines.push(`${clip(wi.title, C.TITLE_MAX_CHARS)}: ${clip(parts.join(' — '), C.EVIDENCE_LINE_MAX_CHARS)}`);
|
|
177
|
+
if (lines.length >= C.MAX_EVIDENCE_LINES)
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
return lines;
|
|
181
|
+
}
|
|
182
|
+
/** The harness rule that finished owner-requested work is reported to the owner. */
|
|
183
|
+
export class OwnerCompletionReportService {
|
|
184
|
+
deps;
|
|
185
|
+
file;
|
|
186
|
+
store;
|
|
187
|
+
timer = null;
|
|
188
|
+
running = false;
|
|
189
|
+
answersDirty = false;
|
|
190
|
+
log;
|
|
191
|
+
constructor(deps) {
|
|
192
|
+
this.deps = deps;
|
|
193
|
+
this.file = path.join(deps.crewlyHome, C.STORE_FILE);
|
|
194
|
+
this.log = deps.logger ?? LoggerService.getInstance().createComponentLogger('OwnerCompletionReport');
|
|
195
|
+
this.store = this.load();
|
|
196
|
+
}
|
|
197
|
+
now() {
|
|
198
|
+
return (this.deps.now ?? Date.now)();
|
|
199
|
+
}
|
|
200
|
+
/** Start the periodic scan (idempotent). */
|
|
201
|
+
start() {
|
|
202
|
+
if (this.timer)
|
|
203
|
+
return;
|
|
204
|
+
this.timer = setInterval(() => void this.tick(), C.TICK_MS);
|
|
205
|
+
this.timer.unref?.();
|
|
206
|
+
}
|
|
207
|
+
/** Stop the periodic scan. */
|
|
208
|
+
stop() {
|
|
209
|
+
if (this.timer)
|
|
210
|
+
clearInterval(this.timer);
|
|
211
|
+
this.timer = null;
|
|
212
|
+
if (this.answersDirty)
|
|
213
|
+
this.save();
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* An agent (or the harness on its behalf) posted in a place. Interim
|
|
217
|
+
* placeholders and owner posts must not be fed here.
|
|
218
|
+
*
|
|
219
|
+
* @param key - Answer key (`slack:<ch>:<ts>`, `slack:<ch>`, `chat:<conv>[:<thread>]`, `app:<app>/<comment>`)
|
|
220
|
+
* @param at - When (epoch ms)
|
|
221
|
+
*/
|
|
222
|
+
noteAnswer(key, at = this.now()) {
|
|
223
|
+
if (!key)
|
|
224
|
+
return;
|
|
225
|
+
const before = this.store.answers[key] ?? 0;
|
|
226
|
+
if (at <= before)
|
|
227
|
+
return;
|
|
228
|
+
this.store.answers[key] = at;
|
|
229
|
+
// Saved with the next scan: every agent post lands here.
|
|
230
|
+
this.answersDirty = true;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* An agent posted in Slack (any machine).
|
|
234
|
+
*
|
|
235
|
+
* @param slackChannelId - Channel / DM
|
|
236
|
+
* @param threadTs - Thread root, when in a thread
|
|
237
|
+
*/
|
|
238
|
+
noteSlackAnswer(slackChannelId, threadTs) {
|
|
239
|
+
if (!slackChannelId)
|
|
240
|
+
return;
|
|
241
|
+
if (threadTs)
|
|
242
|
+
this.noteAnswer(`slack:${slackChannelId}:${threadTs}`);
|
|
243
|
+
else
|
|
244
|
+
this.noteAnswer(`slack:${slackChannelId}`);
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* An agent replied on an app comment.
|
|
248
|
+
*
|
|
249
|
+
* @param appId - App
|
|
250
|
+
* @param commentId - Comment
|
|
251
|
+
*/
|
|
252
|
+
noteAppCommentAnswer(appId, commentId) {
|
|
253
|
+
if (appId && commentId)
|
|
254
|
+
this.noteAnswer(`app:${appId}/${commentId}`);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* An agent posted in a chat conversation.
|
|
258
|
+
*
|
|
259
|
+
* @param conversationId - chat-v2 channel
|
|
260
|
+
* @param chatThreadId - Thread, when in one
|
|
261
|
+
*/
|
|
262
|
+
noteChatAnswer(conversationId, chatThreadId) {
|
|
263
|
+
if (!conversationId)
|
|
264
|
+
return;
|
|
265
|
+
this.noteAnswer(`chat:${conversationId}`);
|
|
266
|
+
if (chatThreadId)
|
|
267
|
+
this.noteAnswer(`chat:${conversationId}:${chatThreadId}`);
|
|
268
|
+
}
|
|
269
|
+
/** Records being reported (tests / diagnostics). */
|
|
270
|
+
get activeRecords() {
|
|
271
|
+
return Object.values(this.store.active);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* One scan: find finished chains and move each one step on. Never throws;
|
|
275
|
+
* a scan already running is not doubled.
|
|
276
|
+
*/
|
|
277
|
+
async tick() {
|
|
278
|
+
if (this.running)
|
|
279
|
+
return;
|
|
280
|
+
this.running = true;
|
|
281
|
+
try {
|
|
282
|
+
await this.scan();
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
this.log.warn('Owner completion report scan failed', { error: err instanceof Error ? err.message : String(err) });
|
|
286
|
+
}
|
|
287
|
+
finally {
|
|
288
|
+
this.running = false;
|
|
289
|
+
if (this.answersDirty)
|
|
290
|
+
this.save();
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
async scan() {
|
|
294
|
+
const now = this.now();
|
|
295
|
+
const items = await this.deps.listItems();
|
|
296
|
+
const chains = collectOwnerChains(items, this.store.handledThrough);
|
|
297
|
+
const byKey = new Map(chains.map((c) => [c.key, c]));
|
|
298
|
+
// New finished chains start settling.
|
|
299
|
+
for (const chain of chains) {
|
|
300
|
+
if (chain.open || !chain.succeeded || this.store.active[chain.key])
|
|
301
|
+
continue;
|
|
302
|
+
if (chain.finishedAt < this.store.since || now - chain.firstCreatedAt > C.MAX_CHAIN_AGE_MS) {
|
|
303
|
+
this.markHandled(chain.key, chain.lastCreatedAt);
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
const id = `${chain.key}#${chain.firstCreatedAt}`;
|
|
307
|
+
if (this.store.ended[id]) {
|
|
308
|
+
this.markHandled(chain.key, chain.lastCreatedAt);
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
this.store.active[chain.key] = this.recordOf(id, chain, now);
|
|
312
|
+
this.save();
|
|
313
|
+
}
|
|
314
|
+
for (const record of Object.values(this.store.active)) {
|
|
315
|
+
const chain = byKey.get(record.key);
|
|
316
|
+
await this.advance(record, chain ?? null, now);
|
|
317
|
+
}
|
|
318
|
+
this.prune(now);
|
|
319
|
+
}
|
|
320
|
+
recordOf(id, chain, now) {
|
|
321
|
+
const mine = [...chain.items].reverse().find((w) => w.target === chain.responsible && !isVerifyItem(w));
|
|
322
|
+
const last = [...chain.items].sort((a, b) => endOf(b) - endOf(a)).find((w) => !isVerifyItem(w)) ?? chain.items[chain.items.length - 1];
|
|
323
|
+
return {
|
|
324
|
+
id,
|
|
325
|
+
key: chain.key,
|
|
326
|
+
origin: chain.origin,
|
|
327
|
+
responsible: chain.responsible,
|
|
328
|
+
workItemIds: chain.items.map((w) => w.id),
|
|
329
|
+
titles: titlesLine(chain.items),
|
|
330
|
+
replyWorkItemId: (mine ?? last).id,
|
|
331
|
+
firstCreatedAt: chain.firstCreatedAt,
|
|
332
|
+
lastCreatedAt: chain.lastCreatedAt,
|
|
333
|
+
finishedAt: chain.finishedAt,
|
|
334
|
+
stage: 'settling',
|
|
335
|
+
closedSince: now,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
async advance(record, chain, now) {
|
|
339
|
+
if (chain) {
|
|
340
|
+
record.workItemIds = chain.items.map((w) => w.id);
|
|
341
|
+
record.lastCreatedAt = chain.lastCreatedAt;
|
|
342
|
+
if (chain.open) {
|
|
343
|
+
// More work joined the chain: wait for it, and count the wait again from its end.
|
|
344
|
+
if (record.stage === 'settling') {
|
|
345
|
+
delete this.store.active[record.key];
|
|
346
|
+
this.save();
|
|
347
|
+
}
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
if (chain.finishedAt > record.finishedAt) {
|
|
351
|
+
record.finishedAt = chain.finishedAt;
|
|
352
|
+
record.titles = titlesLine(chain.items);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const place = await this.deps.resolvePlace(record.origin).catch(() => null);
|
|
356
|
+
if (this.answeredSince(record, place, record.finishedAt)) {
|
|
357
|
+
this.end(record, 'answered', now);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
switch (record.stage) {
|
|
361
|
+
case 'settling': {
|
|
362
|
+
if (now - record.closedSince < C.SETTLE_MS)
|
|
363
|
+
return;
|
|
364
|
+
if (record.responsible === ORCHESTRATOR_SESSION_NAME) {
|
|
365
|
+
this.log.info('Owner chain finished; the orchestrator delivery enforcer covers it', { key: record.key });
|
|
366
|
+
this.end(record, 'skipped', now);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (!place) {
|
|
370
|
+
this.log.info('Owner chain finished but its place cannot be resolved; not reported', { key: record.key });
|
|
371
|
+
this.end(record, 'skipped', now);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
const ok = await this.deps.deliver(record.responsible, this.askText(record, place, false)).catch(() => false);
|
|
375
|
+
record.stage = 'asked';
|
|
376
|
+
record.askedAt = now;
|
|
377
|
+
this.save();
|
|
378
|
+
this.log.info('Asked the agent to report finished owner work', { key: record.key, agent: record.responsible, delivered: ok });
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
case 'asked': {
|
|
382
|
+
if (now - Math.max(record.askedAt ?? 0, record.finishedAt) < C.REPORT_WAIT_MS || !place)
|
|
383
|
+
return;
|
|
384
|
+
const ok = await this.deps.deliver(record.responsible, this.askText(record, place, true)).catch(() => false);
|
|
385
|
+
record.stage = 'reminded';
|
|
386
|
+
record.remindedAt = now;
|
|
387
|
+
this.save();
|
|
388
|
+
this.log.info('Reminded the agent to report finished owner work', { key: record.key, agent: record.responsible, delivered: ok });
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
case 'reminded': {
|
|
392
|
+
if (now - Math.max(record.remindedAt ?? 0, record.finishedAt) < C.REPORT_WAIT_MS || !place)
|
|
393
|
+
return;
|
|
394
|
+
const items = chain?.items ?? [];
|
|
395
|
+
const posted = await this.deps.postFallback(place, record.responsible, this.fallbackText(record, items)).catch(() => false);
|
|
396
|
+
this.log.info('Posted the finished owner work summary for the agent', { key: record.key, agent: record.responsible, posted });
|
|
397
|
+
record.postedAt = now;
|
|
398
|
+
this.end(record, 'posted', now);
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
default:
|
|
402
|
+
this.end(record, record.stage, now);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
answeredSince(record, place, since) {
|
|
406
|
+
return answerKeysOf(record.origin, place).some((k) => (this.store.answers[k] ?? 0) > since);
|
|
407
|
+
}
|
|
408
|
+
name(session) {
|
|
409
|
+
return this.deps.displayNameOf?.(session) ?? session;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* The message asking the responsible agent for the report.
|
|
413
|
+
*
|
|
414
|
+
* @param record - Chain record
|
|
415
|
+
* @param place - Where the owner asked
|
|
416
|
+
* @param reminder - The second (last) ask
|
|
417
|
+
* @returns English harness text
|
|
418
|
+
*/
|
|
419
|
+
askText(record, place, reminder) {
|
|
420
|
+
const cmd = place.kind === 'app-comment'
|
|
421
|
+
? `${this.deps.appCommentsCmd ?? 'app-comments'} --app ${place.appId} --reply ${place.commentId} --text "<summary + where the files are>"`
|
|
422
|
+
: `reply --work-item ${record.replyWorkItemId} "<summary + where the files are>"`;
|
|
423
|
+
const head = reminder ? '[OWNER REPORT DUE — reminder]' : '[OWNER REPORT DUE]';
|
|
424
|
+
const tail = reminder
|
|
425
|
+
? ` The owner has still not been told. If nothing is posted there within ${Math.round(C.REPORT_WAIT_MS / 60_000)} minutes, Crewly posts a short summary there for you.`
|
|
426
|
+
: ' Write it for the owner: what was done, the result, and where the files are. One message; the owner only reads it.';
|
|
427
|
+
return `${head} The work the owner asked for in ${place.label} is finished (${record.titles}). Report the result to the owner there now: ${cmd}.${tail}`;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* The harness's own summary, posted when the agent never reported.
|
|
431
|
+
*
|
|
432
|
+
* @param record - Chain record
|
|
433
|
+
* @param items - The chain's items (for evidence), when still in the pool
|
|
434
|
+
* @returns English harness text
|
|
435
|
+
*/
|
|
436
|
+
fallbackText(record, items) {
|
|
437
|
+
const evidence = evidenceLines(items);
|
|
438
|
+
const results = evidence.length ? `\nResults:\n${evidence.map((l) => `• ${l}`).join('\n')}` : '\nResults: see the work items in Crewly.';
|
|
439
|
+
return `${this.name(record.responsible)} finished: ${record.titles}.${results}\n— sent by Crewly because no report was posted.`;
|
|
440
|
+
}
|
|
441
|
+
end(record, stage, now) {
|
|
442
|
+
record.stage = stage;
|
|
443
|
+
record.endedAt = now;
|
|
444
|
+
delete this.store.active[record.key];
|
|
445
|
+
this.store.ended[record.id] = now;
|
|
446
|
+
this.markHandled(record.key, record.lastCreatedAt);
|
|
447
|
+
}
|
|
448
|
+
markHandled(key, lastCreatedAt) {
|
|
449
|
+
this.store.handledThrough[key] = Math.max(this.store.handledThrough[key] ?? -Infinity, lastCreatedAt);
|
|
450
|
+
this.save();
|
|
451
|
+
}
|
|
452
|
+
prune(now) {
|
|
453
|
+
let changed = false;
|
|
454
|
+
for (const [id, at] of Object.entries(this.store.ended)) {
|
|
455
|
+
if (now - at > C.RECORD_TTL_MS) {
|
|
456
|
+
delete this.store.ended[id];
|
|
457
|
+
changed = true;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
for (const [k, at] of Object.entries(this.store.answers)) {
|
|
461
|
+
if (now - at > C.RECORD_TTL_MS) {
|
|
462
|
+
delete this.store.answers[k];
|
|
463
|
+
changed = true;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (changed)
|
|
467
|
+
this.save();
|
|
468
|
+
}
|
|
469
|
+
load() {
|
|
470
|
+
const fresh = { version: 1, since: this.now(), handledThrough: {}, active: {}, ended: {}, answers: {} };
|
|
471
|
+
try {
|
|
472
|
+
if (!existsSync(this.file)) {
|
|
473
|
+
this.store = fresh;
|
|
474
|
+
this.save();
|
|
475
|
+
return fresh;
|
|
476
|
+
}
|
|
477
|
+
const raw = JSON.parse(readFileSync(this.file, 'utf-8'));
|
|
478
|
+
return {
|
|
479
|
+
version: 1,
|
|
480
|
+
since: typeof raw.since === 'number' ? raw.since : fresh.since,
|
|
481
|
+
handledThrough: raw.handledThrough && typeof raw.handledThrough === 'object' ? raw.handledThrough : {},
|
|
482
|
+
active: raw.active && typeof raw.active === 'object' ? raw.active : {},
|
|
483
|
+
ended: raw.ended && typeof raw.ended === 'object' ? raw.ended : {},
|
|
484
|
+
answers: raw.answers && typeof raw.answers === 'object' ? raw.answers : {},
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
catch (err) {
|
|
488
|
+
this.log.warn('Owner completion report store unreadable; starting fresh', { error: err instanceof Error ? err.message : String(err) });
|
|
489
|
+
return fresh;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
save() {
|
|
493
|
+
this.answersDirty = false;
|
|
494
|
+
try {
|
|
495
|
+
mkdirSync(path.dirname(this.file), { recursive: true });
|
|
496
|
+
const tmp = `${this.file}.${process.pid}.tmp`;
|
|
497
|
+
writeFileSync(tmp, JSON.stringify(this.store, null, 2), 'utf-8');
|
|
498
|
+
renameSync(tmp, this.file);
|
|
499
|
+
}
|
|
500
|
+
catch (err) {
|
|
501
|
+
this.log.warn('Owner completion report store not saved', { error: err instanceof Error ? err.message : String(err) });
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
let instance = null;
|
|
506
|
+
/**
|
|
507
|
+
* The running service, once started at boot.
|
|
508
|
+
*
|
|
509
|
+
* @returns The service, or null
|
|
510
|
+
*/
|
|
511
|
+
export function getOwnerCompletionReport() {
|
|
512
|
+
return instance;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Set (or clear) the running service.
|
|
516
|
+
*
|
|
517
|
+
* @param service - Service or null
|
|
518
|
+
*/
|
|
519
|
+
export function setOwnerCompletionReport(service) {
|
|
520
|
+
instance = service;
|
|
521
|
+
}
|
|
522
|
+
//# sourceMappingURL=owner-completion-report.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"owner-completion-report.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/owner-completion-report.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wiring for {@link OwnerCompletionReportService}: where an owner origin is
|
|
3
|
+
* on this machine, how the harness posts its own summary there, and which
|
|
4
|
+
* posts count as "an agent answered there". The service stays transport-free.
|
|
5
|
+
*
|
|
6
|
+
* @module services/orc/owner-completion-report.wiring
|
|
7
|
+
*/
|
|
8
|
+
import type { ChatMessageDTO } from '../chat-v2/types.js';
|
|
9
|
+
import type { OwnerCompletionReportService, OwnerOrigin, ReportPlace } from './owner-completion-report.service.js';
|
|
10
|
+
/** An app comment's Slack thread, when it is mirrored. */
|
|
11
|
+
export type CommentLinkLookup = (appId: string, commentId: string) => Promise<{
|
|
12
|
+
slackChannelId: string;
|
|
13
|
+
threadTs: string;
|
|
14
|
+
} | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve where an owner origin is.
|
|
17
|
+
*
|
|
18
|
+
* @param origin - Owner origin
|
|
19
|
+
* @param commentLink - App comment → its Slack thread
|
|
20
|
+
* @returns The place, or null when the origin names none
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveReportPlace(origin: OwnerOrigin, commentLink: CommentLinkLookup): Promise<ReportPlace | null>;
|
|
23
|
+
/** Transports the fallback post uses (all injectable). */
|
|
24
|
+
export interface FallbackTransports {
|
|
25
|
+
/** Reply on an app comment as the agent (also mirrored into its Slack thread) */
|
|
26
|
+
replyComment?: (appId: string, commentId: string, agentSession: string, text: string) => Promise<void>;
|
|
27
|
+
/** Post in Slack as the agent's bot */
|
|
28
|
+
slackAsAgent?: (agentSession: string, slackChannelId: string, text: string, threadTs?: string) => Promise<void>;
|
|
29
|
+
/** Post in Slack as the workspace bot */
|
|
30
|
+
slackAsCrewly?: (slackChannelId: string, text: string, threadTs?: string) => Promise<void>;
|
|
31
|
+
/** Post in a chat conversation as the agent */
|
|
32
|
+
chatAsAgent?: (conversationId: string, agentSession: string, text: string) => Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Post the harness's summary in the owner's place: an app comment gets a
|
|
36
|
+
* reply (mirrored to its Slack thread); Slack as the agent's bot, else as
|
|
37
|
+
* Crewly; a chat as the agent. Never throws.
|
|
38
|
+
*
|
|
39
|
+
* @param place - Where
|
|
40
|
+
* @param agentSession - The responsible agent
|
|
41
|
+
* @param text - The summary
|
|
42
|
+
* @param t - Transports
|
|
43
|
+
* @returns True when posted somewhere in that place
|
|
44
|
+
*/
|
|
45
|
+
export declare function postReportFallback(place: ReportPlace, agentSession: string, text: string, t: FallbackTransports): Promise<boolean>;
|
|
46
|
+
/**
|
|
47
|
+
* Feed a chat-v2 row: an agent's (non-interim) post answers its conversation
|
|
48
|
+
* (and the Slack thread its reply was mirrored into).
|
|
49
|
+
*
|
|
50
|
+
* @param service - The report service
|
|
51
|
+
* @param message - The row
|
|
52
|
+
*/
|
|
53
|
+
export declare function onChatRow(service: Pick<OwnerCompletionReportService, 'noteChatAnswer' | 'noteSlackAnswer'>, message: Pick<ChatMessageDTO, 'channelId' | 'senderType' | 'threadId' | 'metadata'>): void;
|
|
54
|
+
/**
|
|
55
|
+
* Feed a Slack post made through this machine's SlackService.
|
|
56
|
+
*
|
|
57
|
+
* @param service - The report service
|
|
58
|
+
* @param post - Where it went
|
|
59
|
+
*/
|
|
60
|
+
export declare function onSlackOutboundPost(service: Pick<OwnerCompletionReportService, 'noteSlackAnswer'>, post: {
|
|
61
|
+
channelId: string;
|
|
62
|
+
threadTs?: string;
|
|
63
|
+
notAnAnswer?: boolean;
|
|
64
|
+
}): void;
|
|
65
|
+
/**
|
|
66
|
+
* Feed an inbound Slack message: an agent (any machine) posting there.
|
|
67
|
+
*
|
|
68
|
+
* @param service - The report service
|
|
69
|
+
* @param message - Inbound fields
|
|
70
|
+
*/
|
|
71
|
+
export declare function onSlackInboundPost(service: Pick<OwnerCompletionReportService, 'noteSlackAnswer'>, message: {
|
|
72
|
+
channelId: string;
|
|
73
|
+
threadTs?: string;
|
|
74
|
+
authorAgentSession?: string;
|
|
75
|
+
}): void;
|
|
76
|
+
//# sourceMappingURL=owner-completion-report.wiring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"owner-completion-report.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/owner-completion-report.wiring.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,4BAA4B,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAEnH,0DAA0D;AAC1D,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAAC;AAEnI;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAiCzH;AAED,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvG,uCAAuC;IACvC,YAAY,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChH,yCAAyC;IACzC,aAAa,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3F,+CAA+C;IAC/C,WAAW,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7F;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBxI;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,IAAI,CAAC,4BAA4B,EAAE,gBAAgB,GAAG,iBAAiB,CAAC,EACjF,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,YAAY,GAAG,UAAU,GAAG,UAAU,CAAC,GAClF,IAAI,CAON;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,IAAI,CAAC,4BAA4B,EAAE,iBAAiB,CAAC,EAC9D,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GACpE,IAAI,CAGN;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,IAAI,CAAC,4BAA4B,EAAE,iBAAiB,CAAC,EAC9D,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7E,IAAI,CAGN"}
|