Revert "feat: Go knowledge compiler with scheduler-driven dataset compilation" (#17897)

Reverts infiniflow/ragflow#17881
This commit is contained in:
Jin Hai
2026-08-05 21:50:28 +08:00
committed by GitHub
parent eaf553320f
commit cf13082a1a
165 changed files with 3172 additions and 6959 deletions

View File

@@ -2,7 +2,7 @@ import { useCompilationTemplateGroupOptions } from '@/hooks/use-compilation-temp
import { IRagNode } from '@/interfaces/database/agent';
import { NodeProps } from '@xyflow/react';
import { get } from 'lodash';
import { LabelCard, LLMLabelCard } from './card';
import { LabelCard } from './card';
import { RagNode } from './index';
import { useTranslation } from 'react-i18next';
@@ -11,14 +11,12 @@ export function CompilationNode({ ...props }: NodeProps<IRagNode>) {
const { t } = useTranslation();
const options = useCompilationTemplateGroupOptions();
const groupId = get(data, 'form.compilation_template_group_id');
const llmId = get(data, 'form.llm_id');
const groupName =
options.find((option) => option.value === groupId)?.label ?? groupId;
return (
<RagNode {...props}>
<section className="flex flex-col gap-2">
<LLMLabelCard llmId={llmId}></LLMLabelCard>
<LabelCard className="text-text-primary flex justify-between flex-col gap-1">
<span className="text-text-secondary">
{t('knowledgeConfiguration.compilationTemplate')}

View File

@@ -362,7 +362,6 @@ export const initialExtractorValues = {
export const initialCompilationValues = {
compilation_template_group_id: '',
llm_id: '',
outputs: {
chunks: { type: 'Array<Object>', value: [] },
},

View File

@@ -1,13 +1,10 @@
import { CompilationTemplateFormField } from '@/components/compilation-template-form-field';
import { LargeModelFormField } from '@/components/large-model-form-field';
import { Form } from '@/components/ui/form';
import { zodResolver } from '@hookform/resolvers/zod';
import { memo } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { initialCompilationValues } from '../../constant/pipeline';
import { useOwnerTenantId } from '../../context';
import { useFormChangeCallback } from '../../hooks/use-form-change-callback';
import { useFormValues } from '../../hooks/use-form-values';
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
import { INextOperatorForm } from '../../interface';
@@ -17,44 +14,28 @@ import { Output } from '../components/output';
export const FormSchema = z.object({
compilation_template_group_id: z.string().optional(),
llm_id: z.string().optional(),
});
export type CompilationFormSchemaType = z.infer<typeof FormSchema>;
const outputList = buildOutputList(initialCompilationValues.outputs);
const CompilationForm = ({
node,
onValuesChange,
hideOutputs,
}: INextOperatorForm) => {
const CompilationForm = ({ node }: INextOperatorForm) => {
const defaultValues = useFormValues(initialCompilationValues, node);
const ownerTenantId = useOwnerTenantId();
const form = useForm<CompilationFormSchemaType>({
defaultValues,
resolver: zodResolver(FormSchema),
mode: 'onChange',
});
useWatchFormChange(node?.id, form);
useFormChangeCallback(form, onValuesChange);
return (
<Form {...form}>
<FormWrapper>
<CompilationTemplateFormField name="compilation_template_group_id"></CompilationTemplateFormField>
<LargeModelFormField
name="llm_id"
ownerTenantId={ownerTenantId}
></LargeModelFormField>
<Output list={outputList}></Output>
</FormWrapper>
{!hideOutputs && (
<div className="p-5">
<Output list={outputList}></Output>
</div>
)}
</Form>
);
};

View File

@@ -185,7 +185,7 @@ export const useInitializeOperatorParams = () => {
sys_prompt: t('flow.prompts.system.summary'),
prompts: t('flow.prompts.user.summary'),
},
[Operator.Compiler]: { ...initialCompilationValues, llm_id: llmId },
[Operator.Compiler]: initialCompilationValues,
[Operator.DataOperations]: initialDataOperationsValues,
[Operator.ListOperations]: initialListOperationsValues,
[Operator.VariableAssigner]: initialVariableAssignerValues,

View File

@@ -3,12 +3,18 @@ import { MoreButton } from '@/components/more-button';
import { SharedBadge } from '@/components/shared-badge';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip';
import { AgentCategory } from '@/constants/agent';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
import { AgentListItemType, IFlow } from '@/interfaces/database/agent';
import { CanvasCategoryToFlowType, FlowType, FlowTypeConfig } from './constant';
import { AgentDropdown } from './agent-dropdown';
import { useRenameAgent } from './use-rename-agent';
import { useRef, useState } from 'react';
import { Tag } from 'lucide-react';
export type DatasetCardProps = {
@@ -45,20 +51,51 @@ function AgentTags({ tags }: { tags?: string }) {
.split(',')
.map((t) => t.trim())
.filter(Boolean);
const containerRef = useRef<HTMLDivElement>(null);
const [open, setOpen] = useState(false);
if (list.length === 0) return null;
const handleOpenChange = (isOpen: boolean) => {
if (isOpen) {
const el = containerRef.current;
setOpen(el ? el.scrollHeight > el.clientHeight : false);
} else {
setOpen(false);
}
};
return (
<div className="flex flex-wrap gap-1 mt-1">
{list.map((tag) => (
<Badge
key={tag}
variant="secondary"
className="text-xs font-normal space-x-1"
>
<Tag className="size-3" />
<span>{tag}</span>
</Badge>
))}
</div>
<Tooltip open={open} onOpenChange={handleOpenChange}>
<TooltipTrigger asChild>
<div ref={containerRef} className="line-clamp-2 leading-6 mt-1">
{list.map((tag) => (
<Badge
key={tag}
variant="secondary"
className="text-xs font-normal mr-1 space-x-1"
>
<Tag className="size-3" />
<span>{tag}</span>
</Badge>
))}
</div>
</TooltipTrigger>
<TooltipContent>
<div className="flex flex-wrap gap-1 max-w-[280px]">
{list.map((tag) => (
<Badge
key={tag}
variant="secondary"
className="text-xs font-normal space-x-1"
>
<Tag className="size-3" />
<span>{tag}</span>
</Badge>
))}
</div>
</TooltipContent>
</Tooltip>
);
}

View File

@@ -9,7 +9,6 @@ import {
useDatasetGenerate,
useGenerateStatus,
} from '@/hooks/use-dataset-generate';
import { isGoDatasetBackend } from '@/utils/api-proxy-scheme';
import {
GenerableViewMode,
@@ -59,66 +58,29 @@ export function CompilationEmptyState({
}, [pauseGenerate, data?.id, generateType]);
const showProgress = status === 'running' || status === 'failed';
const isGo = isGoDatasetBackend();
return (
<div className="flex-1 min-h-0 flex flex-col items-center justify-center border border-dashed border-border-button rounded-xl">
{!showProgress ? (
<div className="flex flex-col items-center gap-4">
<p className="text-text-secondary text-lg">{t(TitleKeyMap[type])}</p>
{!isGo && (
<Button
variant="outline"
onClick={handleGenerate}
disabled={disabled}
>
<WandSparkles className="mr-2 size-4" />
{t('knowledgeDetails.generate')}
</Button>
)}
{isGo && (
<p className="text-sm text-text-secondary">
{t('knowledgeDetails.autoCompiled')}
</p>
)}
<Button
variant="outline"
onClick={handleGenerate}
disabled={disabled}
>
<WandSparkles className="mr-2 size-4" />
{t('knowledgeDetails.generate')}
</Button>
</div>
) : (
<div className="grid h-full w-full grid-cols-[1fr_auto_1fr] items-center gap-8 p-6">
<div />
<div className="flex flex-col items-center gap-5">
{isGo ? (
// Go/hybrid: no stable percentage and no scheduler cancel, so show
// the MySQL inflight/backlog counts (or the error diagnostic).
status === 'failed' ? (
<div className="flex flex-col items-center gap-2 text-state-error">
<IconFontFill name="reparse" className="size-8" />
<span className="text-text-primary">
{data?.compilationError || t('message.operated')}
</span>
</div>
) : (
<div className="flex flex-col items-center gap-2 text-text-secondary">
<span className="text-4xl font-medium text-accent-primary">
{t('knowledgeDetails.compiling', {
defaultValue: 'Compiling…',
})}
</span>
<span>
{t('knowledgeDetails.compilingCounts', {
inflight: data?.inflight ?? 0,
backlog: data?.backlog ?? 0,
defaultValue:
'{{inflight}} processing / {{backlog}} queued',
})}
</span>
</div>
)
) : (
<ProgressRing percent={percent} failed={status === 'failed'} />
)}
<ProgressRing percent={percent} failed={status === 'failed'} />
<div className="flex items-center gap-2 text-text-primary">
<span>{t(ViewModeLabelKeyMap[type])}</span>
{!isGo && status === 'failed' && (
{status === 'failed' && (
<span className="cursor-pointer" onClick={handleGenerate}>
<IconFontFill
name="reparse"
@@ -126,7 +88,7 @@ export function CompilationEmptyState({
/>
</span>
)}
{!isGo && status !== 'failed' && (
{status !== 'failed' && (
<span
className="text-state-error cursor-pointer"
onClick={handlePause}

View File

@@ -11,7 +11,6 @@ import {
} from '@/components/ui/tooltip';
import { GenerateStatus, GenerateType } from '@/constants/knowledge';
import { ITraceInfo, useGenerateStatus } from '@/hooks/use-dataset-generate';
import { isGoDatasetBackend } from '@/utils/api-proxy-scheme';
import { UpdateRunProgress } from './update-run-progress';
@@ -41,13 +40,6 @@ export function CompilationUpdateButton({
const isRunning = status === GenerateStatus.Running;
const isGenerating = isRunning || status === GenerateStatus.Failed;
// Go/hybrid: compilation is auto-driven by the scheduler with no manual
// re-merge, so hide the update control rather than offer a trigger that
// cannot work (plan v4.1 §4.2).
if (isGoDatasetBackend()) {
return null;
}
// A failed trace persists (progress stays < 0) until the next run, so it
// must not keep the button visible on its own — only real changes or a
// live run should.

View File

@@ -1,6 +1,5 @@
import { CircleX } from 'lucide-react';
import { useCallback, type MouseEvent } from 'react';
import { useTranslation } from 'react-i18next';
import { IconFontFill } from '@/components/icon-font';
import { GenerateType } from '@/constants/knowledge';
@@ -9,7 +8,6 @@ import {
useDatasetGenerate,
useGenerateStatus,
} from '@/hooks/use-dataset-generate';
import { isGoDatasetBackend } from '@/utils/api-proxy-scheme';
import { cn } from '@/lib/utils';
import { toFixed } from '@/utils/common-util';
@@ -22,10 +20,8 @@ export function UpdateRunProgress({
data,
generateType,
}: UpdateRunProgressProps) {
const { t } = useTranslation();
const { pauseGenerate } = useDatasetGenerate();
const { status, percent } = useGenerateStatus(data);
const isGo = isGoDatasetBackend();
const handlePause = useCallback(
(e: MouseEvent) => {
@@ -37,39 +33,6 @@ export function UpdateRunProgress({
[pauseGenerate, data?.id, generateType],
);
// Go/hybrid: no scheduler task-level cancel, and no stable terminal state, so
// show the MySQL inflight/backlog entry counts instead of a percentage and no
// pause button. Error diagnostic takes priority (see plan v4.1 §4.2).
if (isGo && status === 'running') {
return (
<span className="flex items-center gap-2 text-sm text-text-secondary">
<span className="size-2 rounded-full bg-accent-primary" />
{data?.compilationError
? data.compilationError
: t('knowledgeDetails.compiling', {
defaultValue: 'Compiling…',
})}
{!data?.compilationError && (
<span>
{t('knowledgeDetails.compilingCounts', {
inflight: data?.inflight ?? 0,
backlog: data?.backlog ?? 0,
defaultValue: '{{inflight}} processing / {{backlog}} queued',
})}
</span>
)}
</span>
);
}
if (isGo && status === 'failed') {
return (
<span className="flex items-center gap-2 text-sm text-state-error">
<IconFontFill name="reparse" className="text-accent-primary" />
{data?.compilationError || t('message.operated')}
</span>
);
}
return (
<span className="flex items-center gap-2">
<span className="bg-border-button h-1 w-16 rounded-full">

View File

@@ -1,4 +1,4 @@
export type WikiPageType = 'concept' | 'entity' | 'topic';
export type WikiPageType = 'concept' | 'entity';
/**
* Parse an internal wiki link href into pageType and slug.
@@ -9,7 +9,7 @@ export type WikiPageType = 'concept' | 'entity' | 'topic';
* {pageType}/{slug}
* /{pageType}/{slug}
*
* entity/, concept/ and topic/ links are all considered wiki navigation links.
* Only entity/ and concept/ links are considered wiki navigation links.
*/
export function parseWikiLinkHref(
href: string,
@@ -19,7 +19,7 @@ export function parseWikiLinkHref(
// Prefer the artifact/{datasetId}/{pageType}/{slug} form.
const artifactMatch = normalized.match(
/(?:^|\/)artifact\/[^/]+\/(entity|concept|topic)\/([^/\s"']+)/,
/(?:^|\/)artifact\/[^/]+\/(entity|concept)\/([^/\s"']+)/,
);
if (artifactMatch) {
return {
@@ -29,9 +29,7 @@ export function parseWikiLinkHref(
}
// Fallback to a plain {pageType}/{slug} form.
const simpleMatch = normalized.match(
/(?:^|\/)(entity|concept|topic)\/([^/\s"']+)/,
);
const simpleMatch = normalized.match(/(?:^|\/)(entity|concept)\/([^/\s"']+)/);
if (simpleMatch) {
return {
pageType: simpleMatch[1] as WikiPageType,

View File

@@ -6,7 +6,7 @@ import { IArtifactTopic } from '@/interfaces/database/dataset';
import { useDebounce } from 'ahooks';
import { useCallback, useMemo, useRef, useState } from 'react';
export type WikiPageType = 'concept' | 'entity' | 'topic';
export type WikiPageType = 'concept' | 'entity';
export function useWikiNavigation() {
const scrollRef = useRef<HTMLDivElement>(null);

View File

@@ -52,7 +52,8 @@ import { LinkToDatasetDialog } from './link-to-dataset-dialog';
import { UseMoveDocumentShowType } from './use-move-file';
import { useNavigateToOtherFolder } from './use-navigate-to-folder';
import { isFolderType, isKnowledgeBaseType } from './util';
import { isGoDatasetBackend } from '../../utils/api-proxy-scheme';
declare const __API_PROXY_SCHEME__: string;
type FilesTableProps = Pick<
ReturnType<typeof useFetchFileList>,
@@ -103,7 +104,13 @@ export function FilesTable({
} = useRenameCurrentFile();
// Check if skills feature is enabled (only in hybrid or go mode)
const isSkillsEnabled = useMemo(() => isGoDatasetBackend(), []);
const isSkillsEnabled = useMemo(() => {
const scheme =
typeof __API_PROXY_SCHEME__ !== 'undefined'
? __API_PROXY_SCHEME__
: 'python';
return scheme === 'hybrid' || scheme === 'go';
}, []);
// Sort files with skills folder first, then by time
// Filter out skills folder if not in hybrid/go mode