mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-08-10 17:31:29 +08:00
Revert "feat: Go knowledge compiler with scheduler-driven dataset compilation" (#17897)
Reverts infiniflow/ragflow#17881
This commit is contained in:
@@ -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')}
|
||||
|
||||
@@ -362,7 +362,6 @@ export const initialExtractorValues = {
|
||||
|
||||
export const initialCompilationValues = {
|
||||
compilation_template_group_id: '',
|
||||
llm_id: '',
|
||||
outputs: {
|
||||
chunks: { type: 'Array<Object>', value: [] },
|
||||
},
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user