feat(frontend): add workspace single and multi round rag

This commit is contained in:
fengxiangdebaozi committed 2026-08-13 21:05:31 +08:00
1 parent 5a4881053d
commit 4f536d9b39
12 files changed
+1122 -119

No files matched your search

@@ -16,6 +16,7 @@ import { apiFetch } from "@/core/api";
import { getBackendBaseURL } from "@/core/config";
import { isThreadRagModeLocked, useLocalSettings } from "@/core/settings";
import { isSingleRoundRagMessage } from "@/core/threads/use-single-round-rag";
import { isMultiRoundRagMessage } from "@/core/threads/use-multi-round-rag";
import { useSkills } from "@/core/skills/hooks";
import type { SkillDisplayConfig } from "@/core/skills/type";
import {
@@ -93,13 +94,20 @@ const ChatBox: React.FC<{
const [settings] = useLocalSettings();
const ragModeEnabled =
settings.display.ragModeEnabled || isThreadRagModeLocked(threadId);
// Frontend single-round RAG writes its own source tool message, so it should
// use the same reference panel without changing the user's global RAG mode.
const hasSingleRoundRag = useMemo(
() => (thread.values.messages ?? []).some(isSingleRoundRagMessage),
// Frontend RAG modes write their own hidden source tool messages. They use
// the existing reference panel, but must not request or write reference
// batches through DeerFlow's backend APIs.
const hasFrontendRag = useMemo(
() =>
(thread.values.messages ?? []).some(
(message) =>
isSingleRoundRagMessage(message) || isMultiRoundRagMessage(message),
),
[thread.values.messages],
);
const referencesEnabled = ragModeEnabled || hasSingleRoundRag;
const referencesEnabled = ragModeEnabled || hasFrontendRag;
const shouldFetchBackendReferenceBatches =
referencesEnabled && !hasFrontendRag;
const { skills } = useSkills();
const {
@@ -128,7 +136,7 @@ const ChatBox: React.FC<{
);
}, [referencesEnabled, skillDisplayMap, thread.isLoading, thread.values.messages]);
useEffect(() => {
if (!referencesEnabled) {
if (!shouldFetchBackendReferenceBatches) {
setBackendReferenceBatches([]);
return;
}
@@ -164,7 +172,12 @@ const ChatBox: React.FC<{
}
});
return () => controller.abort();
}, [referencesEnabled, thread.isLoading, threadId, thread.values.messages]);
}, [
shouldFetchBackendReferenceBatches,
thread.isLoading,
threadId,
thread.values.messages,
]);
const adaptedBackendReferenceBatches = useMemo(
() =>
adaptBackendReferenceBatches(
@@ -175,15 +188,22 @@ const ChatBox: React.FC<{
);
const referenceBatches = useMemo(
() => {
if (adaptedBackendReferenceBatches.length > 0) {
if (
shouldFetchBackendReferenceBatches &&
adaptedBackendReferenceBatches.length > 0
) {
return adaptedBackendReferenceBatches;
}
return fallbackReferenceBatches;
},
[adaptedBackendReferenceBatches, fallbackReferenceBatches],
[
adaptedBackendReferenceBatches,
fallbackReferenceBatches,
shouldFetchBackendReferenceBatches,
],
);
useEffect(() => {
if (!referencesEnabled) {
if (!shouldFetchBackendReferenceBatches) {
return;
}
const signature = JSON.stringify({
@@ -210,7 +230,14 @@ const ChatBox: React.FC<{
fallbackBatches: debugReferenceBatches(fallbackReferenceBatches),
finalBatches: debugReferenceBatches(referenceBatches),
});
}, [adaptedBackendReferenceBatches, backendReferenceBatches, fallbackReferenceBatches, referencesEnabled, referenceBatches, threadId]);
}, [
adaptedBackendReferenceBatches,
backendReferenceBatches,
fallbackReferenceBatches,
referenceBatches,
shouldFetchBackendReferenceBatches,
threadId,
]);
const latestReferenceBatch =
referenceBatches.length > 0
? referenceBatches[referenceBatches.length - 1]!
@@ -221,7 +248,7 @@ const ChatBox: React.FC<{
const referenceSources = activeReferenceBatch?.sources ?? [];
const hasCitationReferences = referenceSources.length > 0;
useEffect(() => {
if (!referencesEnabled || !activeReferenceBatch) {
if (!shouldFetchBackendReferenceBatches || !activeReferenceBatch) {
return;
}
logReferenceDebug("frontend-active-reference-batch-payload", threadId, {
@@ -230,7 +257,7 @@ const ChatBox: React.FC<{
sourceCount: activeReferenceBatch.sources.length,
sources: activeReferenceBatch.sources.map(debugReferenceSource),
});
}, [activeReferenceBatch, referencesEnabled, threadId]);
}, [activeReferenceBatch, shouldFetchBackendReferenceBatches, threadId]);
useEffect(() => {
if (hasCitationReferences) {
setReferencesOpen(true);