diff --git a/web/src/components/large-model-form-field.tsx b/web/src/components/large-model-form-field.tsx index e1fef3f9d0..e50a6b7928 100644 --- a/web/src/components/large-model-form-field.tsx +++ b/web/src/components/large-model-form-field.tsx @@ -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} /> @@ -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} /> diff --git a/web/src/components/llm-select/next.tsx b/web/src/components/llm-select/next.tsx index 9662048e2f..0c18dcccf0 100644 --- a/web/src/components/llm-select/next.tsx +++ b/web/src/components/llm-select/next.tsx @@ -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< diff --git a/web/src/components/llm-setting-items/llm-form-field.tsx b/web/src/components/llm-setting-items/llm-form-field.tsx index c33117fc4a..9ffef8e69a 100644 --- a/web/src/components/llm-setting-items/llm-form-field.tsx +++ b/web/src/components/llm-setting-items/llm-form-field.tsx @@ -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) { ); diff --git a/web/src/components/llm-setting-items/next.tsx b/web/src/components/llm-setting-items/next.tsx index 8c93c30319..60dd0d7c48 100644 --- a/web/src/components/llm-setting-items/next.tsx +++ b/web/src/components/llm-setting-items/next.tsx @@ -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} >
diff --git a/web/src/components/model-tree-select.tsx b/web/src/components/model-tree-select.tsx index 3341832d97..b8f6c1c5aa 100644 --- a/web/src/components/model-tree-select.tsx +++ b/web/src/components/model-tree-select.tsx @@ -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((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(); + 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 ; + if (!node?.data) return null; + return ( + + ); }, [], ); @@ -138,7 +179,7 @@ export function ModelTreeSelect({ return ( @@ -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 ( <> - + {rerankId && ( { return { data, loading }; }; -export const useFetchAllAddedModels = (modelType?: string) => { +export const useFetchAllAddedModels = ( + modelType?: string, + ownerTenantId?: string, +) => { const { data, isFetching: loading } = useQuery({ - 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 ?? []; diff --git a/web/src/interfaces/database/llm.ts b/web/src/interfaces/database/llm.ts index 35c347865c..9f29936c72 100644 --- a/web/src/interfaces/database/llm.ts +++ b/web/src/interfaces/database/llm.ts @@ -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 { diff --git a/web/src/interfaces/request/llm.ts b/web/src/interfaces/request/llm.ts index b6dc7310ae..f5ba462466 100644 --- a/web/src/interfaces/request/llm.ts +++ b/web/src/interfaces/request/llm.ts @@ -71,6 +71,7 @@ export interface IEditInstanceModelRequestBody { export interface IListAllModelsRequestParams { type?: string; + owner_tenant_id?: string; } export interface IUpdateModelStatusRequestBody { diff --git a/web/src/pages/agent/context.ts b/web/src/pages/agent/context.ts index bba54e3272..cbfa1999ec 100644 --- a/web/src/pages/agent/context.ts +++ b/web/src/pages/agent/context.ts @@ -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( undefined, ); +export const OwnerTenantIdContext = createContext( + undefined, +); + +// eslint-disable-next-line react-refresh/only-export-components +export const useOwnerTenantId = () => useContext(OwnerTenantIdContext); + type AgentInstanceContextType = Pick< ReturnType, 'addCanvasNode' diff --git a/web/src/pages/agent/form/agent-form/index.tsx b/web/src/pages/agent/form/agent-form/index.tsx index 169df8e2eb..353d6e37ad 100644 --- a/web/src/pages/agent/form/agent-form/index.tsx +++ b/web/src/pages/agent/form/agent-form/index.tsx @@ -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; function AgentForm({ node }: INextOperatorForm) { const { t } = useTranslation(); + const ownerTenantId = useOwnerTenantId(); const { edges, deleteEdgesBySourceAndSourceHandle } = useGraphStore( (state) => state, ); @@ -158,7 +160,7 @@ function AgentForm({ node }: INextOperatorForm) {
{isSubAgent && } - + {findLlmByUuid(llmId)?.model_type?.includes( LlmModelType.Image2text, ) && ( diff --git a/web/src/pages/agent/form/browser-use-form/index.tsx b/web/src/pages/agent/form/browser-use-form/index.tsx index a6e7b7ca6f..56d7f242b9 100644 --- a/web/src/pages/agent/form/browser-use-form/index.tsx +++ b/web/src/pages/agent/form/browser-use-form/index.tsx @@ -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 ( - + diff --git a/web/src/pages/agent/form/categorize-form/index.tsx b/web/src/pages/agent/form/categorize-form/index.tsx index de69830067..a75a58bf75 100644 --- a/web/src/pages/agent/form/categorize-form/index.tsx +++ b/web/src/pages/agent/form/categorize-form/index.tsx @@ -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 ( - + diff --git a/web/src/pages/agent/form/extractor-form/index.tsx b/web/src/pages/agent/form/extractor-form/index.tsx index 33ab5eff2e..4a7a60011d 100644 --- a/web/src/pages/agent/form/extractor-form/index.tsx +++ b/web/src/pages/agent/form/extractor-form/index.tsx @@ -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 ( - + {(field) => ( )} {languageShown && } diff --git a/web/src/pages/agent/form/parser-form/spreadsheet-form-fields.tsx b/web/src/pages/agent/form/parser-form/spreadsheet-form-fields.tsx index f257a25f51..45a5f68bbc 100644 --- a/web/src/pages/agent/form/parser-form/spreadsheet-form-fields.tsx +++ b/web/src/pages/agent/form/parser-form/spreadsheet-form-fields.tsx @@ -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 && ( diff --git a/web/src/pages/agent/form/parser-form/text-html-form-fields.tsx b/web/src/pages/agent/form/parser-form/text-html-form-fields.tsx index 76e477c74c..33b480da4b 100644 --- a/web/src/pages/agent/form/parser-form/text-html-form-fields.tsx +++ b/web/src/pages/agent/form/parser-form/text-html-form-fields.tsx @@ -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} /> )} diff --git a/web/src/pages/agent/form/parser-form/video-form-fields.tsx b/web/src/pages/agent/form/parser-form/video-form-fields.tsx index b24e703e7c..ee536c45be 100644 --- a/web/src/pages/agent/form/parser-form/video-form-fields.tsx +++ b/web/src/pages/agent/form/parser-form/video-form-fields.tsx @@ -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} /> ); diff --git a/web/src/pages/agent/form/parser-form/word-form-fields.tsx b/web/src/pages/agent/form/parser-form/word-form-fields.tsx index 41de221691..77ce5314fa 100644 --- a/web/src/pages/agent/form/parser-form/word-form-fields.tsx +++ b/web/src/pages/agent/form/parser-form/word-form-fields.tsx @@ -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} /> )} diff --git a/web/src/pages/agent/form/retrieval-form/next.tsx b/web/src/pages/agent/form/retrieval-form/next.tsx index 9adf93c5b3..4ecbef0740 100644 --- a/web/src/pages/agent/form/retrieval-form/next.tsx +++ b/web/src/pages/agent/form/retrieval-form/next.tsx @@ -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) { {hideKnowledgeGraphField || ( <> - + )} diff --git a/web/src/pages/agent/form/rewrite-question-form/index.tsx b/web/src/pages/agent/form/rewrite-question-form/index.tsx index bf55c9310b..336d60b4d8 100644 --- a/web/src/pages/agent/form/rewrite-question-form/index.tsx +++ b/web/src/pages/agent/form/rewrite-question-form/index.tsx @@ -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 ( @@ -28,6 +30,7 @@ const RewriteQuestionForm = ({ form }: INextOperatorForm) => { name="llm_id" label={t('chat.model')} tooltip={t('chat.modelTip')} + ownerTenantId={ownerTenantId} /> { useWatchFormChange(form); + const ownerTenantId = useOwnerTenantId(); + return ( @@ -55,7 +58,7 @@ const RetrievalForm = () => { {hideKnowledgeGraphField || ( <> - + )} diff --git a/web/src/pages/agent/index.tsx b/web/src/pages/agent/index.tsx index 30ef2f2c80..8d35fbe7f6 100644 --- a/web/src/pages/agent/index.tsx +++ b/web/src/pages/agent/index.tsx @@ -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() { - - - - - + + + + + + + {embedVisible && ( { 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} > @@ -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} > diff --git a/web/src/pages/dataset/dataset-setting/general-form.tsx b/web/src/pages/dataset/dataset-setting/general-form.tsx index 1f214ba2f4..b2ecc02d3c 100644 --- a/web/src/pages/dataset/dataset-setting/general-form.tsx +++ b/web/src/pages/dataset/dataset-setting/general-form.tsx @@ -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() { }} /> - + diff --git a/web/src/pages/dataset/testing/testing-form.tsx b/web/src/pages/dataset/testing/testing-form.tsx index 7437500b20..85e69ae8f0 100644 --- a/web/src/pages/dataset/testing/testing-form.tsx +++ b/web/src/pages/dataset/testing/testing-form.tsx @@ -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, @@ -103,7 +104,9 @@ export default function TestingForm({ - + ; export default function MemoryMessage() { @@ -74,8 +75,9 @@ export default function MemoryMessage() { description={t('knowledgeConfiguration.titleDescription')} >
- - {})} className="space-y-6 "> + + + {})} className="space-y-6 ">
@@ -106,7 +108,8 @@ export default function MemoryMessage() { >
- + +
); diff --git a/web/src/pages/memory/memory-setting/memory-model-form.tsx b/web/src/pages/memory/memory-setting/memory-model-form.tsx index 455c4f8b34..8d866a23e2 100644 --- a/web/src/pages/memory/memory-setting/memory-model-form.tsx +++ b/web/src/pages/memory/memory-setting/memory-model-form.tsx @@ -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 ( <> { 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'), diff --git a/web/src/pages/memory/memory-setting/memory-setting-context.tsx b/web/src/pages/memory/memory-setting/memory-setting-context.tsx new file mode 100644 index 0000000000..4887ee8823 --- /dev/null +++ b/web/src/pages/memory/memory-setting/memory-setting-context.tsx @@ -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 ( + + {children} + + ); +}; + +// 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; +};