@agent-native/core 0.111.4 → 0.112.0
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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +12 -0
- package/corpus/core/package.json +3 -1
- package/corpus/core/src/cli/code-agent-executor.ts +17 -5
- package/corpus/core/src/cli/code-agent-runs.ts +43 -2
- package/corpus/core/src/cli/multi-frontier-runs.ts +841 -0
- package/corpus/core/src/coding-tools/index.ts +27 -8
- package/corpus/core/src/embeddings/index.ts +233 -0
- package/corpus/core/src/index.ts +2 -0
- package/corpus/core/src/search/index.ts +413 -0
- package/corpus/templates/brain/.agents/skills/brain/RUNBOOK.md +48 -5
- package/corpus/templates/brain/.agents/skills/brain/SKILL.md +46 -14
- package/corpus/templates/brain/README.md +34 -3
- package/corpus/templates/brain/actions/approve-proposal.ts +2 -0
- package/corpus/templates/brain/actions/claim-distillation.ts +24 -27
- package/corpus/templates/brain/actions/create-source.ts +1 -1
- package/corpus/templates/brain/actions/get-knowledge.ts +6 -2
- package/corpus/templates/brain/actions/get-pilot-report.ts +44 -8
- package/corpus/templates/brain/actions/import-capture.ts +21 -9
- package/corpus/templates/brain/actions/import-transcript.ts +42 -14
- package/corpus/templates/brain/actions/list-captures.ts +10 -1
- package/corpus/templates/brain/actions/list-distillation-queue.ts +39 -14
- package/corpus/templates/brain/actions/list-projects.ts +51 -0
- package/corpus/templates/brain/actions/list-proposals.ts +80 -4
- package/corpus/templates/brain/actions/list-sources.ts +17 -3
- package/corpus/templates/brain/actions/manage-project.ts +118 -0
- package/corpus/templates/brain/actions/mark-capture-distilled.ts +68 -20
- package/corpus/templates/brain/actions/navigate.ts +1 -0
- package/corpus/templates/brain/actions/reject-proposal.ts +6 -1
- package/corpus/templates/brain/actions/resanitize-captures.ts +159 -33
- package/corpus/templates/brain/actions/review-proposal.ts +2 -0
- package/corpus/templates/brain/actions/search-everything.ts +10 -1
- package/corpus/templates/brain/actions/search-knowledge.ts +1 -1
- package/corpus/templates/brain/actions/set-settings.ts +36 -1
- package/corpus/templates/brain/actions/update-proposal.ts +2 -0
- package/corpus/templates/brain/app/hooks/use-distillation-bridge.ts +18 -9
- package/corpus/templates/brain/app/hooks/use-navigation-state.ts +3 -0
- package/corpus/templates/brain/app/i18n-data.ts +731 -2
- package/corpus/templates/brain/app/lib/brain.ts +33 -1
- package/corpus/templates/brain/app/routes/ops.tsx +47 -0
- package/corpus/templates/brain/app/routes/review.tsx +41 -2
- package/corpus/templates/brain/app/routes/search.tsx +33 -2
- package/corpus/templates/brain/app/routes/settings.tsx +158 -0
- package/corpus/templates/brain/app/routes/sources.tsx +31 -0
- package/corpus/templates/brain/changelog/2026-07-19-added-private-source-safe-semantic-search.md +6 -0
- package/corpus/templates/brain/jobs/process-ingest-queue.ts +270 -36
- package/corpus/templates/brain/package.json +1 -0
- package/corpus/templates/brain/server/db/index.ts +18 -0
- package/corpus/templates/brain/server/db/schema.ts +197 -1
- package/corpus/templates/brain/server/jobs/distillation-queue.ts +12 -5
- package/corpus/templates/brain/server/lib/audiences.ts +708 -0
- package/corpus/templates/brain/server/lib/brain-health.ts +251 -38
- package/corpus/templates/brain/server/lib/brain.ts +877 -50
- package/corpus/templates/brain/server/lib/capture-sanitization.ts +217 -53
- package/corpus/templates/brain/server/lib/connectors.ts +556 -70
- package/corpus/templates/brain/server/lib/demo.ts +17 -4
- package/corpus/templates/brain/server/lib/hybrid-search.ts +363 -0
- package/corpus/templates/brain/server/lib/ingest-queue.ts +104 -0
- package/corpus/templates/brain/server/lib/privacy-readiness.ts +24 -0
- package/corpus/templates/brain/server/lib/search-index-contracts.ts +72 -0
- package/corpus/templates/brain/server/lib/search-index.ts +714 -0
- package/corpus/templates/brain/server/lib/search.ts +120 -4
- package/corpus/templates/brain/server/lib/sensitivity-policy.ts +174 -0
- package/corpus/templates/brain/server/lib/slack-events.ts +281 -0
- package/corpus/templates/brain/server/onboarding.ts +29 -0
- package/corpus/templates/brain/server/plugins/db.ts +204 -0
- package/corpus/templates/brain/server/register-secrets.ts +46 -0
- package/corpus/templates/brain/server/routes/api/_agent-native/brain/ingest.post.ts +36 -16
- package/corpus/templates/brain/server/routes/api/_agent-native/brain/slack-events.post.ts +28 -0
- package/corpus/templates/brain/shared/types.ts +10 -0
- package/dist/cli/code-agent-executor.d.ts +8 -9
- package/dist/cli/code-agent-executor.d.ts.map +1 -1
- package/dist/cli/code-agent-executor.js +9 -3
- package/dist/cli/code-agent-executor.js.map +1 -1
- package/dist/cli/code-agent-runs.d.ts +5 -0
- package/dist/cli/code-agent-runs.d.ts.map +1 -1
- package/dist/cli/code-agent-runs.js +33 -2
- package/dist/cli/code-agent-runs.js.map +1 -1
- package/dist/cli/multi-frontier-runs.d.ts +131 -0
- package/dist/cli/multi-frontier-runs.d.ts.map +1 -0
- package/dist/cli/multi-frontier-runs.js +529 -0
- package/dist/cli/multi-frontier-runs.js.map +1 -0
- package/dist/coding-tools/index.d.ts +1 -0
- package/dist/coding-tools/index.d.ts.map +1 -1
- package/dist/coding-tools/index.js +25 -7
- package/dist/coding-tools/index.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/embeddings/index.d.ts +24 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +172 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/search/index.d.ts +88 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +267 -0
- package/dist/search/index.js.map +1 -0
- package/package.json +3 -1
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { getSetting, putSetting } from "@agent-native/core/settings";
|
|
2
|
-
import { accessFilter } from "@agent-native/core/sharing";
|
|
2
|
+
import { accessFilter, assertAccess } from "@agent-native/core/sharing";
|
|
3
3
|
import { listWorkspaceConnectionProviderCatalogForApp } from "@agent-native/core/workspace-connections";
|
|
4
|
-
import { and, desc, eq, inArray, ne } from "drizzle-orm";
|
|
4
|
+
import { and, desc, eq, inArray, isNull, ne, or } from "drizzle-orm";
|
|
5
5
|
|
|
6
6
|
import { getDb, schema } from "../db/index.js";
|
|
7
7
|
import { nextBrainSourceSyncAt } from "../jobs/sync-sources.js";
|
|
8
|
-
import {
|
|
8
|
+
import { listAccessibleAudienceIds } from "./audiences.js";
|
|
9
|
+
import { parseJson, readBrainSettings } from "./brain.js";
|
|
10
|
+
import { brainPrivacyReadiness } from "./privacy-readiness.js";
|
|
11
|
+
import {
|
|
12
|
+
BRAIN_SEARCH_INDEX_VERSION,
|
|
13
|
+
BRAIN_SENSITIVITY_POLICY_VERSION,
|
|
14
|
+
} from "./search-index-contracts.js";
|
|
9
15
|
import { redactSensitiveText } from "./search.js";
|
|
10
16
|
|
|
11
17
|
const APP_ID = "brain";
|
|
@@ -139,6 +145,7 @@ function sourceConfig(source: SourceRow) {
|
|
|
139
145
|
function sourceHasSlackChannels(source: SourceRow) {
|
|
140
146
|
if (source.provider !== "slack") return false;
|
|
141
147
|
const config = sourceConfig(source);
|
|
148
|
+
if (config.includePublicChannels === true) return true;
|
|
142
149
|
const values = [
|
|
143
150
|
config.channelIds,
|
|
144
151
|
config.channels,
|
|
@@ -314,6 +321,19 @@ export async function readBrainHealth() {
|
|
|
314
321
|
)
|
|
315
322
|
.orderBy(desc(schema.brainSources.updatedAt));
|
|
316
323
|
const sourceIds = sourceRows.map((source) => source.id);
|
|
324
|
+
const audienceIds = await listAccessibleAudienceIds(sourceIds);
|
|
325
|
+
const adminSourceIds = (
|
|
326
|
+
await Promise.all(
|
|
327
|
+
sourceIds.map(async (sourceId) => {
|
|
328
|
+
try {
|
|
329
|
+
await assertAccess("brain-source", sourceId, "admin");
|
|
330
|
+
return sourceId;
|
|
331
|
+
} catch {
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
}),
|
|
335
|
+
)
|
|
336
|
+
).filter((sourceId): sourceId is string => Boolean(sourceId));
|
|
317
337
|
const syncRows = sourceIds.length
|
|
318
338
|
? await db
|
|
319
339
|
.select()
|
|
@@ -329,46 +349,146 @@ export async function readBrainHealth() {
|
|
|
329
349
|
}
|
|
330
350
|
}
|
|
331
351
|
|
|
332
|
-
const captureRows =
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
352
|
+
const captureRows =
|
|
353
|
+
sourceIds.length && audienceIds.length
|
|
354
|
+
? await db
|
|
355
|
+
.select({
|
|
356
|
+
sourceId: schema.brainRawCaptures.sourceId,
|
|
357
|
+
status: schema.brainRawCaptures.status,
|
|
358
|
+
sensitivityDisposition:
|
|
359
|
+
schema.brainRawCaptures.sensitivityDisposition,
|
|
360
|
+
createdAt: schema.brainRawCaptures.createdAt,
|
|
361
|
+
capturedAt: schema.brainRawCaptures.capturedAt,
|
|
362
|
+
})
|
|
363
|
+
.from(schema.brainRawCaptures)
|
|
364
|
+
.innerJoin(
|
|
365
|
+
schema.brainCaptureAudiences,
|
|
366
|
+
eq(
|
|
367
|
+
schema.brainCaptureAudiences.captureId,
|
|
368
|
+
schema.brainRawCaptures.id,
|
|
369
|
+
),
|
|
370
|
+
)
|
|
371
|
+
.where(
|
|
372
|
+
and(
|
|
373
|
+
inArray(schema.brainRawCaptures.sourceId, sourceIds),
|
|
374
|
+
eq(schema.brainRawCaptures.sensitivityDisposition, "allowed"),
|
|
375
|
+
inArray(schema.brainCaptureAudiences.audienceId, audienceIds),
|
|
376
|
+
),
|
|
377
|
+
)
|
|
378
|
+
: [];
|
|
343
379
|
const proposalRows = await db
|
|
344
380
|
.select({ status: schema.brainProposals.status })
|
|
345
381
|
.from(schema.brainProposals)
|
|
346
|
-
.where(
|
|
382
|
+
.where(
|
|
383
|
+
and(
|
|
384
|
+
accessFilter(schema.brainProposals, schema.brainProposalShares),
|
|
385
|
+
or(
|
|
386
|
+
isNull(schema.brainProposals.captureId),
|
|
387
|
+
audienceIds.length
|
|
388
|
+
? inArray(schema.brainProposals.audienceId, audienceIds)
|
|
389
|
+
: undefined,
|
|
390
|
+
),
|
|
391
|
+
),
|
|
392
|
+
);
|
|
347
393
|
const knowledgeRows = await db
|
|
348
394
|
.select({ status: schema.brainKnowledge.status })
|
|
349
395
|
.from(schema.brainKnowledge)
|
|
350
|
-
.where(accessFilter(schema.brainKnowledge, schema.brainKnowledgeShares));
|
|
351
|
-
const queueRows = await db
|
|
352
|
-
.select({
|
|
353
|
-
status: schema.brainIngestQueue.status,
|
|
354
|
-
updatedAt: schema.brainIngestQueue.updatedAt,
|
|
355
|
-
sourceId: schema.brainSources.id,
|
|
356
|
-
})
|
|
357
|
-
.from(schema.brainIngestQueue)
|
|
358
|
-
.innerJoin(
|
|
359
|
-
schema.brainRawCaptures,
|
|
360
|
-
eq(schema.brainIngestQueue.captureId, schema.brainRawCaptures.id),
|
|
361
|
-
)
|
|
362
|
-
.innerJoin(
|
|
363
|
-
schema.brainSources,
|
|
364
|
-
eq(schema.brainRawCaptures.sourceId, schema.brainSources.id),
|
|
365
|
-
)
|
|
366
396
|
.where(
|
|
367
397
|
and(
|
|
368
|
-
|
|
369
|
-
|
|
398
|
+
accessFilter(schema.brainKnowledge, schema.brainKnowledgeShares),
|
|
399
|
+
or(
|
|
400
|
+
isNull(schema.brainKnowledge.captureId),
|
|
401
|
+
audienceIds.length
|
|
402
|
+
? inArray(schema.brainKnowledge.audienceId, audienceIds)
|
|
403
|
+
: undefined,
|
|
404
|
+
),
|
|
370
405
|
),
|
|
371
406
|
);
|
|
407
|
+
const queueRows = audienceIds.length
|
|
408
|
+
? await db
|
|
409
|
+
.select({
|
|
410
|
+
operation: schema.brainIngestQueue.operation,
|
|
411
|
+
status: schema.brainIngestQueue.status,
|
|
412
|
+
updatedAt: schema.brainIngestQueue.updatedAt,
|
|
413
|
+
sourceId: schema.brainSources.id,
|
|
414
|
+
})
|
|
415
|
+
.from(schema.brainIngestQueue)
|
|
416
|
+
.innerJoin(
|
|
417
|
+
schema.brainRawCaptures,
|
|
418
|
+
eq(schema.brainIngestQueue.captureId, schema.brainRawCaptures.id),
|
|
419
|
+
)
|
|
420
|
+
.innerJoin(
|
|
421
|
+
schema.brainSources,
|
|
422
|
+
eq(schema.brainRawCaptures.sourceId, schema.brainSources.id),
|
|
423
|
+
)
|
|
424
|
+
.innerJoin(
|
|
425
|
+
schema.brainCaptureAudiences,
|
|
426
|
+
eq(
|
|
427
|
+
schema.brainCaptureAudiences.captureId,
|
|
428
|
+
schema.brainRawCaptures.id,
|
|
429
|
+
),
|
|
430
|
+
)
|
|
431
|
+
.where(
|
|
432
|
+
and(
|
|
433
|
+
accessFilter(schema.brainSources, schema.brainSourceShares),
|
|
434
|
+
eq(schema.brainRawCaptures.sensitivityDisposition, "allowed"),
|
|
435
|
+
inArray(schema.brainCaptureAudiences.audienceId, audienceIds),
|
|
436
|
+
),
|
|
437
|
+
)
|
|
438
|
+
: [];
|
|
439
|
+
const [sensitivityRows, artifactRows, embeddingRows] = await Promise.all([
|
|
440
|
+
adminSourceIds.length
|
|
441
|
+
? db
|
|
442
|
+
.select({
|
|
443
|
+
disposition: schema.brainSensitivityEvents.disposition,
|
|
444
|
+
confidenceBand: schema.brainSensitivityEvents.confidenceBand,
|
|
445
|
+
})
|
|
446
|
+
.from(schema.brainSensitivityEvents)
|
|
447
|
+
.innerJoin(
|
|
448
|
+
schema.brainSources,
|
|
449
|
+
eq(schema.brainSensitivityEvents.sourceId, schema.brainSources.id),
|
|
450
|
+
)
|
|
451
|
+
.where(
|
|
452
|
+
and(
|
|
453
|
+
accessFilter(schema.brainSources, schema.brainSourceShares),
|
|
454
|
+
inArray(schema.brainSensitivityEvents.sourceId, adminSourceIds),
|
|
455
|
+
),
|
|
456
|
+
)
|
|
457
|
+
: Promise.resolve([]),
|
|
458
|
+
audienceIds.length
|
|
459
|
+
? db
|
|
460
|
+
.select({
|
|
461
|
+
captureId: schema.brainSearchArtifacts.captureId,
|
|
462
|
+
status: schema.brainSearchArtifacts.status,
|
|
463
|
+
})
|
|
464
|
+
.from(schema.brainSearchArtifacts)
|
|
465
|
+
.innerJoin(
|
|
466
|
+
schema.brainSources,
|
|
467
|
+
eq(schema.brainSearchArtifacts.sourceId, schema.brainSources.id),
|
|
468
|
+
)
|
|
469
|
+
.where(
|
|
470
|
+
and(
|
|
471
|
+
accessFilter(schema.brainSources, schema.brainSourceShares),
|
|
472
|
+
inArray(schema.brainSearchArtifacts.audienceId, audienceIds),
|
|
473
|
+
),
|
|
474
|
+
)
|
|
475
|
+
: Promise.resolve([]),
|
|
476
|
+
audienceIds.length
|
|
477
|
+
? db
|
|
478
|
+
.select({ status: schema.brainSearchEmbeddings.status })
|
|
479
|
+
.from(schema.brainSearchEmbeddings)
|
|
480
|
+
.innerJoin(
|
|
481
|
+
schema.brainSources,
|
|
482
|
+
eq(schema.brainSearchEmbeddings.sourceId, schema.brainSources.id),
|
|
483
|
+
)
|
|
484
|
+
.where(
|
|
485
|
+
and(
|
|
486
|
+
accessFilter(schema.brainSources, schema.brainSourceShares),
|
|
487
|
+
inArray(schema.brainSearchEmbeddings.audienceId, audienceIds),
|
|
488
|
+
),
|
|
489
|
+
)
|
|
490
|
+
: Promise.resolve([]),
|
|
491
|
+
]);
|
|
372
492
|
|
|
373
493
|
const configuredCounts = new Map<string, number>();
|
|
374
494
|
for (const source of sourceRows) {
|
|
@@ -417,13 +537,51 @@ export async function readBrainHealth() {
|
|
|
417
537
|
...sourceRows.map((source) => ({ status: source.status })),
|
|
418
538
|
]);
|
|
419
539
|
const captureCounts = countStatuses(captureRows);
|
|
540
|
+
const captureDispositionCounts = countStatuses(
|
|
541
|
+
captureRows.map((capture) => ({
|
|
542
|
+
status: capture.sensitivityDisposition,
|
|
543
|
+
})),
|
|
544
|
+
);
|
|
420
545
|
const proposalCounts = countStatuses(proposalRows);
|
|
421
546
|
const knowledgeCounts = countStatuses(knowledgeRows);
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
|
|
547
|
+
const distillationQueueRows = queueRows.filter(
|
|
548
|
+
(row) => row.operation === "distill",
|
|
549
|
+
);
|
|
550
|
+
const searchQueueRows = queueRows.filter(
|
|
551
|
+
(row) =>
|
|
552
|
+
row.operation === "search-index" || row.operation === "search-unindex",
|
|
553
|
+
);
|
|
554
|
+
const staleQueue = distillationQueueRows.filter(isStaleProcessing).length;
|
|
555
|
+
const failedQueue = distillationQueueRows.filter(
|
|
556
|
+
(row) => row.status === "failed",
|
|
557
|
+
).length;
|
|
558
|
+
const pendingQueue = distillationQueueRows.filter(
|
|
425
559
|
(row) => row.status === "queued" || row.status === "processing",
|
|
426
560
|
).length;
|
|
561
|
+
const staleSearchQueue = searchQueueRows.filter(isStaleProcessing).length;
|
|
562
|
+
const failedSearchQueue = searchQueueRows.filter(
|
|
563
|
+
(row) => row.status === "failed",
|
|
564
|
+
).length;
|
|
565
|
+
const pendingSearchQueue = searchQueueRows.filter(
|
|
566
|
+
(row) => row.status === "queued" || row.status === "processing",
|
|
567
|
+
).length;
|
|
568
|
+
const sensitivityCounts = countStatuses(
|
|
569
|
+
sensitivityRows.map((row) => ({ status: row.disposition })),
|
|
570
|
+
);
|
|
571
|
+
const sensitivityConfidenceCounts = countStatuses(
|
|
572
|
+
sensitivityRows.map((row) => ({ status: row.confidenceBand })),
|
|
573
|
+
);
|
|
574
|
+
const artifactCounts = countStatuses(artifactRows);
|
|
575
|
+
const embeddingCounts = countStatuses(embeddingRows);
|
|
576
|
+
const allowedCaptureCount = captureDispositionCounts.allowed ?? 0;
|
|
577
|
+
const activeArtifactCount = artifactCounts.active ?? 0;
|
|
578
|
+
const indexedCaptureCount = new Set(
|
|
579
|
+
artifactRows
|
|
580
|
+
.filter((artifact) => artifact.status === "active")
|
|
581
|
+
.map((artifact) => artifact.captureId),
|
|
582
|
+
).size;
|
|
583
|
+
const privacySettings = await readBrainSettings();
|
|
584
|
+
const privacyClassifier = brainPrivacyReadiness(privacySettings);
|
|
427
585
|
const lastEval = await readBrainEvalSnapshot();
|
|
428
586
|
|
|
429
587
|
const realSources = sourceSummaries.filter((source) => !source.demo);
|
|
@@ -489,6 +647,9 @@ export async function readBrainHealth() {
|
|
|
489
647
|
]);
|
|
490
648
|
|
|
491
649
|
const nextSteps = [
|
|
650
|
+
!privacyClassifier.configured
|
|
651
|
+
? "Configure Brain's approved privacy classifier. Until then, only deterministic-clean captures are stored; uncertain content is quarantined."
|
|
652
|
+
: null,
|
|
492
653
|
...setupSteps
|
|
493
654
|
.filter((step) => step.status === "next")
|
|
494
655
|
.map((step) => step.detail),
|
|
@@ -563,6 +724,23 @@ export async function readBrainHealth() {
|
|
|
563
724
|
captureRows.map((capture) => capture.capturedAt ?? capture.createdAt),
|
|
564
725
|
),
|
|
565
726
|
counts: captureCounts,
|
|
727
|
+
sensitivityDispositionCounts: captureDispositionCounts,
|
|
728
|
+
},
|
|
729
|
+
privacy: {
|
|
730
|
+
classifier: {
|
|
731
|
+
...privacyClassifier,
|
|
732
|
+
},
|
|
733
|
+
events: {
|
|
734
|
+
total: sensitivityRows.length,
|
|
735
|
+
suppressed: sensitivityCounts.suppressed ?? 0,
|
|
736
|
+
quarantined: sensitivityCounts.quarantined ?? 0,
|
|
737
|
+
released: sensitivityCounts.released ?? 0,
|
|
738
|
+
discarded: sensitivityCounts.discarded ?? 0,
|
|
739
|
+
expired: sensitivityCounts.expired ?? 0,
|
|
740
|
+
counts: sensitivityCounts,
|
|
741
|
+
confidenceCounts: sensitivityConfidenceCounts,
|
|
742
|
+
},
|
|
743
|
+
policyVersion: BRAIN_SENSITIVITY_POLICY_VERSION,
|
|
566
744
|
},
|
|
567
745
|
proposals: {
|
|
568
746
|
pending: proposalCounts.pending ?? 0,
|
|
@@ -583,8 +761,43 @@ export async function readBrainHealth() {
|
|
|
583
761
|
pending: pendingQueue,
|
|
584
762
|
failed: failedQueue,
|
|
585
763
|
stale: staleQueue,
|
|
586
|
-
total:
|
|
587
|
-
counts: countStatuses(
|
|
764
|
+
total: distillationQueueRows.length,
|
|
765
|
+
counts: countStatuses(distillationQueueRows),
|
|
766
|
+
},
|
|
767
|
+
searchIndex: {
|
|
768
|
+
indexVersion: BRAIN_SEARCH_INDEX_VERSION,
|
|
769
|
+
coverage: {
|
|
770
|
+
eligibleCaptures: allowedCaptureCount,
|
|
771
|
+
activeArtifacts: activeArtifactCount,
|
|
772
|
+
indexedCaptures: indexedCaptureCount,
|
|
773
|
+
missingCaptures: Math.max(0, allowedCaptureCount - indexedCaptureCount),
|
|
774
|
+
percent:
|
|
775
|
+
allowedCaptureCount === 0
|
|
776
|
+
? 100
|
|
777
|
+
: Math.round((indexedCaptureCount / allowedCaptureCount) * 10_000) /
|
|
778
|
+
100,
|
|
779
|
+
},
|
|
780
|
+
artifacts: {
|
|
781
|
+
total: artifactRows.length,
|
|
782
|
+
active: artifactCounts.active ?? 0,
|
|
783
|
+
stale: artifactCounts.stale ?? 0,
|
|
784
|
+
deleted: artifactCounts.deleted ?? 0,
|
|
785
|
+
counts: artifactCounts,
|
|
786
|
+
},
|
|
787
|
+
embeddings: {
|
|
788
|
+
total: embeddingRows.length,
|
|
789
|
+
active: embeddingCounts.active ?? 0,
|
|
790
|
+
stale: embeddingCounts.stale ?? 0,
|
|
791
|
+
deleted: embeddingCounts.deleted ?? 0,
|
|
792
|
+
counts: embeddingCounts,
|
|
793
|
+
},
|
|
794
|
+
queue: {
|
|
795
|
+
pending: pendingSearchQueue,
|
|
796
|
+
failed: failedSearchQueue,
|
|
797
|
+
stale: staleSearchQueue,
|
|
798
|
+
total: searchQueueRows.length,
|
|
799
|
+
counts: countStatuses(searchQueueRows),
|
|
800
|
+
},
|
|
588
801
|
},
|
|
589
802
|
retrieval: {
|
|
590
803
|
lastEval,
|