wicked-crew 0.14.0 → 0.14.2
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/api/roster-standing.d.ts.map +1 -1
- package/dist/api/roster-standing.js +2 -0
- package/dist/api/roster-standing.js.map +1 -1
- package/dist/api/routes.d.ts +3 -0
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +36 -3
- package/dist/api/routes.js.map +1 -1
- package/dist/api/search-index.d.ts +132 -0
- package/dist/api/search-index.d.ts.map +1 -0
- package/dist/api/search-index.js +345 -0
- package/dist/api/search-index.js.map +1 -0
- package/dist/api/search-routes.d.ts +102 -0
- package/dist/api/search-routes.d.ts.map +1 -0
- package/dist/api/search-routes.js +578 -0
- package/dist/api/search-routes.js.map +1 -0
- package/dist/api/seat-bench-trail.d.ts +14 -0
- package/dist/api/seat-bench-trail.d.ts.map +1 -0
- package/dist/api/seat-bench-trail.js +70 -0
- package/dist/api/seat-bench-trail.js.map +1 -0
- package/dist/api/seat-health.d.ts +51 -2
- package/dist/api/seat-health.d.ts.map +1 -1
- package/dist/api/seat-health.js +58 -9
- package/dist/api/seat-health.js.map +1 -1
- package/dist/api/seat-standing.d.ts +7 -0
- package/dist/api/seat-standing.d.ts.map +1 -1
- package/dist/api/seat-standing.js +12 -0
- package/dist/api/seat-standing.js.map +1 -1
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +16 -0
- package/dist/api/server.js.map +1 -1
- package/dist/studio/assets/{index-BA69zWzx.js → index-BjH2WWnH.js} +211 -211
- package/dist/studio/editors/wicked-deck/editor.json +1 -1
- package/dist/studio/editors/wicked-deck/index.html +1 -1
- package/dist/studio/editors/wicked-doc/editor.json +1 -1
- package/dist/studio/editors/wicked-doc/index.html +1 -1
- package/dist/studio/editors/wicked-page/editor.json +1 -1
- package/dist/studio/editors/wicked-page/index.html +1 -1
- package/dist/studio/editors/wicked-video/editor.json +1 -1
- package/dist/studio/editors/wicked-video/index.html +1 -1
- package/dist/studio/index.html +1 -1
- package/dist/studio/testid-inventory.json +40 -4
- package/endpoint-manifest.json +11 -1
- package/package.json +3 -3
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `GET /search` (api-types 0.127.0): one query over runs, projects, repos, transcripts (chat
|
|
3
|
+
* transcripts and unit outputs), rules, memories and documents.
|
|
4
|
+
*
|
|
5
|
+
* The index ({@link SearchIndex}) is built LAZILY: nothing is read until the first search, and that
|
|
6
|
+
* read runs off the request path — the first request waits a short while for it and answers with
|
|
7
|
+
* the sources still reading marked `indexing`. After that the index follows the daemon:
|
|
8
|
+
* - engine frames: a run's lifecycle re-reads the run list (debounced), a finished unit's output is
|
|
9
|
+
* read once, a chat reply re-reads that chat's transcript, a closed chat leaves;
|
|
10
|
+
* - the daemon's own writes: a successful mutating request re-reads the sources its path can change
|
|
11
|
+
* (`noteWrite`), debounced;
|
|
12
|
+
* - sources written outside the daemon (memories, rules a worker lands, documents) are also re-read
|
|
13
|
+
* when a search finds them older than their TTL — in the background, never on the request.
|
|
14
|
+
* A source that fails to read is `unavailable` with its reason; the others still answer.
|
|
15
|
+
*/
|
|
16
|
+
import { open, readdir, stat } from 'node:fs/promises';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { API_PREFIX } from './api-prefix.js';
|
|
19
|
+
import { coreUnitId } from './evidence.js';
|
|
20
|
+
import { jobTitle } from './job-title.js';
|
|
21
|
+
import { MAX_QUERY_CHARS, MIN_QUERY_CHARS, SEARCH_TYPES, SearchIndex, parseQuery, } from './search-index.js';
|
|
22
|
+
const SOURCES_OF = {
|
|
23
|
+
run: ['run'],
|
|
24
|
+
project: ['project'],
|
|
25
|
+
repo: ['repo'],
|
|
26
|
+
transcript: ['chat', 'run'],
|
|
27
|
+
rule: ['rule'],
|
|
28
|
+
memory: ['memory'],
|
|
29
|
+
doc: ['doc'],
|
|
30
|
+
};
|
|
31
|
+
/** How stale a source may get before a search re-reads it in the background (ms). */
|
|
32
|
+
const DEFAULT_TTL = {
|
|
33
|
+
run: 5 * 60_000,
|
|
34
|
+
project: 60_000,
|
|
35
|
+
repo: 60_000,
|
|
36
|
+
chat: 60_000,
|
|
37
|
+
rule: 60_000,
|
|
38
|
+
memory: 5 * 60_000,
|
|
39
|
+
doc: 2 * 60_000,
|
|
40
|
+
};
|
|
41
|
+
/** Engine frames that change the run list. */
|
|
42
|
+
const RUN_FRAMES = new Set([
|
|
43
|
+
'sessionStarted', 'unitPlanned', 'unitDistributed', 'unitDispatched', 'unitExecuting', 'gateDecided', 'unitDone',
|
|
44
|
+
'unitDenied', 'awaitingHuman', 'resumed', 'runCancelled', 'sessionFailed', 'sessionCompleted', 'unitReassigned',
|
|
45
|
+
]);
|
|
46
|
+
/** The largest slice of a chat transcript file read (its head and tail). */
|
|
47
|
+
const CHAT_READ_BYTES = 2 * 1024 * 1024;
|
|
48
|
+
/** Unit outputs read per run-list load that the index has not tried yet (newest runs first). */
|
|
49
|
+
const UNIT_BACKFILL_MAX = 300;
|
|
50
|
+
/** Unit outputs read at once. */
|
|
51
|
+
const UNIT_CONCURRENCY = 2;
|
|
52
|
+
const message = (err) => (err instanceof Error ? err.message : String(err));
|
|
53
|
+
const secondsToMs = (s) => (s === undefined ? null : s * 1000);
|
|
54
|
+
const firstLine = (s, max) => {
|
|
55
|
+
const line = s.trim().split('\n')[0] ?? '';
|
|
56
|
+
return line.length > max ? `${line.slice(0, max - 1)}…` : line;
|
|
57
|
+
};
|
|
58
|
+
export class SearchService {
|
|
59
|
+
index;
|
|
60
|
+
deps;
|
|
61
|
+
states = new Map();
|
|
62
|
+
/** Off until the first search: before it, frames and writes cost nothing. */
|
|
63
|
+
active = false;
|
|
64
|
+
closed = false;
|
|
65
|
+
/** The last run list, for titling unit transcripts. */
|
|
66
|
+
runsById = new Map();
|
|
67
|
+
/** Unit outputs read (or found empty) — a backfill does not read them again; a `unitDone` does. */
|
|
68
|
+
unitsTried = new Set();
|
|
69
|
+
unitQueue = [];
|
|
70
|
+
unitWorkers = 0;
|
|
71
|
+
chatTimers = new Map();
|
|
72
|
+
constructor(deps) {
|
|
73
|
+
this.deps = deps;
|
|
74
|
+
this.index = new SearchIndex(deps.index);
|
|
75
|
+
for (const s of ['run', 'project', 'repo', 'chat', 'rule', 'memory', 'doc']) {
|
|
76
|
+
this.states.set(s, { loadedAt: null, loading: null, again: false, error: null, timer: null });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
state(s) {
|
|
80
|
+
return this.states.get(s);
|
|
81
|
+
}
|
|
82
|
+
ttl(s) {
|
|
83
|
+
return this.deps.ttlMs?.[s] ?? DEFAULT_TTL[s];
|
|
84
|
+
}
|
|
85
|
+
/** Whether the source exists on this daemon. */
|
|
86
|
+
available(s) {
|
|
87
|
+
if (s === 'chat')
|
|
88
|
+
return this.deps.chatsDir !== undefined;
|
|
89
|
+
if (s === 'memory')
|
|
90
|
+
return this.deps.memories !== undefined;
|
|
91
|
+
if (s === 'doc')
|
|
92
|
+
return this.deps.docs !== undefined;
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
close() {
|
|
96
|
+
this.closed = true;
|
|
97
|
+
for (const st of this.states.values())
|
|
98
|
+
if (st.timer !== null)
|
|
99
|
+
clearTimeout(st.timer);
|
|
100
|
+
for (const t of this.chatTimers.values())
|
|
101
|
+
clearTimeout(t);
|
|
102
|
+
this.chatTimers.clear();
|
|
103
|
+
this.unitQueue.length = 0;
|
|
104
|
+
}
|
|
105
|
+
// ── Keeping current ──────────────────────────────────────────────────────────────────────────
|
|
106
|
+
/** One engine frame (the daemon's fan-in calls this for every frame; cheap until the first search). */
|
|
107
|
+
ingest(event) {
|
|
108
|
+
if (!this.active || this.closed)
|
|
109
|
+
return;
|
|
110
|
+
const f = event;
|
|
111
|
+
if (RUN_FRAMES.has(event.type))
|
|
112
|
+
this.markDirty('run');
|
|
113
|
+
if ((event.type === 'unitDone' || event.type === 'unitDenied') && typeof f['session'] === 'string' && typeof f['ord'] === 'number') {
|
|
114
|
+
this.enqueueUnit(f['session'], f['ord'], true);
|
|
115
|
+
}
|
|
116
|
+
if (event.type === 'chatReply' && typeof f['chat'] === 'string')
|
|
117
|
+
this.markChat(f['chat']);
|
|
118
|
+
if (event.type === 'chatClosed' && typeof f['chat'] === 'string') {
|
|
119
|
+
const t = this.chatTimers.get(f['chat']);
|
|
120
|
+
if (t !== undefined)
|
|
121
|
+
clearTimeout(t);
|
|
122
|
+
this.chatTimers.delete(f['chat']);
|
|
123
|
+
this.index.remove('transcript', `chat:${f['chat']}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** A mutating request answered 2xx/3xx: re-read what its path can change. */
|
|
127
|
+
noteWrite(method, url) {
|
|
128
|
+
if (!this.active || this.closed || method === 'GET' || method === 'HEAD' || method === 'OPTIONS')
|
|
129
|
+
return;
|
|
130
|
+
const path = (url.split('?')[0] ?? '').replace(API_PREFIX, '');
|
|
131
|
+
const chat = /^\/chats\/([^/]+)\/messages$/.exec(path);
|
|
132
|
+
if (chat !== null && chat[1] !== undefined) {
|
|
133
|
+
this.markChat(decodeURIComponent(chat[1]));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const touched = new Set();
|
|
137
|
+
if (path.startsWith('/projects')) {
|
|
138
|
+
touched.add('project');
|
|
139
|
+
touched.add('run');
|
|
140
|
+
if (path.includes('/interactive'))
|
|
141
|
+
touched.add('doc');
|
|
142
|
+
}
|
|
143
|
+
if (path.startsWith('/repos'))
|
|
144
|
+
touched.add('repo');
|
|
145
|
+
if (path.startsWith('/runs'))
|
|
146
|
+
touched.add('run');
|
|
147
|
+
if (path.startsWith('/interactive'))
|
|
148
|
+
touched.add('doc');
|
|
149
|
+
if (path.startsWith('/memory'))
|
|
150
|
+
touched.add('memory');
|
|
151
|
+
if (/^\/(proposals|decisions)/.test(path)) {
|
|
152
|
+
touched.add('memory');
|
|
153
|
+
touched.add('rule');
|
|
154
|
+
}
|
|
155
|
+
if (/^\/(governance|steering|policies|rules|editors)/.test(path))
|
|
156
|
+
touched.add('rule');
|
|
157
|
+
for (const s of touched)
|
|
158
|
+
this.markDirty(s);
|
|
159
|
+
}
|
|
160
|
+
markDirty(s) {
|
|
161
|
+
const st = this.state(s);
|
|
162
|
+
if (st.loadedAt === null && st.loading === null)
|
|
163
|
+
return; // never read: the first search reads it
|
|
164
|
+
// Already scheduled: that re-read will see this change too. (Never pushed back, so a steady stream
|
|
165
|
+
// of frames cannot starve it: a change waits at most one debounce.)
|
|
166
|
+
if (st.timer !== null)
|
|
167
|
+
return;
|
|
168
|
+
st.timer = setTimeout(() => { st.timer = null; void this.refresh(s); }, this.deps.debounceMs ?? 400);
|
|
169
|
+
st.timer.unref?.();
|
|
170
|
+
}
|
|
171
|
+
markChat(chatId) {
|
|
172
|
+
if (!this.available('chat'))
|
|
173
|
+
return;
|
|
174
|
+
if (this.chatTimers.has(chatId))
|
|
175
|
+
return; // the scheduled read will see this reply too
|
|
176
|
+
const t = setTimeout(() => {
|
|
177
|
+
this.chatTimers.delete(chatId);
|
|
178
|
+
void this.readChat(chatId).catch((err) => this.deps.log?.(`[search] chat ${chatId} transcript unread: ${message(err)}`));
|
|
179
|
+
}, this.deps.debounceMs ?? 400);
|
|
180
|
+
t.unref?.();
|
|
181
|
+
this.chatTimers.set(chatId, t);
|
|
182
|
+
}
|
|
183
|
+
/** Re-read one source (coalesced: a refresh asked for mid-read runs once more after it). */
|
|
184
|
+
refresh(s) {
|
|
185
|
+
const st = this.state(s);
|
|
186
|
+
if (this.closed || !this.available(s))
|
|
187
|
+
return Promise.resolve();
|
|
188
|
+
if (st.loading !== null) {
|
|
189
|
+
st.again = true;
|
|
190
|
+
return st.loading;
|
|
191
|
+
}
|
|
192
|
+
st.loading = (async () => {
|
|
193
|
+
try {
|
|
194
|
+
await this.load(s);
|
|
195
|
+
st.error = null;
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
st.error = message(err);
|
|
199
|
+
this.deps.log?.(`[search] ${s} not readable: ${st.error}`);
|
|
200
|
+
}
|
|
201
|
+
finally {
|
|
202
|
+
st.loadedAt = Date.now();
|
|
203
|
+
st.loading = null;
|
|
204
|
+
}
|
|
205
|
+
if (st.again && !this.closed) {
|
|
206
|
+
st.again = false;
|
|
207
|
+
await this.refresh(s);
|
|
208
|
+
}
|
|
209
|
+
})();
|
|
210
|
+
return st.loading;
|
|
211
|
+
}
|
|
212
|
+
/** Before a query: read what was never read, re-read what is past its TTL (both off the request). */
|
|
213
|
+
ensure(types) {
|
|
214
|
+
this.active = true;
|
|
215
|
+
const first = [];
|
|
216
|
+
const seen = new Set();
|
|
217
|
+
for (const t of types) {
|
|
218
|
+
for (const s of SOURCES_OF[t]) {
|
|
219
|
+
if (seen.has(s) || !this.available(s))
|
|
220
|
+
continue;
|
|
221
|
+
seen.add(s);
|
|
222
|
+
const st = this.state(s);
|
|
223
|
+
if (st.loadedAt === null)
|
|
224
|
+
first.push(st.loading ?? this.refresh(s));
|
|
225
|
+
else if (st.loading === null && Date.now() - st.loadedAt > this.ttl(s))
|
|
226
|
+
void this.refresh(s);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return first;
|
|
230
|
+
}
|
|
231
|
+
// ── The sources ──────────────────────────────────────────────────────────────────────────────
|
|
232
|
+
async load(s) {
|
|
233
|
+
switch (s) {
|
|
234
|
+
case 'run': return this.loadRuns();
|
|
235
|
+
case 'project': {
|
|
236
|
+
const projects = await this.deps.projectList();
|
|
237
|
+
this.index.replaceType('project', projects.filter((p) => p.id !== 'default').map((p) => ({
|
|
238
|
+
type: 'project', id: p.id, title: p.name, body: p.description ?? '',
|
|
239
|
+
updatedAt: p.updated_at, projectId: p.id, status: p.status,
|
|
240
|
+
target: { kind: 'project', project_id: p.id }, boost: p.status === 'active' ? 0 : -3,
|
|
241
|
+
})));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
case 'repo': {
|
|
245
|
+
const repos = await this.deps.listRepos();
|
|
246
|
+
this.index.replaceType('repo', repos.map((r) => ({
|
|
247
|
+
type: 'repo', id: r.id, title: r.name,
|
|
248
|
+
body: [r.root_path, r.git_url ?? '', r.default_branch].filter((x) => x !== '').join('\n'),
|
|
249
|
+
updatedAt: r.registered_at > 1e12 ? r.registered_at : r.registered_at * 1000, projectId: null, status: null,
|
|
250
|
+
target: { kind: 'repo', repo_id: r.id },
|
|
251
|
+
})));
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
case 'rule': {
|
|
255
|
+
const rules = await this.deps.listRules();
|
|
256
|
+
this.index.replaceType('rule', rules.map((r) => ({
|
|
257
|
+
type: 'rule', id: r.id, title: firstLine(r.statement, 140) || r.id,
|
|
258
|
+
body: [r.statement, r.criteria ?? '', ...(r.obligations ?? []), r.id, r.steering_type ?? '', r.rule_type].filter((x) => x !== '').join('\n'),
|
|
259
|
+
updatedAt: r.created_at !== undefined ? r.created_at * 1000 : null,
|
|
260
|
+
projectId: r.targets.project ?? null,
|
|
261
|
+
status: r.retired === true ? 'retired' : r.severity,
|
|
262
|
+
target: { kind: 'rule', rule_id: r.id, steering_type: r.steering_type ?? null },
|
|
263
|
+
boost: r.retired === true ? -4 : 0,
|
|
264
|
+
})));
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
case 'memory': {
|
|
268
|
+
const items = await this.deps.memories();
|
|
269
|
+
this.index.replaceType('memory', items.map((m) => ({
|
|
270
|
+
type: 'memory', id: m.id, title: firstLine(m.content, 140) || m.id,
|
|
271
|
+
body: [m.content, ...Object.entries(m.facets).map(([k, v]) => `${k}:${v}`), m.tier].join('\n'),
|
|
272
|
+
updatedAt: m.created_at !== undefined && m.created_at !== null ? m.created_at * 1000 : null,
|
|
273
|
+
projectId: /(?:^|\/)project:([^/]+)/.exec(m.scope)?.[1] ?? null,
|
|
274
|
+
status: m.tier,
|
|
275
|
+
target: { kind: 'memory', memory_id: m.id, scope: m.scope },
|
|
276
|
+
})));
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
case 'doc': {
|
|
280
|
+
const rows = await this.deps.docs();
|
|
281
|
+
this.index.replaceType('doc', rows.filter((d) => d.retired !== true).map((d) => {
|
|
282
|
+
const at = d.updatedAt !== null ? Date.parse(d.updatedAt) : NaN;
|
|
283
|
+
return {
|
|
284
|
+
type: 'doc', id: `${d.projectId}/${d.name}`, title: d.name,
|
|
285
|
+
body: [d.name.replace(/[-_.]+/g, ' '), d.kind].join('\n'),
|
|
286
|
+
updatedAt: Number.isFinite(at) ? at : null, projectId: d.projectId === 'default' ? null : d.projectId,
|
|
287
|
+
status: d.kind, target: { kind: 'doc', project_id: d.projectId, doc: d.name },
|
|
288
|
+
};
|
|
289
|
+
}));
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
case 'chat': return this.loadChats();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
runUpdatedAt(id) {
|
|
296
|
+
return secondsToMs(this.deps.runFacts?.endedAtFor(id) ?? this.deps.runFacts?.createdAtFor(id));
|
|
297
|
+
}
|
|
298
|
+
async loadRuns() {
|
|
299
|
+
const views = await this.deps.sessionsDetail();
|
|
300
|
+
this.runsById = new Map(views.map((v) => [v.session.id, v]));
|
|
301
|
+
this.index.replaceType('run', views.map((v) => {
|
|
302
|
+
const s = v.session;
|
|
303
|
+
const archived = s.archived_at !== null && s.archived_at !== undefined;
|
|
304
|
+
const unitText = v.units.flatMap((u) => [u.description, u.denial_reason ?? '']).filter((x) => x !== '');
|
|
305
|
+
return {
|
|
306
|
+
type: 'run', id: s.id, title: jobTitle(s.problem) || s.id,
|
|
307
|
+
body: [s.problem, ...unitText, s.workflow_id ?? '', s.repo_ref ?? '', s.id].filter((x) => x !== '').join('\n'),
|
|
308
|
+
updatedAt: this.runUpdatedAt(s.id), projectId: this.deps.projectOf(s.id) ?? null,
|
|
309
|
+
status: archived ? 'archived' : s.status,
|
|
310
|
+
target: { kind: 'run', run_id: s.id, chat_id: this.deps.runFacts?.chatIdFor(s.id) ?? null },
|
|
311
|
+
boost: archived ? -3 : 0,
|
|
312
|
+
};
|
|
313
|
+
}));
|
|
314
|
+
// A run that left the list takes its unit transcripts with it.
|
|
315
|
+
this.index.removeWhere('transcript', (id) => id.startsWith('unit:') && !this.runsById.has(id.slice(5, id.lastIndexOf(':'))));
|
|
316
|
+
// Backfill: outputs of finished units not read yet, newest runs first, bounded per load.
|
|
317
|
+
const newest = [...views].sort((a, b) => (this.runUpdatedAt(b.session.id) ?? 0) - (this.runUpdatedAt(a.session.id) ?? 0));
|
|
318
|
+
let queued = 0;
|
|
319
|
+
for (const v of newest) {
|
|
320
|
+
for (const u of v.units) {
|
|
321
|
+
if (queued >= UNIT_BACKFILL_MAX)
|
|
322
|
+
break;
|
|
323
|
+
if (u.status !== 'done' && u.status !== 'rejected')
|
|
324
|
+
continue;
|
|
325
|
+
if (this.unitsTried.has(`${v.session.id}:${u.ord}`))
|
|
326
|
+
continue;
|
|
327
|
+
this.enqueueUnit(v.session.id, u.ord, false);
|
|
328
|
+
queued += 1;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
enqueueUnit(runId, ord, again) {
|
|
333
|
+
const key = `${runId}:${ord}`;
|
|
334
|
+
if (again)
|
|
335
|
+
this.unitsTried.delete(key);
|
|
336
|
+
if (this.unitsTried.has(key) || this.unitQueue.some((q) => q.runId === runId && q.ord === ord))
|
|
337
|
+
return;
|
|
338
|
+
this.unitQueue.push({ runId, ord });
|
|
339
|
+
this.drainUnits();
|
|
340
|
+
}
|
|
341
|
+
drainUnits() {
|
|
342
|
+
while (this.unitWorkers < UNIT_CONCURRENCY && this.unitQueue.length > 0 && !this.closed) {
|
|
343
|
+
const next = this.unitQueue.shift();
|
|
344
|
+
this.unitWorkers += 1;
|
|
345
|
+
void this.readUnit(next.runId, next.ord)
|
|
346
|
+
.catch((err) => this.deps.log?.(`[search] unit ${next.runId}:${next.ord} output unread: ${message(err)}`))
|
|
347
|
+
.finally(() => { this.unitWorkers -= 1; this.drainUnits(); });
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
async readUnit(runId, ord) {
|
|
351
|
+
this.unitsTried.add(`${runId}:${ord}`);
|
|
352
|
+
const view = this.runsById.get(runId);
|
|
353
|
+
const unit = view?.units.find((u) => u.ord === ord);
|
|
354
|
+
const unitId = unit !== undefined ? coreUnitId(runId, unit) : `${runId}:u${ord}`;
|
|
355
|
+
const output = await this.deps.workOutput(unitId);
|
|
356
|
+
const id = `unit:${runId}:${ord}`;
|
|
357
|
+
if (output === null || output.trim() === '') {
|
|
358
|
+
this.index.remove('transcript', id);
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const runTitle = view !== undefined ? jobTitle(view.session.problem) || runId : runId;
|
|
362
|
+
this.index.upsert({
|
|
363
|
+
type: 'transcript', id,
|
|
364
|
+
title: `${runTitle} · ${unit?.description.trim() || `step ${ord + 1}`}`,
|
|
365
|
+
body: output,
|
|
366
|
+
updatedAt: this.runUpdatedAt(runId), projectId: this.deps.projectOf(runId) ?? null,
|
|
367
|
+
status: unit?.status ?? null,
|
|
368
|
+
target: { kind: 'unit', run_id: runId, ord, chat_id: this.deps.runFacts?.chatIdFor(runId) ?? null },
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
async loadChats() {
|
|
372
|
+
const dir = this.deps.chatsDir();
|
|
373
|
+
let files;
|
|
374
|
+
try {
|
|
375
|
+
files = (await readdir(dir)).filter((f) => f.endsWith('.jsonl'));
|
|
376
|
+
}
|
|
377
|
+
catch (err) {
|
|
378
|
+
if (err.code === 'ENOENT')
|
|
379
|
+
files = [];
|
|
380
|
+
else
|
|
381
|
+
throw err;
|
|
382
|
+
}
|
|
383
|
+
const live = new Set(files.map((f) => f.slice(0, -6)));
|
|
384
|
+
this.index.removeWhere('transcript', (id) => id.startsWith('chat:') && !live.has(id.slice(5)));
|
|
385
|
+
for (const chatId of live)
|
|
386
|
+
await this.readChat(chatId);
|
|
387
|
+
}
|
|
388
|
+
/** One chat's transcript file: its head and tail (bounded), as one entity. */
|
|
389
|
+
async readChat(chatId) {
|
|
390
|
+
if (this.closed || !/^[A-Za-z0-9._-]+$/.test(chatId))
|
|
391
|
+
return;
|
|
392
|
+
const file = join(this.deps.chatsDir(), `${chatId}.jsonl`);
|
|
393
|
+
let text;
|
|
394
|
+
try {
|
|
395
|
+
const size = (await stat(file)).size;
|
|
396
|
+
const fh = await open(file, 'r');
|
|
397
|
+
try {
|
|
398
|
+
if (size <= CHAT_READ_BYTES) {
|
|
399
|
+
text = (await fh.readFile('utf8'));
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
const half = CHAT_READ_BYTES / 2;
|
|
403
|
+
const head = Buffer.alloc(half);
|
|
404
|
+
const tail = Buffer.alloc(half);
|
|
405
|
+
await fh.read(head, 0, half, 0);
|
|
406
|
+
await fh.read(tail, 0, half, size - half);
|
|
407
|
+
// Cut lines are dropped: the head's last and the tail's first.
|
|
408
|
+
const h = head.toString('utf8');
|
|
409
|
+
const t = tail.toString('utf8');
|
|
410
|
+
text = `${h.slice(0, h.lastIndexOf('\n'))}\n${t.slice(t.indexOf('\n') + 1)}`;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
finally {
|
|
414
|
+
await fh.close();
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
catch (err) {
|
|
418
|
+
if (err.code === 'ENOENT') {
|
|
419
|
+
this.index.remove('transcript', `chat:${chatId}`);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
throw err;
|
|
423
|
+
}
|
|
424
|
+
let title = '';
|
|
425
|
+
let last = null;
|
|
426
|
+
const parts = [];
|
|
427
|
+
for (const line of text.split('\n')) {
|
|
428
|
+
if (line.trim() === '')
|
|
429
|
+
continue;
|
|
430
|
+
let rec;
|
|
431
|
+
try {
|
|
432
|
+
rec = JSON.parse(line);
|
|
433
|
+
}
|
|
434
|
+
catch {
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
if (typeof rec['at'] === 'number')
|
|
438
|
+
last = rec['at'];
|
|
439
|
+
const said = typeof rec['text'] === 'string' ? rec['text'] : '';
|
|
440
|
+
if (said === '')
|
|
441
|
+
continue;
|
|
442
|
+
if (rec['kind'] === 'user') {
|
|
443
|
+
if (title === '')
|
|
444
|
+
title = jobTitle(said);
|
|
445
|
+
parts.push(said);
|
|
446
|
+
}
|
|
447
|
+
else if (rec['kind'] === 'seat') {
|
|
448
|
+
parts.push(`${typeof rec['cliKey'] === 'string' ? rec['cliKey'] : 'agent'}: ${said}`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
if (parts.length === 0) {
|
|
452
|
+
this.index.remove('transcript', `chat:${chatId}`);
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
this.index.upsert({
|
|
456
|
+
type: 'transcript', id: `chat:${chatId}`, title: title || 'A chat', body: parts.join('\n'),
|
|
457
|
+
updatedAt: last, projectId: this.deps.projectOf(chatId) ?? null, status: 'chat',
|
|
458
|
+
target: { kind: 'chat', chat_id: chatId },
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
// ── The query ────────────────────────────────────────────────────────────────────────────────
|
|
462
|
+
async search(q, opts) {
|
|
463
|
+
const started = performance.now();
|
|
464
|
+
const budget = this.deps.budgetMs ?? 300;
|
|
465
|
+
const first = this.ensure(opts.types);
|
|
466
|
+
if (first.length > 0) {
|
|
467
|
+
// The first read is off the request path: wait for it a little, then answer with what is in.
|
|
468
|
+
let timer;
|
|
469
|
+
await Promise.race([
|
|
470
|
+
Promise.allSettled(first),
|
|
471
|
+
new Promise((r) => { timer = setTimeout(r, Math.min(this.deps.firstReadWaitMs ?? 1500, budget * 5)); }),
|
|
472
|
+
]);
|
|
473
|
+
if (timer !== undefined)
|
|
474
|
+
clearTimeout(timer);
|
|
475
|
+
opts.signal?.throwIfAborted();
|
|
476
|
+
}
|
|
477
|
+
const parsed = parseQuery(q);
|
|
478
|
+
// The scan's budget starts now: the wait for a first read above is not the scan's time.
|
|
479
|
+
const scanStart = performance.now();
|
|
480
|
+
const searchable = opts.types.filter((t) => SOURCES_OF[t].some((s) => this.available(s) && this.state(s).loadedAt !== null));
|
|
481
|
+
const { groups, partial } = await this.index.query(parsed, {
|
|
482
|
+
types: searchable, limit: opts.limit, offset: opts.offset,
|
|
483
|
+
budgetMs: Math.max(1, budget - (performance.now() - scanStart)),
|
|
484
|
+
...(opts.signal !== undefined ? { signal: opts.signal } : {}),
|
|
485
|
+
});
|
|
486
|
+
const sources = opts.types.map((type) => this.sourceState(type));
|
|
487
|
+
return { query: parsed.text, groups, sources, partial, took_ms: Math.round(performance.now() - started) };
|
|
488
|
+
}
|
|
489
|
+
sourceState(type) {
|
|
490
|
+
const srcs = SOURCES_OF[type].filter((s) => this.available(s));
|
|
491
|
+
if (srcs.length === 0)
|
|
492
|
+
return { type, state: 'unavailable', indexed: 0, note: 'This daemon has no source for it.' };
|
|
493
|
+
const sts = srcs.map((s) => this.state(s));
|
|
494
|
+
const indexed = this.index.count(type);
|
|
495
|
+
if (sts.some((st) => st.loadedAt === null))
|
|
496
|
+
return { type, state: 'indexing', indexed, note: null };
|
|
497
|
+
// Unit outputs are read after the run list, a few at a time: until the queue drains, more may come.
|
|
498
|
+
if (type === 'transcript' && (this.unitQueue.length > 0 || this.unitWorkers > 0))
|
|
499
|
+
return { type, state: 'indexing', indexed, note: null };
|
|
500
|
+
const failed = sts.find((st) => st.error !== null);
|
|
501
|
+
// A source that failed but still holds an earlier read answers from it, and says so.
|
|
502
|
+
if (failed !== undefined && indexed === 0)
|
|
503
|
+
return { type, state: 'unavailable', indexed, note: failed.error };
|
|
504
|
+
if (failed !== undefined)
|
|
505
|
+
return { type, state: 'ready', indexed, note: `Showing the last read: ${failed.error}` };
|
|
506
|
+
const left = this.index.leftOutOf(type);
|
|
507
|
+
return { type, state: 'ready', indexed, note: left > 0 ? `The ${left} oldest were left out to keep the index in memory.` : null };
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
/** Parse `types`: comma-separated; unknown → `null`. */
|
|
511
|
+
export function parseTypes(raw) {
|
|
512
|
+
if (raw === undefined || raw.trim() === '')
|
|
513
|
+
return [...SEARCH_TYPES];
|
|
514
|
+
const out = [];
|
|
515
|
+
for (const t of raw.split(',').map((x) => x.trim()).filter((x) => x !== '')) {
|
|
516
|
+
if (!SEARCH_TYPES.includes(t))
|
|
517
|
+
return null;
|
|
518
|
+
if (!out.includes(t))
|
|
519
|
+
out.push(t);
|
|
520
|
+
}
|
|
521
|
+
return out.length > 0 ? out : null;
|
|
522
|
+
}
|
|
523
|
+
const one = (v) => (Array.isArray(v) ? v[0] : v);
|
|
524
|
+
export function registerSearchRoutes(app, service) {
|
|
525
|
+
// Writes keep the index current: a successful mutating request re-reads what its path can change.
|
|
526
|
+
app.addHook('onResponse', (req, reply, done) => {
|
|
527
|
+
if (reply.statusCode < 400)
|
|
528
|
+
service.noteWrite(req.method, req.url);
|
|
529
|
+
done();
|
|
530
|
+
});
|
|
531
|
+
app.addHook('onClose', async () => { service.close(); });
|
|
532
|
+
app.get(`${API_PREFIX}/search`, { config: { manifest: { responseType: 'SearchResponse', statusCodes: [200, 400] } } }, async (req, reply) => {
|
|
533
|
+
const qs = req.query;
|
|
534
|
+
const q = (one(qs['q']) ?? '').trim();
|
|
535
|
+
if (q.length < MIN_QUERY_CHARS)
|
|
536
|
+
return reply.code(400).send({ error: `\`q\` needs at least ${MIN_QUERY_CHARS} characters` });
|
|
537
|
+
if (q.length > MAX_QUERY_CHARS)
|
|
538
|
+
return reply.code(400).send({ error: `\`q\` is longer than ${MAX_QUERY_CHARS} characters` });
|
|
539
|
+
if (parseQuery(q).terms.join('').length < MIN_QUERY_CHARS)
|
|
540
|
+
return reply.code(400).send({ error: `\`q\` needs at least ${MIN_QUERY_CHARS} characters of words` });
|
|
541
|
+
const types = parseTypes(one(qs['types']));
|
|
542
|
+
if (types === null)
|
|
543
|
+
return reply.code(400).send({ error: `\`types\` must be a comma-separated list of: ${SEARCH_TYPES.join(', ')}` });
|
|
544
|
+
const rawLimit = one(qs['limit']);
|
|
545
|
+
const limit = rawLimit === undefined || rawLimit === '' ? 5 : Number(rawLimit);
|
|
546
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 50)
|
|
547
|
+
return reply.code(400).send({ error: '`limit` must be an integer from 1 to 50' });
|
|
548
|
+
const cursor = one(qs['cursor']);
|
|
549
|
+
let offset = 0;
|
|
550
|
+
if (cursor !== undefined && cursor !== '') {
|
|
551
|
+
if (types.length !== 1)
|
|
552
|
+
return reply.code(400).send({ error: '`cursor` pages one type: pass exactly one in `types`' });
|
|
553
|
+
offset = Number(cursor);
|
|
554
|
+
if (!Number.isInteger(offset) || offset < 0 || offset > 100_000)
|
|
555
|
+
return reply.code(400).send({ error: '`cursor` is not a cursor this endpoint gave' });
|
|
556
|
+
}
|
|
557
|
+
// A client that goes away (a superseded query) stops the scan.
|
|
558
|
+
const ac = new AbortController();
|
|
559
|
+
const onClose = () => { if (!reply.raw.writableEnded)
|
|
560
|
+
ac.abort(new Error('client closed')); };
|
|
561
|
+
reply.raw.once('close', onClose);
|
|
562
|
+
try {
|
|
563
|
+
return await service.search(q, { types, limit, offset, signal: ac.signal });
|
|
564
|
+
}
|
|
565
|
+
catch (err) {
|
|
566
|
+
// Nobody is listening: hand the (closed) socket back instead of answering it.
|
|
567
|
+
if (ac.signal.aborted) {
|
|
568
|
+
reply.hijack();
|
|
569
|
+
return undefined;
|
|
570
|
+
}
|
|
571
|
+
throw err;
|
|
572
|
+
}
|
|
573
|
+
finally {
|
|
574
|
+
reply.raw.off('close', onClose);
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
//# sourceMappingURL=search-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-routes.js","sourceRoot":"","sources":["../../src/api/search-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AuditEntry } from '../core/types.js';
|
|
2
|
+
import type { AuditLog } from './audit.js';
|
|
3
|
+
import { type SeatBenchEntry, type SeatBenchStore } from './seat-health.js';
|
|
4
|
+
/** The audit action of a bench the engine recorded in a run. */
|
|
5
|
+
export declare const SEAT_BENCHED_ACTION = "seat.benched";
|
|
6
|
+
/** The audit action of a bench lifted before its window ran out (an ok turn, a live sign-in). */
|
|
7
|
+
export declare const SEAT_BENCH_LIFTED_ACTION = "seat.bench_lifted";
|
|
8
|
+
/** The store the tracker writes through: one audit entry per bench and per lift. */
|
|
9
|
+
export declare function auditSeatBenchStore(audit: AuditLog): SeatBenchStore;
|
|
10
|
+
/** One trail entry as a bench entry, or `null` when it is not one this module wrote. */
|
|
11
|
+
export declare function benchEntryOf(e: AuditEntry): SeatBenchEntry | null;
|
|
12
|
+
/** The bench entries of the last window (the audit `ts` is never earlier than the bench itself). */
|
|
13
|
+
export declare function readSeatBenchEntries(audit: AuditLog, nowMs?: number): Promise<SeatBenchEntry[]>;
|
|
14
|
+
//# sourceMappingURL=seat-bench-trail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seat-bench-trail.d.ts","sourceRoot":"","sources":["../../src/api/seat-bench-trail.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAS,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAwB,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElG,gEAAgE;AAChE,eAAO,MAAM,mBAAmB,iBAAiB,CAAC;AAClD,iGAAiG;AACjG,eAAO,MAAM,wBAAwB,sBAAsB,CAAC;AAI5D,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,GAAG,cAAc,CAYnE;AAUD,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,CAAC,EAAE,UAAU,GAAG,cAAc,GAAG,IAAI,CAqBjE;AAED,oGAAoG;AACpG,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,SAAa,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAOzG"}
|