crewly 1.20.346 → 1.20.348
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 +30 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +30 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +25 -1
- package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts +5 -2
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +16 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts +15 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +73 -1
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts +5 -0
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js +3 -2
- package/dist/backend/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.service.d.ts +165 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.service.js +337 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.service.js.map +1 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.wiring.d.ts +45 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.wiring.js +71 -0
- package/dist/backend/backend/src/services/messaging/agent-ask-ledger.wiring.js.map +1 -0
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts +49 -0
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.js +107 -2
- package/dist/backend/backend/src/services/orc/reply-destination.wiring.js.map +1 -1
- package/dist/backend/backend/src/services/orc/triggered-by.d.ts +62 -0
- package/dist/backend/backend/src/services/orc/triggered-by.d.ts.map +1 -0
- package/dist/backend/backend/src/services/orc/triggered-by.js +141 -0
- package/dist/backend/backend/src/services/orc/triggered-by.js.map +1 -0
- package/dist/backend/backend/src/services/trace/trace-context.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/trace/trace-context.service.js +31 -6
- package/dist/backend/backend/src/services/trace/trace-context.service.js.map +1 -1
- package/dist/backend/backend/src/services/trace/turn-trigger.d.ts +141 -0
- package/dist/backend/backend/src/services/trace/turn-trigger.d.ts.map +1 -0
- package/dist/backend/backend/src/services/trace/turn-trigger.js +258 -0
- package/dist/backend/backend/src/services/trace/turn-trigger.js.map +1 -0
- package/dist/backend/backend/src/services/v3/ticket-review.service.d.ts +21 -0
- package/dist/backend/backend/src/services/v3/ticket-review.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/ticket-review.service.js +35 -0
- package/dist/backend/backend/src/services/v3/ticket-review.service.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +30 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +30 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts +5 -0
- package/dist/cli/backend/src/services/chat-v2/chat-v2.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js +3 -2
- package/dist/cli/backend/src/services/chat-v2/chat-v2.service.js.map +1 -1
- package/dist/cli/backend/src/services/messaging/agent-ask-ledger.service.d.ts +165 -0
- package/dist/cli/backend/src/services/messaging/agent-ask-ledger.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/messaging/agent-ask-ledger.service.js +337 -0
- package/dist/cli/backend/src/services/messaging/agent-ask-ledger.service.js.map +1 -0
- package/dist/cli/backend/src/services/trace/trace-context.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/trace/trace-context.service.js +31 -6
- package/dist/cli/backend/src/services/trace/trace-context.service.js.map +1 -1
- package/dist/cli/backend/src/services/trace/turn-trigger.d.ts +141 -0
- package/dist/cli/backend/src/services/trace/turn-trigger.d.ts.map +1 -0
- package/dist/cli/backend/src/services/trace/turn-trigger.js +258 -0
- package/dist/cli/backend/src/services/trace/turn-trigger.js.map +1 -0
- package/dist/cli/backend/src/services/v3/ticket-review.service.d.ts +21 -0
- package/dist/cli/backend/src/services/v3/ticket-review.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/v3/ticket-review.service.js +35 -0
- package/dist/cli/backend/src/services/v3/ticket-review.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent ask ledger — the return path of agent-to-agent messages.
|
|
3
|
+
*
|
|
4
|
+
* When one agent hands work to another with a plain message (send-message /
|
|
5
|
+
* `/terminal/:to/write`), nothing brings the answer back: no WorkItem, no
|
|
6
|
+
* completion event. On 2026-10-14 Pia passed the owner's "replicate this X
|
|
7
|
+
* video" to Dex; Dex rendered the films in 24 minutes, wrote "both parts are
|
|
8
|
+
* done" into its own terminal and stopped. Nobody saw it for seven hours.
|
|
9
|
+
*
|
|
10
|
+
* This ledger remembers each agent message once it is delivered. When the
|
|
11
|
+
* receiver ends a turn that worked on it for a while and it neither wrote
|
|
12
|
+
* back to the sender nor posted anywhere, the harness passes the receiver's
|
|
13
|
+
* last words to the sender. The receiver's open asks also hold the owner's
|
|
14
|
+
* ticket open (an agent that handed the work on has not answered yet).
|
|
15
|
+
*
|
|
16
|
+
* Cheap by construction: no model call, one transcript read per forwarded
|
|
17
|
+
* ask. Off switch: `CREWLY_AGENT_ASK_RETURN=off`.
|
|
18
|
+
*
|
|
19
|
+
* @module services/messaging/agent-ask-ledger.service
|
|
20
|
+
*/
|
|
21
|
+
import * as fsSync from 'fs';
|
|
22
|
+
import * as path from 'path';
|
|
23
|
+
import { LoggerService } from '../core/logger.service.js';
|
|
24
|
+
import { atomicWriteJson } from '../../utils/file-io.utils.js';
|
|
25
|
+
/** Tunables. */
|
|
26
|
+
export const AGENT_ASK_CONSTANTS = {
|
|
27
|
+
/** Store file under CREWLY_HOME */
|
|
28
|
+
FILE_NAME: 'agent-asks.json',
|
|
29
|
+
/** A turn this long after the delivery counts as having worked on the message (ms) */
|
|
30
|
+
MIN_WORK_MS: 2 * 60_000,
|
|
31
|
+
/**
|
|
32
|
+
* A turn that ends sooner than MIN_WORK_MS but at least this long after
|
|
33
|
+
* the delivery read it and let it go (an FYI, an "ok"): the ask is dropped
|
|
34
|
+
* without a word. Sooner than this, the turn that ended is the previous
|
|
35
|
+
* one, not the message's (ms).
|
|
36
|
+
*/
|
|
37
|
+
MIN_READ_MS: 15_000,
|
|
38
|
+
/** An ask nobody answered is forgotten after this (ms) */
|
|
39
|
+
TTL_MS: 12 * 60 * 60_000,
|
|
40
|
+
/** Asks kept in the store */
|
|
41
|
+
MAX_ASKS: 300,
|
|
42
|
+
/** Characters of the asked message quoted back to the sender */
|
|
43
|
+
EXCERPT_CHARS: 200,
|
|
44
|
+
/** Characters of the receiver's last words passed on */
|
|
45
|
+
RESULT_CHARS: 3000,
|
|
46
|
+
/** Env switch: `off` disables the ledger */
|
|
47
|
+
ENV_SWITCH: 'CREWLY_AGENT_ASK_RETURN',
|
|
48
|
+
};
|
|
49
|
+
const C = AGENT_ASK_CONSTANTS;
|
|
50
|
+
/**
|
|
51
|
+
* The member name in a session id: `flopost-dex-7f17ecbc` → `Dex`.
|
|
52
|
+
*
|
|
53
|
+
* @param session - Session name
|
|
54
|
+
* @returns Readable name
|
|
55
|
+
*/
|
|
56
|
+
export function memberName(session) {
|
|
57
|
+
const parts = session.split('-');
|
|
58
|
+
const name = parts.length >= 3 && /^[0-9a-f]{6,}$/.test(parts[parts.length - 1]) ? parts[parts.length - 2] : session;
|
|
59
|
+
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Text handed to the sender in place of the answer it never got.
|
|
63
|
+
*
|
|
64
|
+
* @param input - Names, the asked excerpt, minutes worked, the last words
|
|
65
|
+
* @returns Message for the sender
|
|
66
|
+
*/
|
|
67
|
+
export function renderReturnedAnswer(input) {
|
|
68
|
+
const head = `[ANSWER FROM ${input.target.toUpperCase()}] ${input.target} worked on your message for about ${input.minutes} min and ended without writing back to you or posting anywhere.`;
|
|
69
|
+
const asked = `Your message: "${input.excerpt}"`;
|
|
70
|
+
if (!input.lastWords) {
|
|
71
|
+
return `${head} Crewly could not read what it said. ${asked}\nAsk ${input.target} for the result.`;
|
|
72
|
+
}
|
|
73
|
+
return (`${head} Crewly is passing on its last words. ${asked}\n\n` +
|
|
74
|
+
`--- ${input.target} ---\n${input.lastWords}\n---\n\n` +
|
|
75
|
+
`If this is what you were waiting for, carry it on (for example, post it where the owner asked). No need to answer Crewly.`);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Remembers delivered agent messages and returns unsent answers. See module docs.
|
|
79
|
+
*/
|
|
80
|
+
export class AgentAskLedger {
|
|
81
|
+
deps;
|
|
82
|
+
asks = [];
|
|
83
|
+
posts = new Map();
|
|
84
|
+
logger;
|
|
85
|
+
now;
|
|
86
|
+
saving = Promise.resolve();
|
|
87
|
+
constructor(deps) {
|
|
88
|
+
this.deps = deps;
|
|
89
|
+
this.logger = LoggerService.getInstance().createComponentLogger('AgentAskLedger');
|
|
90
|
+
this.now = deps.now ?? Date.now;
|
|
91
|
+
this.load();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* A message from `sender` reached `target`'s turn.
|
|
95
|
+
*
|
|
96
|
+
* @param target - Receiving agent
|
|
97
|
+
* @param sender - Sending agent
|
|
98
|
+
* @param text - What was delivered
|
|
99
|
+
*/
|
|
100
|
+
noteDelivered(target, sender, text) {
|
|
101
|
+
if (!target || !sender || target === sender)
|
|
102
|
+
return;
|
|
103
|
+
const excerpt = text.replace(/\s+/g, ' ').trim().slice(0, C.EXCERPT_CHARS);
|
|
104
|
+
this.asks.push({ sender, target, excerpt, deliveredAt: this.now() });
|
|
105
|
+
this.prune();
|
|
106
|
+
this.save();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* `from` wrote to `to`: every open ask of `to` to `from` is answered.
|
|
110
|
+
*
|
|
111
|
+
* @param from - Writing agent
|
|
112
|
+
* @param to - Agent written to
|
|
113
|
+
*/
|
|
114
|
+
noteAnswered(from, to) {
|
|
115
|
+
const before = this.asks.length;
|
|
116
|
+
this.asks = this.asks.filter((a) => !(a.target === from && a.sender === to));
|
|
117
|
+
if (this.asks.length !== before)
|
|
118
|
+
this.save();
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* An agent posted in chat (an answer, not an interim note): asks delivered
|
|
122
|
+
* to it before now count as answered where they were asked to be.
|
|
123
|
+
*
|
|
124
|
+
* @param session - Posting agent
|
|
125
|
+
*/
|
|
126
|
+
notePost(session) {
|
|
127
|
+
if (!session)
|
|
128
|
+
return;
|
|
129
|
+
this.posts.set(session, this.now());
|
|
130
|
+
this.save();
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Asks `sender` made that are still unanswered.
|
|
134
|
+
*
|
|
135
|
+
* @param sender - Asking agent
|
|
136
|
+
* @returns Open asks, oldest first
|
|
137
|
+
*/
|
|
138
|
+
openAsksBy(sender) {
|
|
139
|
+
this.prune();
|
|
140
|
+
return this.asks.filter((a) => a.sender === sender);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* `target` finished a turn. An ask it worked on for at least
|
|
144
|
+
* {@link AGENT_ASK_CONSTANTS.MIN_WORK_MS} with no word back is answered
|
|
145
|
+
* for it: its last words go to the sender. One it answered in chat, or
|
|
146
|
+
* read in a short turn, is dropped. Never throws.
|
|
147
|
+
*
|
|
148
|
+
* @param target - Agent whose turn ended
|
|
149
|
+
* @returns Asks returned to their senders
|
|
150
|
+
*/
|
|
151
|
+
async onTurnEnded(target) {
|
|
152
|
+
try {
|
|
153
|
+
this.prune();
|
|
154
|
+
const now = this.now();
|
|
155
|
+
const mine = this.asks.filter((a) => a.target === target);
|
|
156
|
+
if (mine.length === 0)
|
|
157
|
+
return 0;
|
|
158
|
+
const posted = this.posts.get(target) ?? 0;
|
|
159
|
+
const age = (a) => now - a.deliveredAt;
|
|
160
|
+
// Answered in chat, or read and let go after a short turn: drop quietly.
|
|
161
|
+
const quiet = mine.filter((a) => posted >= a.deliveredAt || (age(a) >= C.MIN_READ_MS && age(a) < C.MIN_WORK_MS));
|
|
162
|
+
const due = mine.filter((a) => posted < a.deliveredAt && age(a) >= C.MIN_WORK_MS);
|
|
163
|
+
if (quiet.length === 0 && due.length === 0)
|
|
164
|
+
return 0;
|
|
165
|
+
const settled = new Set([...quiet, ...due]);
|
|
166
|
+
this.asks = this.asks.filter((a) => !settled.has(a));
|
|
167
|
+
this.save();
|
|
168
|
+
// One message per sender, from the oldest ask it is waiting on.
|
|
169
|
+
const bySender = new Map();
|
|
170
|
+
for (const a of due)
|
|
171
|
+
if (!bySender.has(a.sender))
|
|
172
|
+
bySender.set(a.sender, a);
|
|
173
|
+
let returned = 0;
|
|
174
|
+
for (const ask of bySender.values()) {
|
|
175
|
+
const lastWords = await this.deps.readLastWords(target, ask.deliveredAt).catch(() => null);
|
|
176
|
+
const text = renderReturnedAnswer({
|
|
177
|
+
target: (this.deps.displayName ?? memberName)(target),
|
|
178
|
+
excerpt: ask.excerpt,
|
|
179
|
+
minutes: Math.max(1, Math.round((now - ask.deliveredAt) / 60_000)),
|
|
180
|
+
lastWords: lastWords ? clipResult(lastWords) : null,
|
|
181
|
+
});
|
|
182
|
+
try {
|
|
183
|
+
await this.deps.deliver(ask.sender, text);
|
|
184
|
+
returned += 1;
|
|
185
|
+
this.logger.info('Returned an unsent answer to its asker', { from: target, to: ask.sender, hadText: !!lastWords });
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
this.logger.warn('Could not return an unsent answer', { from: target, to: ask.sender, error: err instanceof Error ? err.message : String(err) });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return returned;
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
this.logger.debug('Ask settle failed', { target, error: err instanceof Error ? err.message : String(err) });
|
|
195
|
+
return 0;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
prune() {
|
|
199
|
+
const cutoff = this.now() - C.TTL_MS;
|
|
200
|
+
this.asks = this.asks.filter((a) => a.deliveredAt >= cutoff).slice(-C.MAX_ASKS);
|
|
201
|
+
for (const [s, at] of this.posts)
|
|
202
|
+
if (at < cutoff)
|
|
203
|
+
this.posts.delete(s);
|
|
204
|
+
}
|
|
205
|
+
load() {
|
|
206
|
+
if (!this.deps.file)
|
|
207
|
+
return;
|
|
208
|
+
try {
|
|
209
|
+
const raw = JSON.parse(fsSync.readFileSync(this.deps.file, 'utf-8'));
|
|
210
|
+
if (Array.isArray(raw.asks)) {
|
|
211
|
+
this.asks = raw.asks.filter((a) => !!a && typeof a.sender === 'string' && typeof a.target === 'string' && typeof a.excerpt === 'string' && typeof a.deliveredAt === 'number');
|
|
212
|
+
}
|
|
213
|
+
if (raw.posts && typeof raw.posts === 'object') {
|
|
214
|
+
for (const [s, at] of Object.entries(raw.posts))
|
|
215
|
+
if (typeof at === 'number')
|
|
216
|
+
this.posts.set(s, at);
|
|
217
|
+
}
|
|
218
|
+
this.prune();
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
// missing or unreadable: start empty
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
save() {
|
|
225
|
+
const file = this.deps.file;
|
|
226
|
+
if (!file)
|
|
227
|
+
return;
|
|
228
|
+
const data = { asks: this.asks, posts: Object.fromEntries(this.posts) };
|
|
229
|
+
this.saving = this.saving
|
|
230
|
+
.then(async () => {
|
|
231
|
+
fsSync.mkdirSync(path.dirname(file), { recursive: true });
|
|
232
|
+
await atomicWriteJson(file, data);
|
|
233
|
+
})
|
|
234
|
+
.catch((err) => {
|
|
235
|
+
this.logger.debug('Ask ledger not saved', { error: err instanceof Error ? err.message : String(err) });
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
/** Wait for pending writes (tests). */
|
|
239
|
+
async flush() {
|
|
240
|
+
await this.saving;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* The agent's last message in a transcript since a time: the text of the
|
|
245
|
+
* newest assistant entry that has text (Claude Code JSONL or Codex rollout).
|
|
246
|
+
* Subagent (sidechain), meta and API-error entries are not the agent's words.
|
|
247
|
+
*
|
|
248
|
+
* @param text - Whole JSONL lines (a tail of the file is fine)
|
|
249
|
+
* @param kind - Transcript format
|
|
250
|
+
* @param sinceMs - Ignore entries older than this (epoch ms)
|
|
251
|
+
* @returns The text, or null when there is none
|
|
252
|
+
*/
|
|
253
|
+
export function lastWordsFromTranscript(text, kind, sinceMs) {
|
|
254
|
+
let last = null;
|
|
255
|
+
for (const line of text.split('\n')) {
|
|
256
|
+
if (line.length < 20)
|
|
257
|
+
continue;
|
|
258
|
+
if (kind === 'claude' && !(line.includes('"type":"assistant"') && line.includes('"type":"text"')))
|
|
259
|
+
continue;
|
|
260
|
+
if (kind === 'codex' && !line.includes('"agent_message"') && !line.includes('"output_text"'))
|
|
261
|
+
continue;
|
|
262
|
+
let entry;
|
|
263
|
+
try {
|
|
264
|
+
entry = JSON.parse(line);
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
const at = typeof entry.timestamp === 'string' ? Date.parse(entry.timestamp) : NaN;
|
|
270
|
+
if (!Number.isFinite(at) || at < sinceMs)
|
|
271
|
+
continue;
|
|
272
|
+
let found = null;
|
|
273
|
+
if (kind === 'claude') {
|
|
274
|
+
if (entry.type !== 'assistant' || entry.isSidechain === true || entry.isMeta === true || entry.isApiErrorMessage === true)
|
|
275
|
+
continue;
|
|
276
|
+
const content = entry.message?.content;
|
|
277
|
+
if (!Array.isArray(content))
|
|
278
|
+
continue;
|
|
279
|
+
const parts = content
|
|
280
|
+
.filter((b) => !!b && b.type === 'text' && typeof b.text === 'string')
|
|
281
|
+
.map((b) => b.text.trim())
|
|
282
|
+
.filter(Boolean);
|
|
283
|
+
if (parts.length > 0)
|
|
284
|
+
found = parts.join('\n');
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
const p = entry.payload;
|
|
288
|
+
if (!p)
|
|
289
|
+
continue;
|
|
290
|
+
if (entry.type === 'event_msg' && p.type === 'agent_message' && typeof p.message === 'string')
|
|
291
|
+
found = p.message.trim();
|
|
292
|
+
else if (entry.type === 'response_item' && p.type === 'message' && p.role === 'assistant' && Array.isArray(p.content)) {
|
|
293
|
+
const parts = p.content
|
|
294
|
+
.filter((b) => b?.type === 'output_text' && typeof b.text === 'string')
|
|
295
|
+
.map((b) => b.text.trim())
|
|
296
|
+
.filter(Boolean);
|
|
297
|
+
if (parts.length > 0)
|
|
298
|
+
found = parts.join('\n');
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (found)
|
|
302
|
+
last = found;
|
|
303
|
+
}
|
|
304
|
+
return last;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Keep the end of a long text: the conclusion is at the end.
|
|
308
|
+
*
|
|
309
|
+
* @param text - Last words
|
|
310
|
+
* @returns At most {@link AGENT_ASK_CONSTANTS.RESULT_CHARS} characters
|
|
311
|
+
*/
|
|
312
|
+
function clipResult(text) {
|
|
313
|
+
const t = text.trim();
|
|
314
|
+
return t.length <= C.RESULT_CHARS ? t : `…${t.slice(-(C.RESULT_CHARS - 1))}`;
|
|
315
|
+
}
|
|
316
|
+
// ---------------------------------------------------------------------------
|
|
317
|
+
// Singleton
|
|
318
|
+
// ---------------------------------------------------------------------------
|
|
319
|
+
let instance = null;
|
|
320
|
+
/** @returns The wired ledger, or null before boot (and when switched off) */
|
|
321
|
+
export function getAgentAskLedger() {
|
|
322
|
+
return instance;
|
|
323
|
+
}
|
|
324
|
+
/** @param ledger - The ledger to expose (null clears) */
|
|
325
|
+
export function setAgentAskLedger(ledger) {
|
|
326
|
+
instance = ledger;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Whether the ledger is switched on.
|
|
330
|
+
*
|
|
331
|
+
* @param env - Environment
|
|
332
|
+
* @returns False when `CREWLY_AGENT_ASK_RETURN=off`
|
|
333
|
+
*/
|
|
334
|
+
export function agentAskReturnEnabled(env = process.env) {
|
|
335
|
+
return (env[C.ENV_SWITCH] ?? '').toLowerCase() !== 'off';
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=agent-ask-ledger.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-ask-ledger.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/agent-ask-ledger.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boot wiring of the agent ask ledger: the store file, the transcript reader
|
|
3
|
+
* and the delivery used to hand an unsent answer to its asker.
|
|
4
|
+
*
|
|
5
|
+
* @module services/messaging/agent-ask-ledger.wiring
|
|
6
|
+
*/
|
|
7
|
+
import { AgentAskLedger } from './agent-ask-ledger.service.js';
|
|
8
|
+
/** Bytes read from the end of a transcript: a long turn's last message is near the end. */
|
|
9
|
+
export declare const LAST_WORDS_TAIL_BYTES: number;
|
|
10
|
+
/** Where a session's transcript is (see the canvas transcript locator). */
|
|
11
|
+
export type AskTranscriptLocator = (session: string) => Promise<{
|
|
12
|
+
kind: 'claude' | 'codex';
|
|
13
|
+
file: string;
|
|
14
|
+
} | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Read the end of a file as whole lines (the first partial line is dropped).
|
|
17
|
+
*
|
|
18
|
+
* @param file - Path
|
|
19
|
+
* @param maxBytes - Bytes from the end
|
|
20
|
+
* @returns Text
|
|
21
|
+
*/
|
|
22
|
+
export declare function readTail(file: string, maxBytes?: number): Promise<string>;
|
|
23
|
+
/**
|
|
24
|
+
* The last words of a session since a time, secrets masked.
|
|
25
|
+
*
|
|
26
|
+
* @param locate - Transcript locator
|
|
27
|
+
* @param session - Agent session
|
|
28
|
+
* @param sinceMs - Oldest entry to read (epoch ms)
|
|
29
|
+
* @returns Text, or null (no transcript, nothing said)
|
|
30
|
+
*/
|
|
31
|
+
export declare function readLastWords(locate: AskTranscriptLocator, session: string, sinceMs: number): Promise<string | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Create and expose the ledger. Returns null when switched off.
|
|
34
|
+
*
|
|
35
|
+
* @param deps.crewlyHome - CREWLY_HOME (store file location)
|
|
36
|
+
* @param deps.sendToAgent - Delivers a harness message to an agent
|
|
37
|
+
* @param deps.locate - Transcript locator
|
|
38
|
+
* @returns The ledger, or null
|
|
39
|
+
*/
|
|
40
|
+
export declare function createAgentAskLedger(deps: {
|
|
41
|
+
crewlyHome: string;
|
|
42
|
+
sendToAgent: (session: string, text: string) => Promise<unknown>;
|
|
43
|
+
locate: AskTranscriptLocator;
|
|
44
|
+
}): AgentAskLedger | null;
|
|
45
|
+
//# sourceMappingURL=agent-ask-ledger.wiring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-ask-ledger.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/agent-ask-ledger.wiring.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAEN,cAAc,EAId,MAAM,+BAA+B,CAAC;AAEvC,2FAA2F;AAC3F,eAAO,MAAM,qBAAqB,QAAkB,CAAC;AAErD,2EAA2E;AAC3E,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAAC;AAEnH;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAA8B,GAAG,OAAO,CAAC,MAAM,CAAC,CAYtG;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAK1H;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,MAAM,EAAE,oBAAoB,CAAC;CAC7B,GAAG,cAAc,GAAG,IAAI,CAYxB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boot wiring of the agent ask ledger: the store file, the transcript reader
|
|
3
|
+
* and the delivery used to hand an unsent answer to its asker.
|
|
4
|
+
*
|
|
5
|
+
* @module services/messaging/agent-ask-ledger.wiring
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs/promises';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { collectSecretEnvValues } from '../../utils/secret-env.js';
|
|
10
|
+
import { redactSecrets } from '../../utils/secret-redactor.js';
|
|
11
|
+
import { AGENT_ASK_CONSTANTS, AgentAskLedger, agentAskReturnEnabled, lastWordsFromTranscript, setAgentAskLedger, } from './agent-ask-ledger.service.js';
|
|
12
|
+
/** Bytes read from the end of a transcript: a long turn's last message is near the end. */
|
|
13
|
+
export const LAST_WORDS_TAIL_BYTES = 2 * 1024 * 1024;
|
|
14
|
+
/**
|
|
15
|
+
* Read the end of a file as whole lines (the first partial line is dropped).
|
|
16
|
+
*
|
|
17
|
+
* @param file - Path
|
|
18
|
+
* @param maxBytes - Bytes from the end
|
|
19
|
+
* @returns Text
|
|
20
|
+
*/
|
|
21
|
+
export async function readTail(file, maxBytes = LAST_WORDS_TAIL_BYTES) {
|
|
22
|
+
const handle = await fs.open(file, 'r');
|
|
23
|
+
try {
|
|
24
|
+
const { size } = await handle.stat();
|
|
25
|
+
const start = Math.max(0, size - maxBytes);
|
|
26
|
+
const buf = Buffer.alloc(size - start);
|
|
27
|
+
await handle.read(buf, 0, buf.length, start);
|
|
28
|
+
const text = buf.toString('utf-8');
|
|
29
|
+
return start > 0 ? text.slice(text.indexOf('\n') + 1) : text;
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
await handle.close();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The last words of a session since a time, secrets masked.
|
|
37
|
+
*
|
|
38
|
+
* @param locate - Transcript locator
|
|
39
|
+
* @param session - Agent session
|
|
40
|
+
* @param sinceMs - Oldest entry to read (epoch ms)
|
|
41
|
+
* @returns Text, or null (no transcript, nothing said)
|
|
42
|
+
*/
|
|
43
|
+
export async function readLastWords(locate, session, sinceMs) {
|
|
44
|
+
const target = await locate(session);
|
|
45
|
+
if (!target)
|
|
46
|
+
return null;
|
|
47
|
+
const words = lastWordsFromTranscript(await readTail(target.file), target.kind, sinceMs);
|
|
48
|
+
return words ? redactSecrets(words, collectSecretEnvValues(process.env)) : null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create and expose the ledger. Returns null when switched off.
|
|
52
|
+
*
|
|
53
|
+
* @param deps.crewlyHome - CREWLY_HOME (store file location)
|
|
54
|
+
* @param deps.sendToAgent - Delivers a harness message to an agent
|
|
55
|
+
* @param deps.locate - Transcript locator
|
|
56
|
+
* @returns The ledger, or null
|
|
57
|
+
*/
|
|
58
|
+
export function createAgentAskLedger(deps) {
|
|
59
|
+
if (!agentAskReturnEnabled()) {
|
|
60
|
+
setAgentAskLedger(null);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const ledger = new AgentAskLedger({
|
|
64
|
+
file: path.join(deps.crewlyHome, AGENT_ASK_CONSTANTS.FILE_NAME),
|
|
65
|
+
readLastWords: (session, sinceMs) => readLastWords(deps.locate, session, sinceMs),
|
|
66
|
+
deliver: deps.sendToAgent,
|
|
67
|
+
});
|
|
68
|
+
setAgentAskLedger(ledger);
|
|
69
|
+
return ledger;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=agent-ask-ledger.wiring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-ask-ledger.wiring.js","sourceRoot":"","sources":["../../../../../../backend/src/services/messaging/agent-ask-ledger.wiring.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EACN,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,iBAAiB,GACjB,MAAM,+BAA+B,CAAC;AAEvC,2FAA2F;AAC3F,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAKrD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,WAAmB,qBAAqB;IACpF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC;QACJ,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC;QACvC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,CAAC;YAAS,CAAC;QACV,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;AACF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAA4B,EAAE,OAAe,EAAE,OAAe;IACjG,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,KAAK,GAAG,uBAAuB,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzF,OAAO,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAIpC;IACA,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;QAC9B,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC;QACjC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,SAAS,CAAC;QAC/D,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC;QACjF,OAAO,EAAE,IAAI,CAAC,WAAW;KACzB,CAAC,CAAC;IACH,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC;AACf,CAAC"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { type ReplyDestination, type ReplyHints, type ReplyReference, type ReplyResolverDeps } from './reply-destination-resolver.js';
|
|
10
10
|
import { type WorkDestinationDeps } from './work-item-destination.wiring.js';
|
|
11
|
+
import { type TurnTrigger } from '../trace/turn-trigger.js';
|
|
11
12
|
/** Forget recent deliveries (tests). */
|
|
12
13
|
export declare function resetReplyDeliveryGuardForTesting(): void;
|
|
13
14
|
/** Delivery into a chat-v2 conversation (chat.controller `deliverAgentReplyToConversation`). */
|
|
@@ -43,6 +44,17 @@ export interface ReplyDeliveryDeps {
|
|
|
43
44
|
* with `reply --decision D-n`. Omitted: no card lookup.
|
|
44
45
|
*/
|
|
45
46
|
decisionOfCardThread?: (slackChannelId: string, threadTs: string) => Promise<string | null>;
|
|
47
|
+
/**
|
|
48
|
+
* What started the agent's current turn (turn-trigger.ts), for the
|
|
49
|
+
* "Triggered by" line and the provenance stored on the row. Omitted: none.
|
|
50
|
+
*/
|
|
51
|
+
turnTrigger?: (session: string) => TurnTrigger | null;
|
|
52
|
+
/** The owner wrote to the agent in this conversation recently (its post there is an answer). Omitted: no. */
|
|
53
|
+
ownerAskedRecently?: (session: string, conversationId: string) => boolean;
|
|
54
|
+
/** The session's current run trace id. Omitted: none. */
|
|
55
|
+
currentTrace?: (session: string) => string | null;
|
|
56
|
+
/** A conversation as the owner knows it (`#content-team`, `the DM with Ella`). Omitted: unnamed. */
|
|
57
|
+
conversationPlace?: (conversationId: string) => string | null;
|
|
46
58
|
}
|
|
47
59
|
/** What a delivery did. */
|
|
48
60
|
export type ReplyDelivery = {
|
|
@@ -89,6 +101,25 @@ export interface DeliverReplyInput {
|
|
|
89
101
|
* @returns Where it landed, or an English error
|
|
90
102
|
*/
|
|
91
103
|
export declare function deliverReply(input: DeliverReplyInput, deps?: ReplyDeliveryDeps): Promise<ReplyDelivery>;
|
|
104
|
+
/**
|
|
105
|
+
* Provenance for a post an agent makes straight into a conversation
|
|
106
|
+
* (`reply-channel`, `POST /chat/channels/:id/messages`), outside
|
|
107
|
+
* {@link deliverReply}: the record to store and the text with the
|
|
108
|
+
* "Triggered by" line when one is shown. Never throws.
|
|
109
|
+
*
|
|
110
|
+
* @param input - Agent, conversation, text, interim flag
|
|
111
|
+
* @param deps - Collaborators (default: the real ones)
|
|
112
|
+
* @returns The text to store and the record, if any
|
|
113
|
+
*/
|
|
114
|
+
export declare function provenanceForAgentPost(input: {
|
|
115
|
+
session: string;
|
|
116
|
+
conversationId: string;
|
|
117
|
+
content: string;
|
|
118
|
+
interim?: boolean;
|
|
119
|
+
}, deps?: Pick<ReplyDeliveryDeps, 'resolver' | 'turnTrigger' | 'ownerAskedRecently' | 'currentTrace' | 'conversationPlace'>): Promise<{
|
|
120
|
+
content: string;
|
|
121
|
+
triggeredBy?: Record<string, unknown>;
|
|
122
|
+
}>;
|
|
92
123
|
/**
|
|
93
124
|
* The Slack place (channel + thread) the resolver gives, without posting —
|
|
94
125
|
* for files and the `[DONE]` notice. Ticket threads that do not exist yet
|
|
@@ -119,4 +150,22 @@ export declare function notDelivered(why: string, fix: string): string;
|
|
|
119
150
|
* @returns Deps
|
|
120
151
|
*/
|
|
121
152
|
export declare function defaultReplyDeliveryDeps(): Promise<ReplyDeliveryDeps>;
|
|
153
|
+
/** The chat-v2 lookups {@link chatConversationPlace} uses. */
|
|
154
|
+
interface ChatChannelLookup {
|
|
155
|
+
getChannelForBridge(id: string): {
|
|
156
|
+
name: string;
|
|
157
|
+
type?: string;
|
|
158
|
+
agentSession?: string;
|
|
159
|
+
} | null;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* A chat conversation as the owner knows it: `#name` for a channel or room,
|
|
163
|
+
* `the DM with <agent>` for a direct conversation.
|
|
164
|
+
*
|
|
165
|
+
* @param chat - chat-v2 lookups, or null
|
|
166
|
+
* @param conversationId - chat-v2 channel id
|
|
167
|
+
* @returns The place, or null when unknown
|
|
168
|
+
*/
|
|
169
|
+
export declare function chatConversationPlace(chat: ChatChannelLookup | null, conversationId: string): string | null;
|
|
170
|
+
export {};
|
|
122
171
|
//# sourceMappingURL=reply-destination.wiring.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reply-destination.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/reply-destination.wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,cAAc,EAEnB,KAAK,iBAAiB,EACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAwD,KAAK,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"reply-destination.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/reply-destination.wiring.ts"],"names":[],"mappings":"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"}
|