deer-flow/frontend/src/components/workspace/messages/knowledge-scope-summary.tsx
zhangwei-way b6503e9a35
feat(knowledge): add per-message RAGFlow retrieval scope (#5238)
* feat(knowledge): integrate RAGFlow retrieval and management

* test(knowledge): cover merged listing tool

* feat(knowledge): add per-message retrieval scope

* chore(docs): remove unrelated document

* docs(knowledge): add interaction screenshots

* feat(knowledge): simplify scope selector trigger

* docs(knowledge): refresh selector screenshot

* feat(knowledge): defer standalone management

* docs(knowledge): show chat-only scope UI

* fix(knowledge): honor scope on clarification replies

* fix(knowledge): harden scoped replay validation

* docs(knowledge): clarify replay scope precedence

* fix(knowledge): keep provider settings on tools

* fix(config): preserve tools-only knowledge settings

* fix(knowledge): submit custom assistant identity

* refactor(knowledge): trim PR scope changes

* fix(knowledge): sanitize document scope display

* feat(knowledge): enable scope selection in main chat

* fix(knowledge): emphasize active scope icon without button frame

* fix(knowledge): close context scrubbing and refresh e2e checks

* fix(knowledge): preserve idempotent canonical retries

* fix(knowledge): accept promptless conversation runs

* style(knowledge): format backend regression tests

* chore(knowledge): trim PR scope and fix frontend format

* fix(knowledge): remove shared-scope notice

* fix(knowledge): remove scope persistence notice

* docs(knowledge): include main chat in catalog scope

* fix(knowledge): preserve scope recovery and upgrades

* fix(config): preserve LightRAG knowledge upgrades

---------

Co-authored-by: foreleven <for-eleven@hotmail.com>
2026-09-18 16:59:31 +08:00

67 lines
1.9 KiB
TypeScript

import { DatabaseIcon } from "lucide-react";
import { useI18n } from "@/core/i18n/hooks";
import {
KNOWLEDGE_SCOPE_KEY,
readKnowledgeScopeSnapshot,
} from "@/core/knowledge";
export function KnowledgeScopeSummary({
additionalKwargs,
}: {
additionalKwargs: Record<string, unknown> | undefined;
}) {
const { t } = useI18n();
const snapshot = readKnowledgeScopeSnapshot(
additionalKwargs?.[KNOWLEDGE_SCOPE_KEY],
);
if (!snapshot) return null;
if (snapshot.mode === "all") {
return <SummaryText text={t.knowledge.scope.historyAll} />;
}
if (snapshot.mode === "disabled") {
return <SummaryText text={t.knowledge.scope.historyDisabled} />;
}
const datasetCount = snapshot.dataset_ids?.length ?? 0;
const documentCount =
snapshot.document_filters?.reduce(
(total, filter) => total + filter.document_ids.length,
0,
) ?? 0;
const datasetNames = snapshot.display?.datasets
.map((dataset) => dataset.name)
.filter(Boolean);
const documentNames = snapshot.display?.datasets
.flatMap(
(dataset) => dataset.documents?.map((document) => document.name) ?? [],
)
.filter(Boolean);
const details = [
datasetNames?.length ? datasetNames.join("、") : null,
documentNames?.length ? documentNames.join("、") : null,
].filter((value): value is string => Boolean(value));
return (
<SummaryText
text={t.knowledge.scope.historySelected(datasetCount, documentCount)}
details={details.join(" · ") || undefined}
/>
);
}
function SummaryText({ text, details }: { text: string; details?: string }) {
return (
<div
className="text-muted-foreground flex max-w-full items-center justify-end gap-1 text-xs"
data-testid="message-knowledge-scope"
title={details}
>
<DatabaseIcon className="size-3 shrink-0" />
<span className="truncate">
{details ? `${text} · ${details}` : text}
</span>
</div>
);
}