| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 | import {  useCallback,  useEffect,  useRef,  useState,} from 'react'import produce from 'immer'import { isEqual } from 'lodash-es'import type { ValueSelector, Var } from '../../types'import { BlockEnum, VarType } from '../../types'import {  useIsChatMode, useNodesReadOnly,  useWorkflow,} from '../../hooks'import type { KnowledgeRetrievalNodeType, MultipleRetrievalConfig } from './types'import {  getMultipleRetrievalConfig,  getSelectedDatasetsMode,} from './utils'import { RETRIEVE_TYPE } from '@/types/app'import { DATASET_DEFAULT } from '@/config'import type { DataSet } from '@/models/datasets'import { fetchDatasets } from '@/service/datasets'import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'import useOneStepRun from '@/app/components/workflow/nodes/_base/hooks/use-one-step-run'import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => {  const { nodesReadOnly: readOnly } = useNodesReadOnly()  const isChatMode = useIsChatMode()  const { getBeforeNodesInSameBranch } = useWorkflow()  const startNode = getBeforeNodesInSameBranch(id).find(node => node.data.type === BlockEnum.Start)  const startNodeId = startNode?.id  const { inputs, setInputs: doSetInputs } = useNodeCrud<KnowledgeRetrievalNodeType>(id, payload)  const setInputs = useCallback((s: KnowledgeRetrievalNodeType) => {    const newInputs = produce(s, (draft) => {      if (s.retrieval_mode === RETRIEVE_TYPE.multiWay)        delete draft.single_retrieval_config      else        delete draft.multiple_retrieval_config    })    // not work in pass to draft...    doSetInputs(newInputs)  }, [doSetInputs])  const inputRef = useRef(inputs)  useEffect(() => {    inputRef.current = inputs  }, [inputs])  const handleQueryVarChange = useCallback((newVar: ValueSelector | string) => {    const newInputs = produce(inputs, (draft) => {      draft.query_variable_selector = newVar as ValueSelector    })    setInputs(newInputs)  }, [inputs, setInputs])  const {    currentProvider,    currentModel,  } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.textGeneration)  const {    defaultModel: rerankDefaultModel,  } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank)  const handleModelChanged = useCallback((model: { provider: string; modelId: string; mode?: string }) => {    const newInputs = produce(inputRef.current, (draft) => {      if (!draft.single_retrieval_config) {        draft.single_retrieval_config = {          model: {            provider: '',            name: '',            mode: '',            completion_params: {},          },        }      }      const draftModel = draft.single_retrieval_config?.model      draftModel.provider = model.provider      draftModel.name = model.modelId      draftModel.mode = model.mode!    })    setInputs(newInputs)  }, [setInputs])  const handleCompletionParamsChange = useCallback((newParams: Record<string, any>) => {    // inputRef.current.single_retrieval_config?.model is old  when change the provider...    if (isEqual(newParams, inputRef.current.single_retrieval_config?.model.completion_params))      return    const newInputs = produce(inputRef.current, (draft) => {      if (!draft.single_retrieval_config) {        draft.single_retrieval_config = {          model: {            provider: '',            name: '',            mode: '',            completion_params: {},          },        }      }      draft.single_retrieval_config.model.completion_params = newParams    })    setInputs(newInputs)  }, [setInputs])  // set defaults models  useEffect(() => {    const inputs = inputRef.current    if (inputs.retrieval_mode === RETRIEVE_TYPE.multiWay && inputs.multiple_retrieval_config?.reranking_model?.provider)      return    if (inputs.retrieval_mode === RETRIEVE_TYPE.oneWay && inputs.single_retrieval_config?.model?.provider)      return    const newInput = produce(inputs, (draft) => {      if (currentProvider?.provider && currentModel?.model) {        const hasSetModel = draft.single_retrieval_config?.model?.provider        if (!hasSetModel) {          draft.single_retrieval_config = {            model: {              provider: currentProvider?.provider,              name: currentModel?.model,              mode: currentModel?.model_properties?.mode as string,              completion_params: {},            },          }        }      }      const multipleRetrievalConfig = draft.multiple_retrieval_config      draft.multiple_retrieval_config = {        top_k: multipleRetrievalConfig?.top_k || DATASET_DEFAULT.top_k,        score_threshold: multipleRetrievalConfig?.score_threshold,        reranking_model: multipleRetrievalConfig?.reranking_model,      }    })    setInputs(newInput)  // eslint-disable-next-line react-hooks/exhaustive-deps  }, [currentProvider?.provider, currentModel, rerankDefaultModel])  const [selectedDatasets, setSelectedDatasets] = useState<DataSet[]>([])  const [rerankModelOpen, setRerankModelOpen] = useState(false)  const handleRetrievalModeChange = useCallback((newMode: RETRIEVE_TYPE) => {    const newInputs = produce(inputs, (draft) => {      draft.retrieval_mode = newMode      if (newMode === RETRIEVE_TYPE.multiWay) {        const multipleRetrievalConfig = draft.multiple_retrieval_config        draft.multiple_retrieval_config = getMultipleRetrievalConfig(multipleRetrievalConfig!, selectedDatasets)      }      else {        const hasSetModel = draft.single_retrieval_config?.model?.provider        if (!hasSetModel) {          draft.single_retrieval_config = {            model: {              provider: currentProvider?.provider || '',              name: currentModel?.model || '',              mode: currentModel?.model_properties?.mode as string,              completion_params: {},            },          }        }      }    })    setInputs(newInputs)  }, [currentModel?.model, currentModel?.model_properties?.mode, currentProvider?.provider, inputs, setInputs, selectedDatasets])  const handleMultipleRetrievalConfigChange = useCallback((newConfig: MultipleRetrievalConfig) => {    const newInputs = produce(inputs, (draft) => {      draft.multiple_retrieval_config = getMultipleRetrievalConfig(newConfig!, selectedDatasets)    })    setInputs(newInputs)  }, [inputs, setInputs, selectedDatasets])  // datasets  useEffect(() => {    (async () => {      const inputs = inputRef.current      const datasetIds = inputs.dataset_ids      if (datasetIds?.length > 0) {        const { data: dataSetsWithDetail } = await fetchDatasets({ url: '/datasets', params: { page: 1, ids: datasetIds } })        setSelectedDatasets(dataSetsWithDetail)      }      const newInputs = produce(inputs, (draft) => {        draft.dataset_ids = datasetIds      })      setInputs(newInputs)    })()  // eslint-disable-next-line react-hooks/exhaustive-deps  }, [])  useEffect(() => {    let query_variable_selector: ValueSelector = inputs.query_variable_selector    if (isChatMode && inputs.query_variable_selector.length === 0 && startNodeId)      query_variable_selector = [startNodeId, 'sys.query']    setInputs({      ...inputs,      query_variable_selector,    })  // eslint-disable-next-line react-hooks/exhaustive-deps  }, [])  const handleOnDatasetsChange = useCallback((newDatasets: DataSet[]) => {    const {      allEconomic,      mixtureHighQualityAndEconomic,      inconsistentEmbeddingModel,    } = getSelectedDatasetsMode(newDatasets)    const newInputs = produce(inputs, (draft) => {      draft.dataset_ids = newDatasets.map(d => d.id)      if (payload.retrieval_mode === RETRIEVE_TYPE.multiWay && newDatasets.length > 0) {        const multipleRetrievalConfig = draft.multiple_retrieval_config        draft.multiple_retrieval_config = getMultipleRetrievalConfig(multipleRetrievalConfig!, newDatasets)      }    })    setInputs(newInputs)    setSelectedDatasets(newDatasets)    if (allEconomic || mixtureHighQualityAndEconomic || inconsistentEmbeddingModel)      setRerankModelOpen(true)  }, [inputs, setInputs, payload.retrieval_mode])  const filterVar = useCallback((varPayload: Var) => {    return varPayload.type === VarType.string  }, [])  // single run  const {    isShowSingleRun,    hideSingleRun,    runningStatus,    handleRun,    handleStop,    runInputData,    setRunInputData,    runResult,  } = useOneStepRun<KnowledgeRetrievalNodeType>({    id,    data: inputs,    defaultRunInputData: {      query: '',    },  })  const query = runInputData.query  const setQuery = useCallback((newQuery: string) => {    setRunInputData({      ...runInputData,      query: newQuery,    })  }, [runInputData, setRunInputData])  return {    readOnly,    inputs,    handleQueryVarChange,    filterVar,    handleRetrievalModeChange,    handleMultipleRetrievalConfigChange,    handleModelChanged,    handleCompletionParamsChange,    selectedDatasets: selectedDatasets.filter(d => d.name),    handleOnDatasetsChange,    isShowSingleRun,    hideSingleRun,    runningStatus,    handleRun,    handleStop,    query,    setQuery,    runResult,    rerankModelOpen,    setRerankModelOpen,  }}export default useConfig
 |