codesesh 1.0.0 → 1.0.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/README.md +29 -5
- package/dist/{chunk-TIHF4T3K.js → chunk-PROMURPM.js} +80 -16
- package/dist/chunk-PROMURPM.js.map +1 -0
- package/dist/{chunk-BEF6LLRG.js → chunk-VAUC2W7I.js} +5317 -2268
- package/dist/chunk-VAUC2W7I.js.map +1 -0
- package/dist/{dist-3F467V44.js → dist-6QTGTYZT.js} +40 -4
- package/dist/index.js +1818 -454
- package/dist/index.js.map +1 -1
- package/dist/scan-refresh-worker.js +274 -95
- package/dist/scan-refresh-worker.js.map +1 -1
- package/dist/search-index-worker.js +112 -50
- package/dist/search-index-worker.js.map +1 -1
- package/dist/smart-tag-worker.js +5 -3
- package/dist/smart-tag-worker.js.map +1 -1
- package/dist/web/assets/ErrorBoundary-D11tWzfn.js +1 -0
- package/dist/web/assets/OverviewScreen-DriPmCam.js +1 -0
- package/dist/web/assets/Projects-BPDIcUBK.js +1 -0
- package/dist/web/assets/SearchFilterBar-Bx73B5e9.js +1 -0
- package/dist/web/assets/SearchResultsPanel-A6_3TPhW.js +1 -0
- package/dist/web/assets/SessionDetail-BnpvDwtH.js +54 -0
- package/dist/web/assets/agents-BkRP_ww3.js +1 -0
- package/dist/web/assets/contract-V6QuD0UY.js +1 -0
- package/dist/web/assets/index-99ZxpV2y.js +1410 -0
- package/dist/web/assets/index-B2RqUgZ5.css +1 -0
- package/dist/web/assets/panel-C-gc79Gz.js +1 -0
- package/dist/web/assets/session-indexes-0oT5HSS5.js +4 -0
- package/dist/web/assets/utils-DgUgu15E.js +1 -0
- package/dist/web/icon/agent/dsh.svg +3 -0
- package/dist/web/index.html +10 -32
- package/dist/web/theme-bootstrap.js +19 -0
- package/package.json +10 -10
- package/dist/chunk-BEF6LLRG.js.map +0 -1
- package/dist/chunk-TIHF4T3K.js.map +0 -1
- package/dist/web/assets/ErrorBoundary-BY-N1QzJ.js +0 -1
- package/dist/web/assets/OverviewScreen-_ZaVjhxN.js +0 -1
- package/dist/web/assets/Projects-q6cEm2dc.js +0 -1
- package/dist/web/assets/SearchFilterBar-CrVBpo40.js +0 -1
- package/dist/web/assets/SearchResultsPanel-Cg5V8Ia6.js +0 -1
- package/dist/web/assets/SessionDetail-BSSuddsZ.js +0 -54
- package/dist/web/assets/chunk-62JRHF6Z-BWRsEBnL.js +0 -4
- package/dist/web/assets/index-C3KgxGwE.js +0 -1410
- package/dist/web/assets/index-DQX42cFQ.css +0 -1
- package/dist/web/assets/panel-B7kuE60V.js +0 -1
- package/dist/web/assets/session-indexes-DmnjZ_JL.js +0 -1
- package/dist/web/assets/utils-t2u9IbNT.js +0 -1
- /package/dist/{dist-3F467V44.js.map → dist-6QTGTYZT.js.map} +0 -0
|
@@ -1,22 +1,86 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
appLogger
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PROMURPM.js";
|
|
5
5
|
import {
|
|
6
6
|
FileSystemSessionSource,
|
|
7
|
+
SMART_TAG_CLASSIFIER_REVISION,
|
|
7
8
|
attachMissingProjectIdentities,
|
|
8
9
|
buildAgentCacheMeta,
|
|
9
10
|
computeSessionDiff,
|
|
10
11
|
createRegisteredAgents,
|
|
11
|
-
diffSessionSources,
|
|
12
12
|
ensureSessionTagsSync,
|
|
13
13
|
sessionSignature,
|
|
14
|
-
sortSessions
|
|
15
|
-
|
|
14
|
+
sortSessions,
|
|
15
|
+
synchronizePricingGeneration,
|
|
16
|
+
synchronizeSessionSources
|
|
17
|
+
} from "./chunk-VAUC2W7I.js";
|
|
16
18
|
|
|
17
19
|
// src/scan-refresh-worker.ts
|
|
18
20
|
import { parentPort, workerData } from "worker_threads";
|
|
19
21
|
import { isDeepStrictEqual } from "util";
|
|
22
|
+
|
|
23
|
+
// src/monotonic-value-sampler.ts
|
|
24
|
+
var MonotonicValueSampler = class {
|
|
25
|
+
constructor(intervalMs, emit, now = () => performance.now()) {
|
|
26
|
+
this.intervalMs = intervalMs;
|
|
27
|
+
this.emit = emit;
|
|
28
|
+
this.now = now;
|
|
29
|
+
}
|
|
30
|
+
intervalMs;
|
|
31
|
+
emit;
|
|
32
|
+
now;
|
|
33
|
+
phase = null;
|
|
34
|
+
lastEmittedAt = -Infinity;
|
|
35
|
+
pending;
|
|
36
|
+
hasPending = false;
|
|
37
|
+
push(value, phase) {
|
|
38
|
+
if (this.phase !== phase) {
|
|
39
|
+
this.flush();
|
|
40
|
+
this.phase = phase;
|
|
41
|
+
this.emitNow(value);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (this.now() - this.lastEmittedAt >= this.intervalMs) {
|
|
45
|
+
this.pending = void 0;
|
|
46
|
+
this.hasPending = false;
|
|
47
|
+
this.emitNow(value);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
this.pending = value;
|
|
51
|
+
this.hasPending = true;
|
|
52
|
+
}
|
|
53
|
+
flush() {
|
|
54
|
+
if (!this.hasPending) return;
|
|
55
|
+
const pending = this.pending;
|
|
56
|
+
this.pending = void 0;
|
|
57
|
+
this.hasPending = false;
|
|
58
|
+
this.emitNow(pending);
|
|
59
|
+
}
|
|
60
|
+
cancel() {
|
|
61
|
+
this.phase = null;
|
|
62
|
+
this.lastEmittedAt = -Infinity;
|
|
63
|
+
this.pending = void 0;
|
|
64
|
+
this.hasPending = false;
|
|
65
|
+
}
|
|
66
|
+
emitNow(value) {
|
|
67
|
+
this.lastEmittedAt = this.now();
|
|
68
|
+
this.emit(value);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// src/scan-refresh-operation.ts
|
|
73
|
+
function synchronizesSessionSources(operation) {
|
|
74
|
+
return operation.kind === "source-refresh" || operation.kind === "source-backfill";
|
|
75
|
+
}
|
|
76
|
+
function isBackfillOperation(operation) {
|
|
77
|
+
return operation.kind === "full-backfill" || operation.kind === "source-backfill";
|
|
78
|
+
}
|
|
79
|
+
function usesDurableCheckpoints(operation) {
|
|
80
|
+
return "checkpoint" in operation && operation.checkpoint === "durable";
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/scan-refresh-worker.ts
|
|
20
84
|
function computeCacheMetaDiff(previous, next) {
|
|
21
85
|
const changes = {};
|
|
22
86
|
const removedIds = [];
|
|
@@ -30,7 +94,7 @@ function computeCacheMetaDiff(previous, next) {
|
|
|
30
94
|
}
|
|
31
95
|
function hasStaleSmartTags(session) {
|
|
32
96
|
const sourceUpdatedAt = session.time_updated ?? session.time_created;
|
|
33
|
-
return !Array.isArray(session.smart_tags) || session.smart_tags_source_updated_at !== sourceUpdatedAt;
|
|
97
|
+
return !Array.isArray(session.smart_tags) || session.smart_tags_source_updated_at !== sourceUpdatedAt || session.smart_tags_classifier_revision !== SMART_TAG_CLASSIFIER_REVISION;
|
|
34
98
|
}
|
|
35
99
|
function selectBackfillSessions(sessions, changedIds, cursor) {
|
|
36
100
|
const orderedSessions = sortSessions(sessions);
|
|
@@ -47,44 +111,23 @@ function selectBackfillSessions(sessions, changedIds, cursor) {
|
|
|
47
111
|
}
|
|
48
112
|
return { orderedSessions, finalizeSessionIds, cursorIndex };
|
|
49
113
|
}
|
|
50
|
-
function
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
sourceRefs
|
|
63
|
-
) ?? [.../* @__PURE__ */ new Set([...changedIds, ...removedIds])];
|
|
64
|
-
const isWindowed = windowOptions?.from != null || windowOptions?.to != null;
|
|
65
|
-
const finalizeSessionIds = isWindowed ? [...rescanIds] : sourceRefs.map((source) => source.sessionId);
|
|
66
|
-
rescanIds.forEach((sessionId, index) => {
|
|
67
|
-
const source = sourceById.get(sessionId);
|
|
68
|
-
if (!source) return;
|
|
69
|
-
const next = agent.scanSessionSource(source.sourcePath);
|
|
70
|
-
if (next) {
|
|
71
|
-
sessionMap.set(next.id, next);
|
|
72
|
-
} else {
|
|
73
|
-
sessionMap.delete(sessionId);
|
|
74
|
-
}
|
|
75
|
-
onProgress?.({ total: rescanIds.length, processed: index + 1, sessions: sessionMap.size });
|
|
114
|
+
function inheritSmartTags(sessions, previousSessions) {
|
|
115
|
+
const previousById = new Map(previousSessions.map((session) => [session.id, session]));
|
|
116
|
+
return sessions.map((session) => {
|
|
117
|
+
if (Array.isArray(session.smart_tags)) return session;
|
|
118
|
+
const previous = previousById.get(session.id);
|
|
119
|
+
if (!previous || !Array.isArray(previous.smart_tags)) return session;
|
|
120
|
+
return {
|
|
121
|
+
...session,
|
|
122
|
+
smart_tags: previous.smart_tags,
|
|
123
|
+
smart_tags_source_updated_at: previous.smart_tags_source_updated_at,
|
|
124
|
+
smart_tags_classifier_revision: previous.smart_tags_classifier_revision
|
|
125
|
+
};
|
|
76
126
|
});
|
|
77
|
-
for (const sessionId of removedIds) sessionMap.delete(sessionId);
|
|
78
|
-
return {
|
|
79
|
-
sessions: [...sessionMap.values()],
|
|
80
|
-
changedIds: rescanIds,
|
|
81
|
-
finalizeSessionIds,
|
|
82
|
-
sourceCount: sourceRefs.length,
|
|
83
|
-
removedCount: removedIds.length
|
|
84
|
-
};
|
|
85
127
|
}
|
|
86
128
|
var TAG_SETTLE_MS = 6e4;
|
|
87
129
|
var TAG_CHECKPOINT_SIZE = 32;
|
|
130
|
+
var PROGRESS_INTERVAL_MS = 100;
|
|
88
131
|
function createSessionFinalizationTiming() {
|
|
89
132
|
return {
|
|
90
133
|
batches: 0,
|
|
@@ -155,75 +198,150 @@ function finalizeSessions(agent, sessions, onProgress, onCheckpoint, finalizeSes
|
|
|
155
198
|
}
|
|
156
199
|
return ordered.map((session) => taggedById.get(session.id) ?? session);
|
|
157
200
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
201
|
+
var workerBaseline = null;
|
|
202
|
+
function baselineFor(data) {
|
|
203
|
+
const generation = data.generation ?? 0;
|
|
204
|
+
const hasSessions = Array.isArray(data.previousSessions);
|
|
205
|
+
const hasMeta = data.meta != null;
|
|
206
|
+
if (hasSessions !== hasMeta)
|
|
207
|
+
throw new Error("Worker baseline requires sessions and meta together");
|
|
208
|
+
if (hasSessions && hasMeta) {
|
|
209
|
+
if (workerBaseline) throw new Error("Scan refresh worker baseline is already initialized");
|
|
210
|
+
const agent = createRegisteredAgents().find((item) => item.name === data.agentName);
|
|
211
|
+
if (!agent) throw new Error(`Unknown agent: ${data.agentName}`);
|
|
212
|
+
workerBaseline = {
|
|
213
|
+
agentName: data.agentName,
|
|
214
|
+
agent,
|
|
215
|
+
generation,
|
|
216
|
+
sessions: data.previousSessions,
|
|
217
|
+
meta: data.meta,
|
|
218
|
+
staged: null
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
if (!workerBaseline) throw new Error("Scan refresh worker baseline is not initialized");
|
|
222
|
+
if (workerBaseline.agentName !== data.agentName) {
|
|
223
|
+
throw new Error(`Worker Agent mismatch: expected ${workerBaseline.agentName}`);
|
|
224
|
+
}
|
|
225
|
+
if (workerBaseline.generation !== generation) {
|
|
226
|
+
throw new Error(
|
|
227
|
+
`Worker generation mismatch: expected ${workerBaseline.generation}, received ${generation}`
|
|
228
|
+
);
|
|
163
229
|
}
|
|
230
|
+
if (workerBaseline.staged) {
|
|
231
|
+
throw new Error(`Worker result ${workerBaseline.staged.requestId} is awaiting commit`);
|
|
232
|
+
}
|
|
233
|
+
workerBaseline.agent.setSessionMetaMap(new Map(Object.entries(workerBaseline.meta)));
|
|
234
|
+
return workerBaseline;
|
|
235
|
+
}
|
|
236
|
+
async function run(data, progressEmitter) {
|
|
237
|
+
const startedAt = performance.now();
|
|
238
|
+
const baseline = baselineFor(data);
|
|
239
|
+
const { agent } = baseline;
|
|
240
|
+
const previousSessions = baseline.sessions;
|
|
241
|
+
const previousMeta = baseline.meta;
|
|
242
|
+
const operation = data.operation;
|
|
243
|
+
const sourceSynchronization = synchronizesSessionSources(operation);
|
|
244
|
+
const backfill = isBackfillOperation(operation);
|
|
245
|
+
const durableCheckpoints = usesDurableCheckpoints(operation);
|
|
246
|
+
const backfillCursor = backfill ? operation.cursor : void 0;
|
|
164
247
|
appLogger.debug("scan.refresh_worker.started", {
|
|
165
248
|
agent: data.agentName,
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
previous_sessions: data.previousSessions.length
|
|
249
|
+
operation: operation.kind,
|
|
250
|
+
backfill_cursor: backfillCursor ?? void 0,
|
|
251
|
+
changed_ids: operation.kind === "incremental-scan" ? operation.changedIds.length : 0,
|
|
252
|
+
previous_sessions: previousSessions.length
|
|
171
253
|
});
|
|
172
254
|
const reportProgress = (progress) => {
|
|
173
|
-
|
|
174
|
-
type: "progress",
|
|
175
|
-
requestId: data.requestId,
|
|
176
|
-
progress
|
|
177
|
-
});
|
|
255
|
+
progressEmitter.push(progress, progress.phase ?? "scanning");
|
|
178
256
|
};
|
|
179
|
-
agent.setSessionMetaMap(new Map(Object.entries(data.meta)));
|
|
180
257
|
const isAvailable = agent.isAvailable();
|
|
181
258
|
let sessions;
|
|
182
259
|
let changedIds;
|
|
260
|
+
let sourceFailures = [];
|
|
261
|
+
let explicitRemovedSessionIds = [];
|
|
183
262
|
let finalizeSessionIds;
|
|
184
263
|
let backfillOrder;
|
|
185
264
|
let backfillCursorIndex = -1;
|
|
186
|
-
let
|
|
265
|
+
let sourceSynchronizationDetails;
|
|
187
266
|
if (!isAvailable) {
|
|
188
267
|
sessions = [];
|
|
189
|
-
} else if (
|
|
190
|
-
|
|
268
|
+
} else if (operation.kind === "recompute-derived") {
|
|
269
|
+
sessions = previousSessions;
|
|
270
|
+
} else if (sourceSynchronization) {
|
|
271
|
+
if (!(agent instanceof FileSystemSessionSource)) {
|
|
272
|
+
throw new Error(`Agent ${agent.name} does not support Session Source synchronization`);
|
|
273
|
+
}
|
|
274
|
+
const result = synchronizeSessionSources(
|
|
275
|
+
agent,
|
|
276
|
+
{ sessions: previousSessions, meta: previousMeta },
|
|
277
|
+
{
|
|
278
|
+
kind: "refresh",
|
|
279
|
+
scanOptions: { ...data.scanOptions, onProgress: reportProgress }
|
|
280
|
+
}
|
|
281
|
+
);
|
|
282
|
+
sessions = result.sessions;
|
|
283
|
+
changedIds = result.changedSessionIds;
|
|
284
|
+
finalizeSessionIds = new Set(result.finalizeSessionIds);
|
|
285
|
+
sourceSynchronizationDetails = {
|
|
286
|
+
sourceCount: result.sourceCount,
|
|
287
|
+
removedCount: result.removedSourceCount
|
|
288
|
+
};
|
|
289
|
+
sourceFailures = result.sourceFailures;
|
|
290
|
+
explicitRemovedSessionIds = result.explicitRemovedSessionIds;
|
|
291
|
+
} else if (operation.kind === "incremental-scan") {
|
|
292
|
+
changedIds = operation.changedIds;
|
|
293
|
+
sessions = inheritSmartTags(
|
|
294
|
+
await Promise.resolve(
|
|
295
|
+
agent.incrementalScan(previousSessions, operation.changedIds, void 0, {
|
|
296
|
+
...data.scanOptions,
|
|
297
|
+
onProgress: reportProgress
|
|
298
|
+
})
|
|
299
|
+
),
|
|
300
|
+
previousSessions
|
|
301
|
+
);
|
|
302
|
+
} else if (agent instanceof FileSystemSessionSource) {
|
|
303
|
+
const result = synchronizeSessionSources(
|
|
191
304
|
agent,
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
305
|
+
{ sessions: previousSessions, meta: previousMeta },
|
|
306
|
+
{
|
|
307
|
+
kind: "reload",
|
|
308
|
+
scanOptions: { ...data.scanOptions, onProgress: reportProgress }
|
|
309
|
+
}
|
|
196
310
|
);
|
|
197
311
|
sessions = result.sessions;
|
|
198
|
-
changedIds = result.changedIds;
|
|
199
312
|
finalizeSessionIds = new Set(result.finalizeSessionIds);
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
sessions = await Promise.resolve(agent.incrementalScan(data.previousSessions, data.changedIds));
|
|
313
|
+
sourceFailures = result.sourceFailures;
|
|
314
|
+
explicitRemovedSessionIds = result.explicitRemovedSessionIds;
|
|
203
315
|
} else {
|
|
204
|
-
sessions =
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
316
|
+
sessions = inheritSmartTags(
|
|
317
|
+
await Promise.resolve(
|
|
318
|
+
agent.scan({
|
|
319
|
+
...data.scanOptions,
|
|
320
|
+
onProgress: reportProgress
|
|
321
|
+
})
|
|
322
|
+
),
|
|
323
|
+
previousSessions
|
|
209
324
|
);
|
|
210
325
|
}
|
|
211
326
|
sessions = attachMissingProjectIdentities(sessions);
|
|
212
|
-
|
|
327
|
+
const completeness = data.scanOptions.from == null && data.scanOptions.to == null && sourceFailures.length === 0 ? "complete" : "partial";
|
|
328
|
+
if (durableCheckpoints) {
|
|
213
329
|
const ordered = sortSessions(sessions);
|
|
214
330
|
parentPort?.postMessage({
|
|
215
331
|
type: "checkpoint",
|
|
216
332
|
requestId: data.requestId,
|
|
333
|
+
generation: baseline.generation,
|
|
217
334
|
checkpoint: {
|
|
218
335
|
stage: "scanned",
|
|
219
336
|
sessions: ordered,
|
|
220
|
-
meta: buildAgentCacheMeta(agent, new Set(ordered.map((session) => session.id)))
|
|
337
|
+
meta: buildAgentCacheMeta(agent, new Set(ordered.map((session) => session.id))),
|
|
338
|
+
completeness
|
|
221
339
|
}
|
|
222
340
|
});
|
|
223
341
|
sessions = ordered;
|
|
224
342
|
}
|
|
225
|
-
if (
|
|
226
|
-
const selection = selectBackfillSessions(sessions, changedIds ?? [],
|
|
343
|
+
if (backfill) {
|
|
344
|
+
const selection = selectBackfillSessions(sessions, changedIds ?? [], backfillCursor);
|
|
227
345
|
sessions = selection.orderedSessions;
|
|
228
346
|
finalizeSessionIds = selection.finalizeSessionIds;
|
|
229
347
|
backfillOrder = selection.orderedSessions;
|
|
@@ -232,13 +350,13 @@ async function run(data) {
|
|
|
232
350
|
const scanDuration = performance.now() - startedAt;
|
|
233
351
|
appLogger.debug("scan.refresh_worker.scanned", {
|
|
234
352
|
agent: data.agentName,
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
backfill_cursor: data.backfillCursor ?? void 0,
|
|
353
|
+
operation: operation.kind,
|
|
354
|
+
backfill_cursor: backfillCursor ?? void 0,
|
|
238
355
|
sessions: sessions.length,
|
|
239
356
|
changed_ids: changedIds?.length ?? 0,
|
|
240
|
-
source_count:
|
|
241
|
-
removed_count:
|
|
357
|
+
source_count: sourceSynchronizationDetails?.sourceCount,
|
|
358
|
+
removed_count: sourceSynchronizationDetails?.removedCount,
|
|
359
|
+
failed_sources: sourceFailures.length,
|
|
242
360
|
duration_ms: Math.round(scanDuration)
|
|
243
361
|
});
|
|
244
362
|
const finalizeStartedAt = performance.now();
|
|
@@ -248,7 +366,7 @@ async function run(data) {
|
|
|
248
366
|
agent,
|
|
249
367
|
sessions,
|
|
250
368
|
reportProgress,
|
|
251
|
-
(checkpoint) => {
|
|
369
|
+
durableCheckpoints ? (checkpoint) => {
|
|
252
370
|
let nextCheckpoint = checkpoint;
|
|
253
371
|
if (checkpoint.stage === "finalizing" && backfillOrder && backfillPositionById) {
|
|
254
372
|
let nextCursorIndex = backfillCursorIndex;
|
|
@@ -267,9 +385,10 @@ async function run(data) {
|
|
|
267
385
|
parentPort?.postMessage({
|
|
268
386
|
type: "checkpoint",
|
|
269
387
|
requestId: data.requestId,
|
|
388
|
+
generation: baseline.generation,
|
|
270
389
|
checkpoint: nextCheckpoint
|
|
271
390
|
});
|
|
272
|
-
},
|
|
391
|
+
} : void 0,
|
|
273
392
|
finalizeSessionIds,
|
|
274
393
|
(batchTiming) => {
|
|
275
394
|
finalizationTiming.batches += 1;
|
|
@@ -295,7 +414,7 @@ async function run(data) {
|
|
|
295
414
|
);
|
|
296
415
|
appLogger.debug("scan.refresh_worker.finalized", {
|
|
297
416
|
agent: data.agentName,
|
|
298
|
-
|
|
417
|
+
operation: operation.kind,
|
|
299
418
|
backfill_cursor: backfillOrder?.[backfillCursorIndex]?.id,
|
|
300
419
|
sessions: sessions.length,
|
|
301
420
|
finalized_sessions: finalizationTiming.sessions,
|
|
@@ -318,46 +437,106 @@ async function run(data) {
|
|
|
318
437
|
total_duration_ms: Math.round(performance.now() - startedAt)
|
|
319
438
|
});
|
|
320
439
|
const nextMeta = buildAgentCacheMeta(agent, new Set(sessions.map((session) => session.id)));
|
|
321
|
-
const metaDiff = computeCacheMetaDiff(
|
|
440
|
+
const metaDiff = computeCacheMetaDiff(previousMeta, nextMeta);
|
|
322
441
|
const diff = computeSessionDiff(
|
|
323
|
-
|
|
442
|
+
previousSessions,
|
|
324
443
|
sessions,
|
|
325
444
|
[...changedIds ?? [], ...Object.keys(metaDiff.changes), ...metaDiff.removedIds],
|
|
326
445
|
sessionSignature
|
|
327
446
|
);
|
|
447
|
+
baseline.staged = {
|
|
448
|
+
requestId: data.requestId,
|
|
449
|
+
generation: baseline.generation,
|
|
450
|
+
sessions,
|
|
451
|
+
meta: nextMeta
|
|
452
|
+
};
|
|
453
|
+
progressEmitter.flush();
|
|
328
454
|
parentPort?.postMessage({
|
|
329
455
|
type: "done",
|
|
330
456
|
requestId: data.requestId,
|
|
457
|
+
generation: baseline.generation,
|
|
331
458
|
changes: diff.changes,
|
|
332
459
|
removedSessionIds: diff.removedSessionIds,
|
|
333
460
|
meta: metaDiff.changes,
|
|
334
461
|
removedMetaIds: metaDiff.removedIds,
|
|
462
|
+
sourceFailures,
|
|
463
|
+
completeness,
|
|
464
|
+
explicitRemovedSessionIds,
|
|
335
465
|
durationMs: performance.now() - startedAt
|
|
336
466
|
});
|
|
337
467
|
}
|
|
338
468
|
async function handleRequest(data) {
|
|
339
469
|
const startedAt = performance.now();
|
|
470
|
+
const progressEmitter = new MonotonicValueSampler(
|
|
471
|
+
PROGRESS_INTERVAL_MS,
|
|
472
|
+
(progress) => {
|
|
473
|
+
parentPort?.postMessage({
|
|
474
|
+
type: "progress",
|
|
475
|
+
requestId: data.requestId,
|
|
476
|
+
generation: data.generation ?? 0,
|
|
477
|
+
progress
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
);
|
|
340
481
|
try {
|
|
341
|
-
|
|
482
|
+
synchronizePricingGeneration(data.pricingGenerationId);
|
|
483
|
+
await run(data, progressEmitter);
|
|
342
484
|
} catch (error) {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
durationMs: performance.now() - startedAt
|
|
348
|
-
});
|
|
485
|
+
progressEmitter.flush();
|
|
486
|
+
postRequestError(data, error, startedAt);
|
|
487
|
+
} finally {
|
|
488
|
+
progressEmitter.cancel();
|
|
349
489
|
}
|
|
350
490
|
}
|
|
351
491
|
var requestTail = Promise.resolve();
|
|
492
|
+
function commitBaseline(data) {
|
|
493
|
+
if (!workerBaseline) throw new Error("Cannot commit an uninitialized worker baseline");
|
|
494
|
+
const staged = workerBaseline.staged;
|
|
495
|
+
if (!staged || staged.requestId !== data.requestId) {
|
|
496
|
+
throw new Error(`Worker result ${data.requestId} is not awaiting commit`);
|
|
497
|
+
}
|
|
498
|
+
if (workerBaseline.generation !== data.generation || staged.generation !== data.generation) {
|
|
499
|
+
throw new Error(
|
|
500
|
+
`Worker commit generation mismatch: expected ${workerBaseline.generation}, received ${data.generation}`
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
workerBaseline.sessions = staged.sessions;
|
|
504
|
+
workerBaseline.meta = staged.meta;
|
|
505
|
+
workerBaseline.generation += 1;
|
|
506
|
+
workerBaseline.staged = null;
|
|
507
|
+
}
|
|
508
|
+
function postRequestError(data, error, startedAt) {
|
|
509
|
+
parentPort?.postMessage({
|
|
510
|
+
type: "error",
|
|
511
|
+
requestId: data.requestId,
|
|
512
|
+
generation: data.generation,
|
|
513
|
+
error: error instanceof Error ? error.message : String(error),
|
|
514
|
+
durationMs: performance.now() - startedAt
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
function handleCommit(data) {
|
|
518
|
+
const startedAt = performance.now();
|
|
519
|
+
try {
|
|
520
|
+
commitBaseline(data);
|
|
521
|
+
} catch (error) {
|
|
522
|
+
postRequestError(data, error, startedAt);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
352
525
|
function enqueueRequest(data) {
|
|
353
|
-
requestTail = requestTail.then(() => handleRequest(data))
|
|
526
|
+
requestTail = requestTail.then(() => data.type === "commit" ? handleCommit(data) : handleRequest(data)).catch((error) => {
|
|
527
|
+
appLogger.error("scan.refresh_worker.request_error", {
|
|
528
|
+
request_id: data.requestId,
|
|
529
|
+
request_type: data.type,
|
|
530
|
+
error
|
|
531
|
+
});
|
|
532
|
+
});
|
|
354
533
|
}
|
|
355
534
|
var initialRequest = workerData;
|
|
356
|
-
if (initialRequest?.type === "run" && typeof initialRequest.requestId === "number" && typeof initialRequest.agentName === "string" && Array.isArray(initialRequest.previousSessions)) {
|
|
535
|
+
if (initialRequest?.type === "run" && typeof initialRequest.requestId === "number" && typeof initialRequest.agentName === "string" && typeof initialRequest.pricingGenerationId === "number" && initialRequest.operation != null && Array.isArray(initialRequest.previousSessions) && initialRequest.meta != null) {
|
|
357
536
|
enqueueRequest(initialRequest);
|
|
358
537
|
}
|
|
359
538
|
parentPort?.on("message", (message) => {
|
|
360
|
-
|
|
539
|
+
enqueueRequest(message);
|
|
361
540
|
});
|
|
362
541
|
export {
|
|
363
542
|
finalizeSessions
|