// The status a page reads: the module flag, the search service's readiness (separate from the // indexing indicator, which is the per-document rows), and the document counts by progress state. import { type DocumentStatus, documents } from "../contract/index.js" import { type KnowledgeDeps, type KnowledgeScope, knowledgeEnabled } from "./ports.js" const PAGE = 200 export interface KnowledgeStatus { enabled: boolean service: { state: "registered" | "indexing" | "ready" | "degraded" | "disabled" | "unavailable"; reasons: string[] } documents: Record } export async function knowledgeStatusOf(deps: KnowledgeDeps, scope: KnowledgeScope): Promise { const counts: Record = { queued: 0, indexing: 0, indexed: 0, failed: 0, cancelled: 0 } let cursor: string | undefined for (;;) { const page = await deps.data .forScope(scope) .of(documents) .list({ limit: PAGE, ...(cursor === undefined ? {} : { cursor }) }) for (const row of page.items) counts[row.status as DocumentStatus] += 1 if (!page.hasMore) break cursor = page.cursor } const enabled = await knowledgeEnabled(deps, scope) const readiness = deps.search === undefined ? { state: "unavailable" as const, reasons: ["the knowledge search service is not bound in this process"] } : await deps.search.readiness(scope).catch((error: unknown) => ({ state: "unavailable" as const, reasons: [ error instanceof Error ? (error.message.split("\n")[0] ?? error.message) : "the search service did not answer", ], })) return { enabled, service: readiness, documents: counts } }