feat: RAG Integration (#238)

* feat: add rag provider and retriever

* feat: retriever tool

* feat: add retriever tool to the researcher node

* feat: add rag http apis

* feat: new message input supports resource mentions

* feat: new message input component support resource mentions

* refactor: need_web_search to need_search

* chore: RAG integration docs

* chore: change example api host

* fix: user message color in dark mode

* fix: mentions style

* feat: add local_search_tool to researcher prompt

* chore: research prompt

* fix: ragflow page size and reporter with

* docs: ragflow integration and add acknowledgment projects

* chore: format
This commit is contained in:
JeffJiang
2025-05-28 14:13:46 +08:00
committed by GitHub
parent 0565ab6d27
commit 462752b462
43 changed files with 1172 additions and 181 deletions

View File

@@ -4,6 +4,7 @@
import { env } from "~/env";
import type { MCPServerMetadata } from "../mcp";
import type { Resource } from "../messages";
import { extractReplayIdFromSearchParams } from "../replay/get-replay-id";
import { fetchStream } from "../sse";
import { sleep } from "../utils";
@@ -15,6 +16,7 @@ export async function* chatStream(
userMessage: string,
params: {
thread_id: string;
resources?: Array<Resource>;
auto_accepted_plan: boolean;
max_plan_iterations: number;
max_step_num: number;

View File

@@ -3,9 +3,12 @@
import { useEffect, useRef, useState } from "react";
import { env } from "~/env";
import { useReplay } from "../replay";
import { fetchReplayTitle } from "./chat";
import { getRAGConfig } from "./rag";
export function useReplayMetadata() {
const { isReplay } = useReplay();
@@ -39,3 +42,26 @@ export function useReplayMetadata() {
}, [isLoading, isReplay, title]);
return { title, isLoading, hasError: error };
}
export function useRAGProvider() {
const [loading, setLoading] = useState(true);
const [provider, setProvider] = useState<string | null>(null);
useEffect(() => {
if (env.NEXT_PUBLIC_STATIC_WEBSITE_ONLY) {
setLoading(false);
return;
}
getRAGConfig()
.then(setProvider)
.catch((e) => {
setProvider(null);
console.error("Failed to get RAG provider", e);
})
.finally(() => {
setLoading(false);
});
}, []);
return { provider, loading };
}

24
web/src/core/api/rag.ts Normal file
View File

@@ -0,0 +1,24 @@
import type { Resource } from "../messages";
import { resolveServiceURL } from "./resolve-service-url";
export function queryRAGResources(query: string) {
return fetch(resolveServiceURL(`rag/resources?query=${query}`), {
method: "GET",
})
.then((res) => res.json())
.then((res) => {
return res.resources as Array<Resource>;
})
.catch((err) => {
return [];
});
}
export function getRAGConfig() {
return fetch(resolveServiceURL(`rag/config`), {
method: "GET",
})
.then((res) => res.json())
.then((res) => res.provider);
}

View File

@@ -21,6 +21,7 @@ export interface Message {
options?: Option[];
finishReason?: "stop" | "interrupt" | "tool_calls";
interruptFeedback?: string;
resources?: Array<Resource>;
}
export interface Option {
@@ -35,3 +36,8 @@ export interface ToolCallRuntime {
argsChunks?: string[];
result?: string;
}
export interface Resource {
uri: string;
title: string;
}

View File

@@ -7,7 +7,7 @@ import { create } from "zustand";
import { useShallow } from "zustand/react/shallow";
import { chatStream, generatePodcast } from "../api";
import type { Message } from "../messages";
import type { Message, Resource } from "../messages";
import { mergeMessage } from "../messages";
import { parseJSON } from "../utils";
@@ -78,8 +78,10 @@ export async function sendMessage(
content?: string,
{
interruptFeedback,
resources,
}: {
interruptFeedback?: string;
resources?: Array<Resource>;
} = {},
options: { abortSignal?: AbortSignal } = {},
) {
@@ -90,6 +92,7 @@ export async function sendMessage(
role: "user",
content: content,
contentChunks: [content],
resources,
});
}
@@ -99,6 +102,7 @@ export async function sendMessage(
{
thread_id: THREAD_ID,
interrupt_feedback: interruptFeedback,
resources,
auto_accepted_plan: settings.autoAcceptedPlan,
enable_background_investigation:
settings.enableBackgroundInvestigation ?? true,