Fix: resolve shared embedding/LLM model selection errors (#16773)

This commit is contained in:
chanx
2026-07-09 15:17:49 +08:00
committed by GitHub
parent cc94639555
commit a9420a7832
30 changed files with 228 additions and 36 deletions

View File

@@ -41,10 +41,11 @@ export const LargeModelFilterFormSchema = {
type LargeModelFormFieldProps = Pick<
NextInnerLLMSelectProps,
'showSpeech2TextModel'
'showSpeech2TextModel' | 'ownerTenantId'
>;
export function LargeModelFormField({
showSpeech2TextModel: showTTSModel,
ownerTenantId,
}: LargeModelFormFieldProps) {
const form = useFormContext();
const { t } = useTranslation();
@@ -96,6 +97,7 @@ export function LargeModelFormField({
{...field}
filter={filter}
showSpeech2TextModel={showTTSModel}
ownerTenantId={ownerTenantId}
/>
</FormControl>
</section>
@@ -110,12 +112,13 @@ export function LargeModelFormField({
type LargeModelFormFieldWithoutFilterProps = Pick<
NextInnerLLMSelectProps,
'triggerTestId' | 'optionTestIdPrefix'
'triggerTestId' | 'optionTestIdPrefix' | 'ownerTenantId'
>;
export function LargeModelFormFieldWithoutFilter({
triggerTestId,
optionTestIdPrefix,
ownerTenantId,
}: LargeModelFormFieldWithoutFilterProps = {}) {
const form = useFormContext();
@@ -130,6 +133,7 @@ export function LargeModelFormFieldWithoutFilter({
{...field}
triggerTestId={triggerTestId}
optionTestIdPrefix={optionTestIdPrefix}
ownerTenantId={ownerTenantId}
/>
</FormControl>
<FormMessage />

View File

@@ -17,6 +17,7 @@ export interface NextInnerLLMSelectProps {
showSpeech2TextModel?: boolean;
triggerTestId?: string;
optionTestIdPrefix?: string;
ownerTenantId?: string;
}
const NextInnerLLMSelect = forwardRef<
@@ -31,6 +32,7 @@ const NextInnerLLMSelect = forwardRef<
showSpeech2TextModel = false,
triggerTestId,
optionTestIdPrefix,
ownerTenantId,
},
ref,
) => {
@@ -72,6 +74,7 @@ const NextInnerLLMSelect = forwardRef<
<LlmSettingFieldItems
modelTypes={modelTypes}
llmOptionTestIdPrefix={optionTestIdPrefix}
ownerTenantId={ownerTenantId}
></LlmSettingFieldItems>
</PopoverContent>
</Popover>

View File

@@ -8,9 +8,15 @@ export type LLMFormFieldProps = {
testId?: string;
optionTestIdPrefix?: string;
config?: any;
ownerTenantId?: string;
};
export function LLMFormField({ name, config, modelTypes }: LLMFormFieldProps) {
export function LLMFormField({
name,
config,
modelTypes,
ownerTenantId,
}: LLMFormFieldProps) {
const { t } = useTranslation();
return (
@@ -18,6 +24,7 @@ export function LLMFormField({ name, config, modelTypes }: LLMFormFieldProps) {
<ModelTreeSelect
allowClear={config?.allowClear ?? false}
modelTypes={modelTypes}
ownerTenantId={ownerTenantId}
/>
</RAGFlowFormItem>
);

View File

@@ -41,6 +41,7 @@ interface LlmSettingFieldItemsProps {
| 'thinking'
>;
showCollapse?: boolean;
ownerTenantId?: string;
}
export const LLMIdFormField = {
@@ -86,6 +87,7 @@ export function LlmSettingFieldItems({
],
llmId,
showCollapse = false,
ownerTenantId,
}: LlmSettingFieldItemsProps) {
const form = useFormContext();
const { t } = useTranslate('chat');
@@ -154,6 +156,7 @@ export function LlmSettingFieldItems({
name={llmId ?? getFieldWithPrefix('llm_id')}
testId={llmSelectTestId}
optionTestIdPrefix={llmOptionTestIdPrefix}
ownerTenantId={ownerTenantId}
></LLMFormField>
<CollapseComponent {...collapseProps}>
<section className="space-y-5">

View File

@@ -9,7 +9,7 @@ import {
} from '@/components/ui/form';
import { useFetchAllAddedModels } from '@/hooks/use-llm-request';
import { IAddedModel } from '@/interfaces/database/llm';
import { getRealModelName } from '@/utils/llm-util';
import { buildModelValue, getRealModelName } from '@/utils/llm-util';
import { useCallback, useMemo } from 'react';
import { useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
@@ -62,7 +62,7 @@ export function buildModelTree(
title: instance,
children: models.reduce<TreeSelectNode[]>((acc, m) => {
const modelName = getRealModelName(m.name);
const id = `${modelName}@${m.instance_name}@${m.provider_name}`;
const id = m.model_id;
if (seenLeafIds.has(id)) return acc;
seenLeafIds.add(id);
const leafNode: TreeSelectNode = {
@@ -106,6 +106,7 @@ export interface ModelTreeSelectProps {
className?: string;
renderSelected?: (node: TreeSelectNode | undefined) => React.ReactNode;
testId?: string;
ownerTenantId?: string;
}
export function ModelTreeSelect({
@@ -119,18 +120,58 @@ export function ModelTreeSelect({
className,
renderSelected,
testId,
ownerTenantId,
}: ModelTreeSelectProps) {
const { data: allAddedModels } = useFetchAllAddedModels();
const { data: allAddedModels } = useFetchAllAddedModels(
undefined,
ownerTenantId,
);
const treeData = useMemo(
() => buildModelTree(allAddedModels, modelTypes),
[allAddedModels, modelTypes],
);
// Backward compatibility: map legacy concatenated ids
// ("modelName@instanceName@providerName") to new model_id-based ids so
// that previously persisted values still display correctly.
const legacyIdMap = useMemo(() => {
const map = new Map<string, string>();
const walk = (nodes: TreeSelectNode[]) => {
for (const node of nodes) {
if (node.children?.length) {
walk(node.children);
} else if (node.data) {
const legacyId = buildModelValue({
model_name: node.data.model_name,
model_instance: node.data.instance_name,
model_provider: node.data.provider_name,
});
map.set(legacyId, node.id);
}
}
};
walk(treeData);
return map;
}, [treeData]);
const normalizedValue = useMemo(() => {
if (!value) return value;
return legacyIdMap.get(value) ?? value;
}, [value, legacyIdMap]);
const defaultRenderSelected = useCallback(
(node: TreeSelectNode | undefined) => {
if (!node?.id) return null;
return <LLMLabel value={node.id} />;
if (!node?.data) return null;
return (
<LLMLabel
value={buildModelValue({
model_name: node.data.model_name,
model_instance: node.data.instance_name,
model_provider: node.data.provider_name,
})}
/>
);
},
[],
);
@@ -138,7 +179,7 @@ export function ModelTreeSelect({
return (
<TreeSelect
data={treeData}
value={value}
value={normalizedValue}
onChange={onChange}
placeholder={placeholder}
disabled={disabled}

View File

@@ -2,6 +2,7 @@ import { FormLayout } from '@/constants/form';
import { DocumentParserType } from '@/constants/knowledge';
import { useTranslate } from '@/hooks/common-hooks';
import { cn } from '@/lib/utils';
import { useKnowledgeBaseContext } from '@/pages/dataset/contexts/knowledge-base-context';
import { LLMModelItem } from '@/pages/dataset/dataset-setting/configuration/common-item';
import {
GenerateLogButton,
@@ -145,6 +146,7 @@ const GraphRagItems = ({
<LLMModelItem
label={t('globalIndexModel')}
name={'parser_config.llm_id'}
ownerTenantId={useKnowledgeBaseContext().knowledgeBase?.tenant_id}
/>
<UseGraphRagFormField
data={data}

View File

@@ -25,9 +25,13 @@ const DefaultTopK = 'top_k';
interface RerankFormFieldProps {
name?: string;
ownerTenantId?: string;
}
function RerankFormField({ name = DefaultRerankId }: RerankFormFieldProps) {
function RerankFormField({
name = DefaultRerankId,
ownerTenantId,
}: RerankFormFieldProps) {
const form = useFormContext();
const { t } = useTranslate('knowledgeDetails');
@@ -43,6 +47,7 @@ function RerankFormField({ name = DefaultRerankId }: RerankFormFieldProps) {
modelTypes={['rerank']}
allowClear
placeholder={t('rerankPlaceholder')}
ownerTenantId={ownerTenantId}
{...field}
/>
</FormControl>
@@ -60,9 +65,13 @@ export const rerankFormSchema = {
interface RerankFormFieldsProps {
prefix?: string;
ownerTenantId?: string;
}
export function RerankFormFields({ prefix = '' }: RerankFormFieldsProps) {
export function RerankFormFields({
prefix = '',
ownerTenantId,
}: RerankFormFieldsProps) {
const { watch } = useFormContext();
const { t } = useTranslate('knowledgeDetails');
const rerankIdName = prefixName(prefix, DefaultRerankId);
@@ -72,7 +81,10 @@ export function RerankFormFields({ prefix = '' }: RerankFormFieldsProps) {
return (
<>
<RerankFormField name={rerankIdName}></RerankFormField>
<RerankFormField
name={rerankIdName}
ownerTenantId={ownerTenantId}
></RerankFormField>
{rerankId && (
<SliderInputFormField
name={topKName}

View File

@@ -105,9 +105,12 @@ export const useFetchAddedProviders = () => {
return { data, loading };
};
export const useFetchAllAddedModels = (modelType?: string) => {
export const useFetchAllAddedModels = (
modelType?: string,
ownerTenantId?: string,
) => {
const { data, isFetching: loading } = useQuery<IAddedModel[]>({
queryKey: LlmKeys.allModels(modelType),
queryKey: [...LlmKeys.allModels(modelType), ownerTenantId],
initialData: [],
gcTime: 0,
queryFn: async () => {
@@ -115,6 +118,9 @@ export const useFetchAllAddedModels = (modelType?: string) => {
if (modelType) {
params.type = modelType;
}
if (ownerTenantId) {
params.owner_tenant_id = ownerTenantId;
}
const { data } = await llmService.listAllAddedModels({ params }, true);
return data?.data ?? [];

View File

@@ -78,12 +78,15 @@ export interface IProviderInstance {
provider_order?: string;
}
export interface IAddedModel {
model_id: string;
model_type: string[];
name: string;
provider_id: string;
provider_name: string;
instance_id: string;
instance_name: string;
tenant_id?: string;
tenant_name?: string;
}
export interface IInstanceModel {

View File

@@ -71,6 +71,7 @@ export interface IEditInstanceModelRequestBody {
export interface IListAllModelsRequestParams {
type?: string;
owner_tenant_id?: string;
}
export interface IUpdateModelStatusRequestBody {

View File

@@ -2,7 +2,7 @@ import { INodeEvent } from '@/hooks/use-send-message';
import { RAGFlowNodeType } from '@/interfaces/database/agent';
import { IMessage } from '@/interfaces/database/chat';
import { HandleType, Position } from '@xyflow/react';
import { Dispatch, SetStateAction, createContext } from 'react';
import { Dispatch, SetStateAction, createContext, useContext } from 'react';
import { useAddNode } from './hooks/use-add-node';
import { useCacheChatLog } from './hooks/use-cache-chat-log';
import { useShowFormDrawer, useShowLogSheet } from './hooks/use-show-drawer';
@@ -11,6 +11,13 @@ export const AgentFormContext = createContext<RAGFlowNodeType | undefined>(
undefined,
);
export const OwnerTenantIdContext = createContext<string | undefined>(
undefined,
);
// eslint-disable-next-line react-refresh/only-export-components
export const useOwnerTenantId = () => useContext(OwnerTenantIdContext);
type AgentInstanceContextType = Pick<
ReturnType<typeof useAddNode>,
'addCanvasNode'

View File

@@ -33,6 +33,7 @@ import {
NodeHandleId,
VariableType,
} from '../../constant';
import { useOwnerTenantId } from '../../context';
import { INextOperatorForm } from '../../interface';
import useGraphStore from '../../store';
import { hasSubAgentOrTool, isBottomSubAgent } from '../../utils';
@@ -84,6 +85,7 @@ export type AgentFormSchemaType = z.infer<typeof FormSchema>;
function AgentForm({ node }: INextOperatorForm) {
const { t } = useTranslation();
const ownerTenantId = useOwnerTenantId();
const { edges, deleteEdgesBySourceAndSourceHandle } = useGraphStore(
(state) => state,
);
@@ -158,7 +160,7 @@ function AgentForm({ node }: INextOperatorForm) {
<Form {...form}>
<FormWrapper>
{isSubAgent && <DescriptionField></DescriptionField>}
<LargeModelFormField showSpeech2TextModel></LargeModelFormField>
<LargeModelFormField showSpeech2TextModel ownerTenantId={ownerTenantId}></LargeModelFormField>
{findLlmByUuid(llmId)?.model_type?.includes(
LlmModelType.Image2text,
) && (

View File

@@ -9,6 +9,7 @@ import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { z } from 'zod';
import { initialBrowserValues } from '../../constant';
import { useOwnerTenantId } from '../../context';
import { useFormValues } from '../../hooks/use-form-values';
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
import { INextOperatorForm } from '../../interface';
@@ -39,11 +40,13 @@ function BrowserForm({ node }: INextOperatorForm) {
useWatchFormChange(node?.id, form);
const ownerTenantId = useOwnerTenantId();
return (
<Form {...form}>
<FormWrapper>
<RAGFlowFormItem label={t('chat.model')} name="llm_id">
<NextLLMSelect></NextLLMSelect>
<NextLLMSelect ownerTenantId={ownerTenantId}></NextLLMSelect>
</RAGFlowFormItem>
<RAGFlowFormItem label={t('flow.userPrompt')} name="prompts">
<PromptEditor showToolbar={true}></PromptEditor>

View File

@@ -6,6 +6,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
import { memo } from 'react';
import { useForm } from 'react-hook-form';
import { initialCategorizeValues } from '../../constant';
import { useOwnerTenantId } from '../../context';
import { INextOperatorForm } from '../../interface';
import { buildOutputList } from '../../utils/build-output-list';
import { FormWrapper } from '../components/form-wrapper';
@@ -30,11 +31,13 @@ function CategorizeForm({ node }: INextOperatorForm) {
useWatchFormChange(node?.id, form);
const ownerTenantId = useOwnerTenantId();
return (
<Form {...form}>
<FormWrapper>
<QueryVariable></QueryVariable>
<LargeModelFormField></LargeModelFormField>
<LargeModelFormField ownerTenantId={ownerTenantId}></LargeModelFormField>
<MessageHistoryWindowSizeFormField
min={0}
></MessageHistoryWindowSizeFormField>

View File

@@ -18,6 +18,7 @@ import {
import { useBuildNodeOutputOptions } from '../../hooks/use-build-options';
import { useFormValues } from '../../hooks/use-form-values';
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
import { useOwnerTenantId } from '../../context';
import { INextOperatorForm } from '../../interface';
import { buildOutputList } from '../../utils/build-output-list';
import { FormWrapper } from '../components/form-wrapper';
@@ -59,12 +60,13 @@ const ExtractorForm = ({ node }: INextOperatorForm) => {
useWatchFormChange(node?.id, form);
const ownerTenantId = useOwnerTenantId();
const isToc = form.getValues('field_name') === 'toc';
return (
<Form {...form}>
<FormWrapper>
<LargeModelFormField></LargeModelFormField>
<LargeModelFormField ownerTenantId={ownerTenantId}></LargeModelFormField>
<RAGFlowFormItem label={t('flow.fieldName')} name="field_name">
{(field) => (
<SelectWithSearch

View File

@@ -12,6 +12,7 @@ import { isEmpty } from 'lodash';
import { useEffect, useMemo } from 'react';
import { useFormContext, useWatch } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { useOwnerTenantId } from '../../context';
import {
FlattenMediaToTextFormField,
LanguageFormField,
@@ -37,6 +38,7 @@ const markdownImageResponseTypeOptions: SelectWithSearchFlagOptionType[] = [
export function PdfFormFields({ prefix }: CommonProps) {
const { t } = useTranslation();
const form = useFormContext();
const ownerTenantId = useOwnerTenantId();
const parseMethodName = buildFieldNameWithPrefix('parse_method', prefix);
const parseMethod = useWatch({
@@ -112,6 +114,7 @@ export function PdfFormFields({ prefix }: CommonProps) {
label={t('chat.model')}
modelTypes={ModelTypeMap.img2txt_id}
allowClear
ownerTenantId={ownerTenantId}
/>
)}
{languageShown && <LanguageFormField prefix={prefix}></LanguageFormField>}

View File

@@ -12,6 +12,7 @@ import { isEmpty } from 'lodash';
import { useEffect, useMemo } from 'react';
import { useFormContext, useWatch } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { useOwnerTenantId } from '../../context';
import {
FlattenMediaToTextFormField,
ParserMethodFormField,
@@ -32,6 +33,7 @@ const markdownImageResponseTypeOptions: SelectWithSearchFlagOptionType[] = [
export function SpreadsheetFormFields({ prefix }: CommonProps) {
const { t } = useTranslation();
const form = useFormContext();
const ownerTenantId = useOwnerTenantId();
const parseMethodName = buildFieldNameWithPrefix('parse_method', prefix);
@@ -106,6 +108,7 @@ export function SpreadsheetFormFields({ prefix }: CommonProps) {
label={t('chat.model')}
modelTypes={ModelTypeMap.img2txt_id}
allowClear
ownerTenantId={ownerTenantId}
/>
)}
{tcadpOptionsShown && (

View File

@@ -4,6 +4,7 @@ import {
} from '@/components/model-tree-select';
import { useWatch } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { useOwnerTenantId } from '../../context';
import {
FlattenMediaToTextFormField,
RemoveHeaderFooterFormField,
@@ -14,6 +15,7 @@ import { buildFieldNameWithPrefix } from './utils';
export function TextMarkdownFormFields({ prefix }: CommonProps) {
const { t } = useTranslation();
const ownerTenantId = useOwnerTenantId();
const flattenMediaToText = useWatch({
name: buildFieldNameWithPrefix('flatten_media_to_text', prefix),
});
@@ -28,6 +30,7 @@ export function TextMarkdownFormFields({ prefix }: CommonProps) {
label={t('chat.model')}
modelTypes={ModelTypeMap.img2txt_id}
allowClear
ownerTenantId={ownerTenantId}
/>
)}
</>

View File

@@ -3,11 +3,13 @@ import {
ModelTypeMap,
} from '@/components/model-tree-select';
import { useTranslation } from 'react-i18next';
import { useOwnerTenantId } from '../../context';
import { OutputFormatFormFieldProps } from './common-form-fields';
import { buildFieldNameWithPrefix } from './utils';
export function AudioFormFields({ prefix }: OutputFormatFormFieldProps) {
const { t } = useTranslation();
const ownerTenantId = useOwnerTenantId();
return (
<>
@@ -17,6 +19,7 @@ export function AudioFormFields({ prefix }: OutputFormatFormFieldProps) {
label={t('chat.model')}
modelTypes={ModelTypeMap.asr_id}
allowClear
ownerTenantId={ownerTenantId}
/>
</>
);
@@ -24,6 +27,7 @@ export function AudioFormFields({ prefix }: OutputFormatFormFieldProps) {
export function VideoFormFields({ prefix }: OutputFormatFormFieldProps) {
const { t } = useTranslation();
const ownerTenantId = useOwnerTenantId();
return (
<>
@@ -33,6 +37,7 @@ export function VideoFormFields({ prefix }: OutputFormatFormFieldProps) {
label={t('chat.model')}
modelTypes={ModelTypeMap.img2txt_id}
allowClear
ownerTenantId={ownerTenantId}
/>
</>
);

View File

@@ -4,6 +4,7 @@ import {
} from '@/components/model-tree-select';
import { useWatch } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { useOwnerTenantId } from '../../context';
import {
FlattenMediaToTextFormField,
OutputFormatFormFieldProps,
@@ -14,6 +15,7 @@ import { buildFieldNameWithPrefix } from './utils';
export function WordFormFields({ prefix }: OutputFormatFormFieldProps) {
const { t } = useTranslation();
const ownerTenantId = useOwnerTenantId();
const flattenMediaToText = useWatch({
name: buildFieldNameWithPrefix('flatten_media_to_text', prefix),
});
@@ -29,6 +31,7 @@ export function WordFormFields({ prefix }: OutputFormatFormFieldProps) {
label={t('chat.model')}
modelTypes={ModelTypeMap.img2txt_id}
allowClear
ownerTenantId={ownerTenantId}
/>
)}
</>

View File

@@ -33,6 +33,7 @@ import {
import { useTranslation } from 'react-i18next';
import { z } from 'zod';
import { RetrievalFrom, initialRetrievalValues } from '../../constant';
import { useOwnerTenantId } from '../../context';
import { useWatchFormChange } from '../../hooks/use-watch-form-change';
import { INextOperatorForm } from '../../interface';
import { FormWrapper } from '../components/form-wrapper';
@@ -134,6 +135,7 @@ export function EmptyResponseField() {
function RetrievalForm({ node }: INextOperatorForm) {
const { t } = useTranslation();
const ownerTenantId = useOwnerTenantId();
const outputList = useMemo(() => {
return [
@@ -176,7 +178,7 @@ function RetrievalForm({ node }: INextOperatorForm) {
<TopNFormField></TopNFormField>
{hideKnowledgeGraphField || (
<>
<RerankFormFields></RerankFormFields>
<RerankFormFields ownerTenantId={ownerTenantId}></RerankFormFields>
<MetadataFilter canReference></MetadataFilter>
</>
)}

View File

@@ -11,10 +11,12 @@ import {
import { RAGFlowSelect } from '@/components/ui/select';
import { useTranslation } from 'react-i18next';
import { INextOperatorForm } from '../../interface';
import { useOwnerTenantId } from '../../context';
import { GoogleLanguageOptions } from '../../options';
const RewriteQuestionForm = ({ form }: INextOperatorForm) => {
const { t } = useTranslation();
const ownerTenantId = useOwnerTenantId();
return (
<Form {...form}>
@@ -28,6 +30,7 @@ const RewriteQuestionForm = ({ form }: INextOperatorForm) => {
name="llm_id"
label={t('chat.model')}
tooltip={t('chat.modelTip')}
ownerTenantId={ownerTenantId}
/>
<FormField
control={form.control}

View File

@@ -12,6 +12,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
import { t } from 'i18next';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { useOwnerTenantId } from '../../../context';
import { DescriptionField } from '../../components/description-field';
import { FormWrapper } from '../../components/form-wrapper';
import {
@@ -40,6 +41,8 @@ const RetrievalForm = () => {
useWatchFormChange(form);
const ownerTenantId = useOwnerTenantId();
return (
<Form {...form}>
<FormWrapper>
@@ -55,7 +58,7 @@ const RetrievalForm = () => {
<TopNFormField></TopNFormField>
{hideKnowledgeGraphField || (
<>
<RerankFormFields></RerankFormFields>
<RerankFormFields ownerTenantId={ownerTenantId}></RerankFormFields>
<MetadataFilter canReference></MetadataFilter>
</>
)}

View File

@@ -45,6 +45,7 @@ import AgentCanvas from './canvas';
import { DropdownProvider } from './canvas/context';
import { PublishConfirmDialog } from './components/publish-confirm-dialog';
import { Operator } from './constant';
import { OwnerTenantIdContext } from './context';
import { GlobalParamSheet } from './gobal-variable-sheet';
import { useBuildDslData } from './hooks/use-build-dsl';
import { useCancelCurrentDataflow } from './hooks/use-cancel-dataflow';
@@ -357,14 +358,16 @@ export default function Agent() {
</DropdownMenu>
</div>
</PageHeader>
<ReactFlowProvider>
<DropdownProvider>
<AgentCanvas
drawerVisible={chatDrawerVisible}
hideDrawer={hideChatDrawer}
></AgentCanvas>
</DropdownProvider>
</ReactFlowProvider>
<OwnerTenantIdContext.Provider value={agentDetail?.user_id}>
<ReactFlowProvider>
<DropdownProvider>
<AgentCanvas
drawerVisible={chatDrawerVisible}
hideDrawer={hideChatDrawer}
></AgentCanvas>
</DropdownProvider>
</ReactFlowProvider>
</OwnerTenantIdContext.Provider>
{embedVisible && (
<EmbedDialog
visible={embedVisible}

View File

@@ -106,12 +106,14 @@ export const EmbeddingSelect = ({
name,
disabled = false,
testId,
ownerTenantId,
}: {
isEdit: boolean;
field: FieldValues;
name?: string;
disabled?: boolean;
testId?: string;
ownerTenantId?: string;
}) => {
const { t } = useTranslate('knowledgeConfiguration');
const form = useFormContext();
@@ -144,6 +146,7 @@ export const EmbeddingSelect = ({
setLoading(false);
}
}}
ownerTenantId={ownerTenantId}
disabled={disabled && !isEdit}
value={field.value}
placeholder={t('embeddingModelPlaceholder')}
@@ -153,7 +156,11 @@ export const EmbeddingSelect = ({
);
};
export function EmbeddingModelItem({ line = 1, isEdit }: IProps) {
export function EmbeddingModelItem({
line = 1,
isEdit,
ownerTenantId,
}: IProps & { ownerTenantId?: string }) {
const { t } = useTranslate('knowledgeConfiguration');
const form = useFormContext();
const disabled = useHasParsedDocument(isEdit);
@@ -188,6 +195,7 @@ export function EmbeddingModelItem({ line = 1, isEdit }: IProps) {
field={field}
disabled={disabled}
testId="ds-settings-basic-embedding-model-select"
ownerTenantId={ownerTenantId}
></EmbeddingSelect>
</FormControl>
</div>
@@ -533,11 +541,13 @@ export const LLMSelect = ({
isEdit,
field,
disabled = false,
ownerTenantId,
}: {
isEdit: boolean;
field: FieldValues;
name?: string;
disabled?: boolean;
ownerTenantId?: string;
}) => {
const { t } = useTranslate('knowledgeConfiguration');
return (
@@ -549,11 +559,18 @@ export const LLMSelect = ({
disabled={disabled && !isEdit}
value={field.value}
placeholder={t('embeddingModelPlaceholder')}
ownerTenantId={ownerTenantId}
/>
);
};
export function LLMModelItem({ line = 1, isEdit, label, name }: IProps) {
export function LLMModelItem({
line = 1,
isEdit,
label,
name,
ownerTenantId,
}: IProps & { ownerTenantId?: string }) {
const { t } = useTranslate('knowledgeConfiguration');
const form = useFormContext();
// const disabled = useHasParsedDocument(isEdit);
@@ -586,6 +603,7 @@ export function LLMModelItem({ line = 1, isEdit, label, name }: IProps) {
isEdit={!!isEdit}
field={field}
disabled={false}
ownerTenantId={ownerTenantId}
></LLMSelect>
</FormControl>
</div>

View File

@@ -14,6 +14,7 @@ import { LanguageTranslationMap } from '@/constants/common';
import { useMemo } from 'react';
import { useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { useKnowledgeBaseContext } from '../contexts/knowledge-base-context';
import { TagItems } from './components/tag-item';
import { EmbeddingModelItem } from './configuration/common-item';
import { PermissionFormField } from './permission-form-field';
@@ -124,7 +125,10 @@ export function GeneralForm() {
}}
/>
<PermissionFormField></PermissionFormField>
<EmbeddingModelItem isEdit={true}></EmbeddingModelItem>
<EmbeddingModelItem
isEdit={true}
ownerTenantId={useKnowledgeBaseContext().knowledgeBase?.tenant_id}
></EmbeddingModelItem>
<PageRankFormField></PageRankFormField>
<TagItems></TagItems>

View File

@@ -40,6 +40,7 @@ import { Send } from 'lucide-react';
import { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router';
import { useKnowledgeBaseContext } from '../contexts/knowledge-base-context';
type TestingFormProps = Pick<
ReturnType<typeof useTestRetrieval>,
@@ -103,7 +104,9 @@ export default function TestingForm({
<SimilaritySliderFormField
isTooltipShown={true}
></SimilaritySliderFormField>
<RerankFormFields></RerankFormFields>
<RerankFormFields
ownerTenantId={useKnowledgeBaseContext().knowledgeBase?.tenant_id}
></RerankFormFields>
<UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField>
<CrossLanguageFormField
name={'cross_languages'}

View File

@@ -23,6 +23,7 @@ import {
defaultMemoryModelForm,
memoryModelFormSchema,
} from './memory-model-form';
import { MemorySettingProvider } from './memory-setting-context';
// type MemoryMessageForm = z.infer<typeof MemoryMessageSchema>;
export default function MemoryMessage() {
@@ -74,8 +75,9 @@ export default function MemoryMessage() {
description={t('knowledgeConfiguration.titleDescription')}
></TopTitle>
<div className="flex gap-14 flex-1 min-h-0">
<Form {...form}>
<form onSubmit={form.handleSubmit(() => {})} className="space-y-6 ">
<MemorySettingProvider data={data}>
<Form {...form}>
<form onSubmit={form.handleSubmit(() => {})} className="space-y-6 ">
<div className="w-[768px] h-[calc(100vh-300px)] pr-1 overflow-y-auto scrollbar-auto pb-4">
<MainContainer className="text-text-secondary !space-y-10">
<div className="text-base font-medium text-text-primary">
@@ -106,7 +108,8 @@ export default function MemoryMessage() {
></DynamicForm.SavingButton>
</div>
</form>
</Form>
</Form>
</MemorySettingProvider>
</div>
</section>
);

View File

@@ -6,6 +6,7 @@ import { TFunction } from 'i18next';
import { useTranslation } from 'react-i18next';
import { z } from 'zod';
import { useFetchMemoryMessageList } from '../memory-message/hook';
import { useMemorySettingContext } from './memory-setting-context';
export const memoryModelFormSchema = (t: TFunction) => ({
embd_id: z.string(),
@@ -30,6 +31,8 @@ export const defaultMemoryModelForm = {
export const MemoryModelForm = () => {
const { t } = useTranslation();
const { data } = useFetchMemoryMessageList();
const { data: configData } = useMemorySettingContext();
const ownerTenantId = configData?.tenant_id;
return (
<>
<RenderField
@@ -46,6 +49,7 @@ export const MemoryModelForm = () => {
field={field}
isEdit={false}
disabled={data?.messages?.total_count > 0}
ownerTenantId={ownerTenantId}
/>
),
@@ -65,6 +69,7 @@ export const MemoryModelForm = () => {
value={field.value}
onChange={field.onChange}
placeholder={t('memories.selectModel')}
ownerTenantId={ownerTenantId}
/>
),
tooltip: t('memories.llmTooltip'),

View File

@@ -0,0 +1,32 @@
import { IMemory } from '@/pages/memories/interface';
import React, { createContext, ReactNode, useContext } from 'react';
interface MemorySettingContextType {
data: IMemory;
}
const MemorySettingContext = createContext<
MemorySettingContextType | undefined
>(undefined);
export const MemorySettingProvider: React.FC<{
children: ReactNode;
data: IMemory;
}> = ({ children, data }) => {
return (
<MemorySettingContext.Provider value={{ data }}>
{children}
</MemorySettingContext.Provider>
);
};
// eslint-disable-next-line react-refresh/only-export-components
export const useMemorySettingContext = (): MemorySettingContextType => {
const context = useContext(MemorySettingContext);
if (context === undefined) {
throw new Error(
'useMemorySettingContext must be used within a MemorySettingProvider',
);
}
return context;
};