Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

panel.tsx 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import type { FC } from 'react'
  2. import {
  3. memo,
  4. useCallback,
  5. useMemo,
  6. } from 'react'
  7. import { intersectionBy } from 'lodash-es'
  8. import { useTranslation } from 'react-i18next'
  9. import VarReferencePicker from '../_base/components/variable/var-reference-picker'
  10. import useConfig from './use-config'
  11. import RetrievalConfig from './components/retrieval-config'
  12. import AddKnowledge from './components/add-dataset'
  13. import DatasetList from './components/dataset-list'
  14. import MetadataFilter from './components/metadata/metadata-filter'
  15. import type { KnowledgeRetrievalNodeType } from './types'
  16. import Field from '@/app/components/workflow/nodes/_base/components/field'
  17. import Split from '@/app/components/workflow/nodes/_base/components/split'
  18. import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars'
  19. import { InputVarType, type NodePanelProps } from '@/app/components/workflow/types'
  20. import BeforeRunForm from '@/app/components/workflow/nodes/_base/components/before-run-form'
  21. import ResultPanel from '@/app/components/workflow/run/result-panel'
  22. const i18nPrefix = 'workflow.nodes.knowledgeRetrieval'
  23. const Panel: FC<NodePanelProps<KnowledgeRetrievalNodeType>> = ({
  24. id,
  25. data,
  26. }) => {
  27. const { t } = useTranslation()
  28. const {
  29. readOnly,
  30. inputs,
  31. handleQueryVarChange,
  32. filterVar,
  33. handleModelChanged,
  34. handleCompletionParamsChange,
  35. handleRetrievalModeChange,
  36. handleMultipleRetrievalConfigChange,
  37. selectedDatasets,
  38. selectedDatasetsLoaded,
  39. handleOnDatasetsChange,
  40. isShowSingleRun,
  41. hideSingleRun,
  42. runningStatus,
  43. handleRun,
  44. handleStop,
  45. query,
  46. setQuery,
  47. runResult,
  48. rerankModelOpen,
  49. setRerankModelOpen,
  50. handleAddCondition,
  51. handleMetadataFilterModeChange,
  52. handleRemoveCondition,
  53. handleToggleConditionLogicalOperator,
  54. handleUpdateCondition,
  55. handleMetadataModelChange,
  56. handleMetadataCompletionParamsChange,
  57. availableStringVars,
  58. availableStringNodesWithParent,
  59. availableNumberVars,
  60. availableNumberNodesWithParent,
  61. } = useConfig(id, data)
  62. const handleOpenFromPropsChange = useCallback((openFromProps: boolean) => {
  63. setRerankModelOpen(openFromProps)
  64. }, [setRerankModelOpen])
  65. const metadataList = useMemo(() => {
  66. return intersectionBy(...selectedDatasets.filter((dataset) => {
  67. return !!dataset.doc_metadata
  68. }).map((dataset) => {
  69. return dataset.doc_metadata!
  70. }), 'name')
  71. }, [selectedDatasets])
  72. return (
  73. <div className='pt-2'>
  74. <div className='space-y-4 px-4 pb-2'>
  75. {/* {JSON.stringify(inputs, null, 2)} */}
  76. <Field
  77. title={t(`${i18nPrefix}.queryVariable`)}
  78. required
  79. >
  80. <VarReferencePicker
  81. nodeId={id}
  82. readonly={readOnly}
  83. isShowNodeName
  84. value={inputs.query_variable_selector}
  85. onChange={handleQueryVarChange}
  86. filterVar={filterVar}
  87. />
  88. </Field>
  89. <Field
  90. title={t(`${i18nPrefix}.knowledge`)}
  91. required
  92. operations={
  93. <div className='flex items-center space-x-1'>
  94. <RetrievalConfig
  95. payload={{
  96. retrieval_mode: inputs.retrieval_mode,
  97. multiple_retrieval_config: inputs.multiple_retrieval_config,
  98. single_retrieval_config: inputs.single_retrieval_config,
  99. }}
  100. onRetrievalModeChange={handleRetrievalModeChange}
  101. onMultipleRetrievalConfigChange={handleMultipleRetrievalConfigChange}
  102. singleRetrievalModelConfig={inputs.single_retrieval_config?.model}
  103. onSingleRetrievalModelChange={handleModelChanged as any}
  104. onSingleRetrievalModelParamsChange={handleCompletionParamsChange}
  105. readonly={readOnly || !selectedDatasets.length}
  106. openFromProps={rerankModelOpen}
  107. onOpenFromPropsChange={handleOpenFromPropsChange}
  108. selectedDatasets={selectedDatasets}
  109. />
  110. {!readOnly && (<div className='h-3 w-px bg-divider-regular'></div>)}
  111. {!readOnly && (
  112. <AddKnowledge
  113. selectedIds={inputs.dataset_ids}
  114. onChange={handleOnDatasetsChange}
  115. />
  116. )}
  117. </div>
  118. }
  119. >
  120. <DatasetList
  121. list={selectedDatasets}
  122. onChange={handleOnDatasetsChange}
  123. readonly={readOnly}
  124. />
  125. </Field>
  126. </div>
  127. <div className='mb-2 py-2'>
  128. <MetadataFilter
  129. metadataList={metadataList}
  130. selectedDatasetsLoaded={selectedDatasetsLoaded}
  131. metadataFilterMode={inputs.metadata_filtering_mode}
  132. metadataFilteringConditions={inputs.metadata_filtering_conditions}
  133. handleAddCondition={handleAddCondition}
  134. handleMetadataFilterModeChange={handleMetadataFilterModeChange}
  135. handleRemoveCondition={handleRemoveCondition}
  136. handleToggleConditionLogicalOperator={handleToggleConditionLogicalOperator}
  137. handleUpdateCondition={handleUpdateCondition}
  138. metadataModelConfig={inputs.metadata_model_config}
  139. handleMetadataModelChange={handleMetadataModelChange}
  140. handleMetadataCompletionParamsChange={handleMetadataCompletionParamsChange}
  141. availableStringVars={availableStringVars}
  142. availableStringNodesWithParent={availableStringNodesWithParent}
  143. availableNumberVars={availableNumberVars}
  144. availableNumberNodesWithParent={availableNumberNodesWithParent}
  145. />
  146. </div>
  147. <Split />
  148. <div>
  149. <OutputVars>
  150. <>
  151. <VarItem
  152. name='result'
  153. type='Array[Object]'
  154. description={t(`${i18nPrefix}.outputVars.output`)}
  155. subItems={[
  156. {
  157. name: 'content',
  158. type: 'string',
  159. description: t(`${i18nPrefix}.outputVars.content`),
  160. },
  161. // url, title, link like bing search reference result: link, link page title, link page icon
  162. {
  163. name: 'title',
  164. type: 'string',
  165. description: t(`${i18nPrefix}.outputVars.title`),
  166. },
  167. {
  168. name: 'url',
  169. type: 'string',
  170. description: t(`${i18nPrefix}.outputVars.url`),
  171. },
  172. {
  173. name: 'icon',
  174. type: 'string',
  175. description: t(`${i18nPrefix}.outputVars.icon`),
  176. },
  177. {
  178. name: 'metadata',
  179. type: 'object',
  180. description: t(`${i18nPrefix}.outputVars.metadata`),
  181. },
  182. ]}
  183. />
  184. </>
  185. </OutputVars>
  186. {isShowSingleRun && (
  187. <BeforeRunForm
  188. nodeName={inputs.title}
  189. onHide={hideSingleRun}
  190. forms={[
  191. {
  192. inputs: [{
  193. label: t(`${i18nPrefix}.queryVariable`)!,
  194. variable: 'query',
  195. type: InputVarType.paragraph,
  196. required: true,
  197. }],
  198. values: { query },
  199. onChange: keyValue => setQuery(keyValue.query),
  200. },
  201. ]}
  202. runningStatus={runningStatus}
  203. onRun={handleRun}
  204. onStop={handleStop}
  205. result={<ResultPanel {...runResult} showSteps={false} />}
  206. />
  207. )}
  208. </div>
  209. </div>
  210. )
  211. }
  212. export default memo(Panel)