fix(km): bound knowledge readbacks under pool pressure
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m19s
CD Pipeline / build-and-deploy (push) Successful in 4m56s
CD Pipeline / post-deploy-checks (push) Has been cancelled
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m19s
CD Pipeline / build-and-deploy (push) Successful in 4m56s
CD Pipeline / post-deploy-checks (push) Has been cancelled
This commit is contained in:
@@ -64,6 +64,7 @@ interface ListResponse {
|
||||
categories: CategoryCount[]
|
||||
asset_taxonomy?: AssetTaxonomyCount[]
|
||||
readback_status?: 'ready' | 'degraded' | string
|
||||
degraded_reason_code?: string | null
|
||||
operator_stage?: string | null
|
||||
next_step?: string | null
|
||||
writes_on_read?: boolean
|
||||
@@ -496,7 +497,7 @@ export default function KnowledgeBasePage({
|
||||
const [assetTaxonomy, setAssetTaxonomy] = useState<AssetTaxonomyCount[]>(ASSET_TAXONOMY_FALLBACK_COUNTS)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [entryFetchError, setEntryFetchError] = useState<string | null>(null)
|
||||
const [entryReadback, setEntryReadback] = useState<Pick<ListResponse, 'readback_status' | 'operator_stage' | 'next_step'> | null>(null)
|
||||
const [entryReadback, setEntryReadback] = useState<Pick<ListResponse, 'readback_status' | 'degraded_reason_code' | 'operator_stage' | 'next_step'> | null>(null)
|
||||
const [governanceTelemetry, setGovernanceTelemetry] = useState<KnowledgeGovernanceTelemetry>({
|
||||
staleCandidates: null,
|
||||
ownerReviews: null,
|
||||
@@ -541,6 +542,7 @@ export default function KnowledgeBasePage({
|
||||
setAssetTaxonomy(data.asset_taxonomy?.length ? data.asset_taxonomy : ASSET_TAXONOMY_FALLBACK_COUNTS)
|
||||
setEntryReadback({
|
||||
readback_status: data.readback_status ?? 'ready',
|
||||
degraded_reason_code: data.degraded_reason_code ?? null,
|
||||
operator_stage: data.operator_stage ?? null,
|
||||
next_step: data.next_step ?? null,
|
||||
})
|
||||
@@ -574,23 +576,15 @@ export default function KnowledgeBasePage({
|
||||
setGovernanceLoading(true)
|
||||
try {
|
||||
const apiBase = process.env.NEXT_PUBLIC_API_URL ?? ''
|
||||
const [staleCandidates, ownerReviews, burnDown, completionQueue, ragStats] = await Promise.all([
|
||||
fetch(`${apiBase}/api/v1/ai/governance/km-stale-candidates?project_id=awoooi&limit=5`)
|
||||
.then(res => res.ok ? res.json() : null)
|
||||
.catch(() => null),
|
||||
fetch(`${apiBase}/api/v1/ai/governance/km-stale-owner-reviews?project_id=awoooi&dispatch_status=pending&limit=5`)
|
||||
.then(res => res.ok ? res.json() : null)
|
||||
.catch(() => null),
|
||||
fetch(`${apiBase}/api/v1/ai/governance/km-stale-owner-review-burndown?project_id=awoooi&limit=5`)
|
||||
.then(res => res.ok ? res.json() : null)
|
||||
.catch(() => null),
|
||||
fetch(`${apiBase}/api/v1/ai/governance/km-stale-owner-review-completion-queue?project_id=awoooi&status_bucket=all&limit=5`)
|
||||
.then(res => res.ok ? res.json() : null)
|
||||
.catch(() => null),
|
||||
fetch(`${apiBase}/api/v1/knowledge/rag/stats?project_id=${encodeURIComponent(KNOWLEDGE_PROJECT_ID)}`)
|
||||
.then(res => res.ok ? res.json() : null)
|
||||
.catch(() => null),
|
||||
])
|
||||
const fetchOptionalJson = async (path: string) => fetch(`${apiBase}${path}`)
|
||||
.then(res => res.ok ? res.json() : null)
|
||||
.catch(() => null)
|
||||
|
||||
const staleCandidates = await fetchOptionalJson('/api/v1/ai/governance/km-stale-candidates?project_id=awoooi&limit=5')
|
||||
const ownerReviews = await fetchOptionalJson('/api/v1/ai/governance/km-stale-owner-reviews?project_id=awoooi&dispatch_status=pending&limit=5')
|
||||
const burnDown = await fetchOptionalJson('/api/v1/ai/governance/km-stale-owner-review-burndown?project_id=awoooi&limit=5')
|
||||
const completionQueue = await fetchOptionalJson('/api/v1/ai/governance/km-stale-owner-review-completion-queue?project_id=awoooi&status_bucket=all&limit=5')
|
||||
const ragStats = await fetchOptionalJson(`/api/v1/knowledge/rag/stats?project_id=${encodeURIComponent(KNOWLEDGE_PROJECT_ID)}`)
|
||||
|
||||
setGovernanceTelemetry({
|
||||
staleCandidates,
|
||||
@@ -694,8 +688,11 @@ export default function KnowledgeBasePage({
|
||||
)
|
||||
const totalCount = categories.reduce((sum, c) => sum + c.count, 0)
|
||||
const isKnowledgeListUnavailable = Boolean(entryFetchError)
|
||||
const isKnowledgeListDegraded = entryReadback?.readback_status === 'degraded'
|
||||
const knowledgeReadbackReady = !loading && !isKnowledgeListUnavailable && !isKnowledgeListDegraded
|
||||
const readbackStatus = entryReadback?.readback_status ?? null
|
||||
const isKnowledgeSourceBacked = Boolean(readbackStatus?.startsWith('source_backed'))
|
||||
const isKnowledgeListDegraded = Boolean(readbackStatus && readbackStatus !== 'ready')
|
||||
const hasKnowledgePayload = entries.length > 0 || total > 0 || categories.some(category => category.count > 0)
|
||||
const knowledgeReadbackReady = !loading && !isKnowledgeListUnavailable && (!isKnowledgeListDegraded || hasKnowledgePayload)
|
||||
const localeCode = params.locale === 'en' ? 'en-US' : 'zh-TW'
|
||||
const formatCount = useCallback(
|
||||
(value: number) => value.toLocaleString(localeCode),
|
||||
@@ -1430,15 +1427,27 @@ export default function KnowledgeBasePage({
|
||||
<div className="min-w-0">
|
||||
<div className="flex items-center gap-2 text-xs font-label text-status-warning">
|
||||
<TriangleAlert className="h-4 w-4 shrink-0" aria-hidden="true" />
|
||||
<span>{entryFetchError ? t('dataChain.errorTitle') : t('dataChain.degradedTitle')}</span>
|
||||
<span>
|
||||
{entryFetchError
|
||||
? t('dataChain.errorTitle')
|
||||
: isKnowledgeSourceBacked
|
||||
? t('dataChain.sourceBackedTitle')
|
||||
: t('dataChain.degradedTitle')}
|
||||
</span>
|
||||
</div>
|
||||
<p className="mt-1 text-xs font-body leading-5 text-secondary">
|
||||
{entryFetchError
|
||||
? t('dataChain.errorDescription', { reason: entryFetchError })
|
||||
: t('dataChain.degradedDescription', {
|
||||
stage: entryReadback?.operator_stage ?? '--',
|
||||
next: entryReadback?.next_step ?? '--',
|
||||
})}
|
||||
: isKnowledgeSourceBacked
|
||||
? t('dataChain.sourceBackedDescription', {
|
||||
reason: entryReadback?.degraded_reason_code ?? '--',
|
||||
stage: entryReadback?.operator_stage ?? '--',
|
||||
next: entryReadback?.next_step ?? '--',
|
||||
})
|
||||
: t('dataChain.degradedDescription', {
|
||||
stage: entryReadback?.operator_stage ?? '--',
|
||||
next: entryReadback?.next_step ?? '--',
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user