mirror of https://github.com/langgenius/dify.git
Merge branch 'main' into feat/hitl-frontend
This commit is contained in:
commit
bf161d01a8
|
|
@ -22,7 +22,7 @@ from core.plugin.impl.plugin import PluginInstaller
|
|||
from core.rag.datasource.vdb.vector_factory import Vector
|
||||
from core.rag.datasource.vdb.vector_type import VectorType
|
||||
from core.rag.index_processor.constant.built_in_field import BuiltInField
|
||||
from core.rag.models.document import Document
|
||||
from core.rag.models.document import ChildDocument, Document
|
||||
from core.tools.utils.system_oauth_encryption import encrypt_system_oauth_params
|
||||
from events.app_event import app_was_created
|
||||
from extensions.ext_database import db
|
||||
|
|
@ -418,6 +418,22 @@ def migrate_knowledge_vector_database():
|
|||
"dataset_id": segment.dataset_id,
|
||||
},
|
||||
)
|
||||
if dataset_document.doc_form == "hierarchical_model":
|
||||
child_chunks = segment.get_child_chunks()
|
||||
if child_chunks:
|
||||
child_documents = []
|
||||
for child_chunk in child_chunks:
|
||||
child_document = ChildDocument(
|
||||
page_content=child_chunk.content,
|
||||
metadata={
|
||||
"doc_id": child_chunk.index_node_id,
|
||||
"doc_hash": child_chunk.index_node_hash,
|
||||
"document_id": segment.document_id,
|
||||
"dataset_id": segment.dataset_id,
|
||||
},
|
||||
)
|
||||
child_documents.append(child_document)
|
||||
document.children = child_documents
|
||||
|
||||
documents.append(document)
|
||||
segments_count = segments_count + 1
|
||||
|
|
@ -431,7 +447,13 @@ def migrate_knowledge_vector_database():
|
|||
fg="green",
|
||||
)
|
||||
)
|
||||
all_child_documents = []
|
||||
for doc in documents:
|
||||
if doc.children:
|
||||
all_child_documents.extend(doc.children)
|
||||
vector.create(documents)
|
||||
if all_child_documents:
|
||||
vector.create(all_child_documents)
|
||||
click.echo(click.style(f"Created vector index for dataset {dataset.id}.", fg="green"))
|
||||
except Exception as e:
|
||||
click.echo(click.style(f"Failed to created vector index for dataset {dataset.id}.", fg="red"))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 7.33337V2.66671H4.00002V13.3334H8.00002C8.36821 13.3334 8.66669 13.6319 8.66669 14C8.66669 14.3682 8.36821 14.6667 8.00002 14.6667H3.33335C2.96516 14.6667 2.66669 14.3682 2.66669 14V2.00004C2.66669 1.63185 2.96516 1.33337 3.33335 1.33337H12.6667C13.0349 1.33337 13.3334 1.63185 13.3334 2.00004V7.33337C13.3334 7.70156 13.0349 8.00004 12.6667 8.00004C12.2985 8.00004 12 7.70156 12 7.33337Z" fill="#354052"/>
|
||||
<path d="M10 4.00004C10.3682 4.00004 10.6667 4.29852 10.6667 4.66671C10.6667 5.0349 10.3682 5.33337 10 5.33337H6.00002C5.63183 5.33337 5.33335 5.0349 5.33335 4.66671C5.33335 4.29852 5.63183 4.00004 6.00002 4.00004H10Z" fill="#354052"/>
|
||||
<path d="M8.00002 6.66671C8.36821 6.66671 8.66669 6.96518 8.66669 7.33337C8.66669 7.70156 8.36821 8.00004 8.00002 8.00004H6.00002C5.63183 8.00004 5.33335 7.70156 5.33335 7.33337C5.33335 6.96518 5.63183 6.66671 6.00002 6.66671H8.00002Z" fill="#354052"/>
|
||||
<path d="M12.827 10.7902L12.3624 9.58224C12.3048 9.43231 12.1607 9.33337 12 9.33337C11.8394 9.33337 11.6953 9.43231 11.6376 9.58224L11.173 10.7902C11.1054 10.9662 10.9662 11.1054 10.7902 11.173L9.58222 11.6376C9.43229 11.6953 9.33335 11.8394 9.33335 12C9.33335 12.1607 9.43229 12.3048 9.58222 12.3624L10.7902 12.827C10.9662 12.8947 11.1054 13.0338 11.173 13.2099L11.6376 14.4178C11.6953 14.5678 11.8394 14.6667 12 14.6667C12.1607 14.6667 12.3048 14.5678 12.3624 14.4178L12.827 13.2099C12.8947 13.0338 13.0338 12.8947 13.2099 12.827L14.4178 12.3624C14.5678 12.3048 14.6667 12.1607 14.6667 12C14.6667 11.8394 14.5678 11.6953 14.4178 11.6376L13.2099 11.173C13.0338 11.1054 12.8947 10.9662 12.827 10.7902Z" fill="#354052"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"icon": {
|
||||
"type": "element",
|
||||
"isRootNode": true,
|
||||
"name": "svg",
|
||||
"attributes": {
|
||||
"width": "16",
|
||||
"height": "16",
|
||||
"viewBox": "0 0 16 16",
|
||||
"fill": "none",
|
||||
"xmlns": "http://www.w3.org/2000/svg"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M12 7.33337V2.66671H4.00002V13.3334H8.00002C8.36821 13.3334 8.66669 13.6319 8.66669 14C8.66669 14.3682 8.36821 14.6667 8.00002 14.6667H3.33335C2.96516 14.6667 2.66669 14.3682 2.66669 14V2.00004C2.66669 1.63185 2.96516 1.33337 3.33335 1.33337H12.6667C13.0349 1.33337 13.3334 1.63185 13.3334 2.00004V7.33337C13.3334 7.70156 13.0349 8.00004 12.6667 8.00004C12.2985 8.00004 12 7.70156 12 7.33337Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M10 4.00004C10.3682 4.00004 10.6667 4.29852 10.6667 4.66671C10.6667 5.0349 10.3682 5.33337 10 5.33337H6.00002C5.63183 5.33337 5.33335 5.0349 5.33335 4.66671C5.33335 4.29852 5.63183 4.00004 6.00002 4.00004H10Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M8.00002 6.66671C8.36821 6.66671 8.66669 6.96518 8.66669 7.33337C8.66669 7.70156 8.36821 8.00004 8.00002 8.00004H6.00002C5.63183 8.00004 5.33335 7.70156 5.33335 7.33337C5.33335 6.96518 5.63183 6.66671 6.00002 6.66671H8.00002Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M12.827 10.7902L12.3624 9.58224C12.3048 9.43231 12.1607 9.33337 12 9.33337C11.8394 9.33337 11.6953 9.43231 11.6376 9.58224L11.173 10.7902C11.1054 10.9662 10.9662 11.1054 10.7902 11.173L9.58222 11.6376C9.43229 11.6953 9.33335 11.8394 9.33335 12C9.33335 12.1607 9.43229 12.3048 9.58222 12.3624L10.7902 12.827C10.9662 12.8947 11.1054 13.0338 11.173 13.2099L11.6376 14.4178C11.6953 14.5678 11.8394 14.6667 12 14.6667C12.1607 14.6667 12.3048 14.5678 12.3624 14.4178L12.827 13.2099C12.8947 13.0338 13.0338 12.8947 13.2099 12.827L14.4178 12.3624C14.5678 12.3048 14.6667 12.1607 14.6667 12C14.6667 11.8394 14.5678 11.6953 14.4178 11.6376L13.2099 11.173C13.0338 11.1054 12.8947 10.9662 12.827 10.7902Z",
|
||||
"fill": "currentColor"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "SearchLinesSparkle"
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
import * as React from 'react'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import data from './SearchLinesSparkle.json'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'SearchLinesSparkle'
|
||||
|
||||
export default Icon
|
||||
|
|
@ -11,5 +11,6 @@ export { default as HighQuality } from './HighQuality'
|
|||
export { default as HybridSearch } from './HybridSearch'
|
||||
export { default as ParentChildChunk } from './ParentChildChunk'
|
||||
export { default as QuestionAndAnswer } from './QuestionAndAnswer'
|
||||
export { default as SearchLinesSparkle } from './SearchLinesSparkle'
|
||||
export { default as SearchMenu } from './SearchMenu'
|
||||
export { default as VectorSearch } from './VectorSearch'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { PreProcessingRule } from '@/models/datasets'
|
||||
import type { PreProcessingRule, SummaryIndexSetting as SummaryIndexSettingType } from '@/models/datasets'
|
||||
import {
|
||||
RiAlertFill,
|
||||
RiSearchEyeLine,
|
||||
|
|
@ -12,6 +12,7 @@ import Button from '@/app/components/base/button'
|
|||
import Checkbox from '@/app/components/base/checkbox'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import SummaryIndexSetting from '@/app/components/datasets/settings/summary-index-setting'
|
||||
import { IS_CE_EDITION } from '@/config'
|
||||
import { ChunkingMode } from '@/models/datasets'
|
||||
import SettingCog from '../../assets/setting-gear-mod.svg'
|
||||
|
|
@ -52,6 +53,9 @@ type GeneralChunkingOptionsProps = {
|
|||
onReset: () => void
|
||||
// Locale
|
||||
locale: string
|
||||
showSummaryIndexSetting?: boolean
|
||||
summaryIndexSetting?: SummaryIndexSettingType
|
||||
onSummaryIndexSettingChange?: (payload: SummaryIndexSettingType) => void
|
||||
}
|
||||
|
||||
export const GeneralChunkingOptions: FC<GeneralChunkingOptionsProps> = ({
|
||||
|
|
@ -74,6 +78,9 @@ export const GeneralChunkingOptions: FC<GeneralChunkingOptionsProps> = ({
|
|||
onPreview,
|
||||
onReset,
|
||||
locale,
|
||||
showSummaryIndexSetting,
|
||||
summaryIndexSetting,
|
||||
onSummaryIndexSettingChange,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
|
|
@ -146,6 +153,17 @@ export const GeneralChunkingOptions: FC<GeneralChunkingOptionsProps> = ({
|
|||
</label>
|
||||
</div>
|
||||
))}
|
||||
{
|
||||
showSummaryIndexSetting && (
|
||||
<div className="mt-3">
|
||||
<SummaryIndexSetting
|
||||
entry="create-document"
|
||||
summaryIndexSetting={summaryIndexSetting}
|
||||
onSummaryIndexSettingChange={onSummaryIndexSettingChange}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{IS_CE_EDITION && (
|
||||
<>
|
||||
<Divider type="horizontal" className="my-4 bg-divider-subtle" />
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import type { FC } from 'react'
|
||||
import type { ParentChildConfig } from '../hooks'
|
||||
import type { ParentMode, PreProcessingRule } from '@/models/datasets'
|
||||
import type { ParentMode, PreProcessingRule, SummaryIndexSetting as SummaryIndexSettingType } from '@/models/datasets'
|
||||
import { RiSearchEyeLine } from '@remixicon/react'
|
||||
import Image from 'next/image'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
|
@ -11,6 +11,7 @@ import Checkbox from '@/app/components/base/checkbox'
|
|||
import Divider from '@/app/components/base/divider'
|
||||
import { ParentChildChunk } from '@/app/components/base/icons/src/vender/knowledge'
|
||||
import RadioCard from '@/app/components/base/radio-card'
|
||||
import SummaryIndexSetting from '@/app/components/datasets/settings/summary-index-setting'
|
||||
import { ChunkingMode } from '@/models/datasets'
|
||||
import FileList from '../../assets/file-list-3-fill.svg'
|
||||
import Note from '../../assets/note-mod.svg'
|
||||
|
|
@ -31,6 +32,8 @@ type ParentChildOptionsProps = {
|
|||
// State
|
||||
parentChildConfig: ParentChildConfig
|
||||
rules: PreProcessingRule[]
|
||||
summaryIndexSetting?: SummaryIndexSettingType
|
||||
onSummaryIndexSettingChange?: (payload: SummaryIndexSettingType) => void
|
||||
currentDocForm: ChunkingMode
|
||||
// Flags
|
||||
isActive: boolean
|
||||
|
|
@ -46,11 +49,13 @@ type ParentChildOptionsProps = {
|
|||
onRuleToggle: (id: string) => void
|
||||
onPreview: () => void
|
||||
onReset: () => void
|
||||
showSummaryIndexSetting?: boolean
|
||||
}
|
||||
|
||||
export const ParentChildOptions: FC<ParentChildOptionsProps> = ({
|
||||
parentChildConfig,
|
||||
rules,
|
||||
summaryIndexSetting,
|
||||
currentDocForm: _currentDocForm,
|
||||
isActive,
|
||||
isInUpload,
|
||||
|
|
@ -62,8 +67,10 @@ export const ParentChildOptions: FC<ParentChildOptionsProps> = ({
|
|||
onChildDelimiterChange,
|
||||
onChildMaxLengthChange,
|
||||
onRuleToggle,
|
||||
onSummaryIndexSettingChange,
|
||||
onPreview,
|
||||
onReset,
|
||||
showSummaryIndexSetting,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
|
|
@ -183,6 +190,17 @@ export const ParentChildOptions: FC<ParentChildOptionsProps> = ({
|
|||
</label>
|
||||
</div>
|
||||
))}
|
||||
{
|
||||
showSummaryIndexSetting && (
|
||||
<div className="mt-3">
|
||||
<SummaryIndexSetting
|
||||
entry="create-document"
|
||||
summaryIndexSetting={summaryIndexSetting}
|
||||
onSummaryIndexSettingChange={onSummaryIndexSettingChange}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { ChunkingMode } from '@/models/datasets'
|
|||
import { cn } from '@/utils/classnames'
|
||||
import { ChunkContainer, QAPreview } from '../../../chunk'
|
||||
import PreviewDocumentPicker from '../../../common/document-picker/preview-document-picker'
|
||||
import SummaryLabel from '../../../documents/detail/completed/common/summary-label'
|
||||
import { PreviewSlice } from '../../../formatted-text/flavours/preview-slice'
|
||||
import { FormattedText } from '../../../formatted-text/formatted'
|
||||
import PreviewContainer from '../../../preview/container'
|
||||
|
|
@ -99,6 +100,7 @@ export const PreviewPanel: FC<PreviewPanelProps> = ({
|
|||
characterCount={item.content.length}
|
||||
>
|
||||
{item.content}
|
||||
{item.summary && <SummaryLabel summary={item.summary} />}
|
||||
</ChunkContainer>
|
||||
))
|
||||
)}
|
||||
|
|
@ -131,6 +133,7 @@ export const PreviewPanel: FC<PreviewPanelProps> = ({
|
|||
)
|
||||
})}
|
||||
</FormattedText>
|
||||
{item.summary && <SummaryLabel summary={item.summary} />}
|
||||
</ChunkContainer>
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import type {
|
|||
CustomFile,
|
||||
FullDocumentDetail,
|
||||
ProcessRule,
|
||||
SummaryIndexSetting as SummaryIndexSettingType,
|
||||
} from '@/models/datasets'
|
||||
import type { RetrievalConfig, RETRIEVE_METHOD } from '@/types/app'
|
||||
import { useCallback } from 'react'
|
||||
|
|
@ -141,6 +142,7 @@ export const useDocumentCreation = (options: UseDocumentCreationOptions) => {
|
|||
retrievalConfig: RetrievalConfig,
|
||||
embeddingModel: DefaultModel,
|
||||
indexingTechnique: string,
|
||||
summaryIndexSetting?: SummaryIndexSettingType,
|
||||
): CreateDocumentReq | null => {
|
||||
if (isSetting) {
|
||||
return {
|
||||
|
|
@ -148,6 +150,7 @@ export const useDocumentCreation = (options: UseDocumentCreationOptions) => {
|
|||
doc_form: currentDocForm,
|
||||
doc_language: docLanguage,
|
||||
process_rule: processRule,
|
||||
summary_index_setting: summaryIndexSetting,
|
||||
retrieval_model: retrievalConfig,
|
||||
embedding_model: embeddingModel.model,
|
||||
embedding_model_provider: embeddingModel.provider,
|
||||
|
|
@ -164,6 +167,7 @@ export const useDocumentCreation = (options: UseDocumentCreationOptions) => {
|
|||
},
|
||||
indexing_technique: indexingTechnique,
|
||||
process_rule: processRule,
|
||||
summary_index_setting: summaryIndexSetting,
|
||||
doc_form: currentDocForm,
|
||||
doc_language: docLanguage,
|
||||
retrieval_model: retrievalConfig,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { ParentMode, PreProcessingRule, ProcessRule, Rules } from '@/models/datasets'
|
||||
import { useCallback, useState } from 'react'
|
||||
import type { ParentMode, PreProcessingRule, ProcessRule, Rules, SummaryIndexSetting as SummaryIndexSettingType } from '@/models/datasets'
|
||||
import { useCallback, useRef, useState } from 'react'
|
||||
import { ChunkingMode, ProcessMode } from '@/models/datasets'
|
||||
import escape from './escape'
|
||||
import unescape from './unescape'
|
||||
|
|
@ -39,10 +39,11 @@ export const defaultParentChildConfig: ParentChildConfig = {
|
|||
|
||||
export type UseSegmentationStateOptions = {
|
||||
initialSegmentationType?: ProcessMode
|
||||
initialSummaryIndexSetting?: SummaryIndexSettingType
|
||||
}
|
||||
|
||||
export const useSegmentationState = (options: UseSegmentationStateOptions = {}) => {
|
||||
const { initialSegmentationType } = options
|
||||
const { initialSegmentationType, initialSummaryIndexSetting } = options
|
||||
|
||||
// Segmentation type (general or parent-child)
|
||||
const [segmentationType, setSegmentationType] = useState<ProcessMode>(
|
||||
|
|
@ -58,6 +59,15 @@ export const useSegmentationState = (options: UseSegmentationStateOptions = {})
|
|||
// Pre-processing rules
|
||||
const [rules, setRules] = useState<PreProcessingRule[]>([])
|
||||
const [defaultConfig, setDefaultConfig] = useState<Rules>()
|
||||
const [summaryIndexSetting, setSummaryIndexSetting] = useState<SummaryIndexSettingType | undefined>(initialSummaryIndexSetting)
|
||||
const summaryIndexSettingRef = useRef<SummaryIndexSettingType | undefined>(initialSummaryIndexSetting)
|
||||
const handleSummaryIndexSettingChange = useCallback((payload: SummaryIndexSettingType) => {
|
||||
setSummaryIndexSetting((prev) => {
|
||||
const newSetting = { ...prev, ...payload }
|
||||
summaryIndexSettingRef.current = newSetting
|
||||
return newSetting
|
||||
})
|
||||
}, [])
|
||||
|
||||
// Parent-child config
|
||||
const [parentChildConfig, setParentChildConfig] = useState<ParentChildConfig>(defaultParentChildConfig)
|
||||
|
|
@ -134,6 +144,7 @@ export const useSegmentationState = (options: UseSegmentationStateOptions = {})
|
|||
},
|
||||
},
|
||||
mode: 'hierarchical',
|
||||
summary_index_setting: summaryIndexSettingRef.current,
|
||||
} as ProcessRule
|
||||
}
|
||||
|
||||
|
|
@ -147,6 +158,7 @@ export const useSegmentationState = (options: UseSegmentationStateOptions = {})
|
|||
},
|
||||
},
|
||||
mode: segmentationType,
|
||||
summary_index_setting: summaryIndexSettingRef.current,
|
||||
} as ProcessRule
|
||||
}, [rules, parentChildConfig, segmentIdentifier, maxChunkLength, overlap, segmentationType])
|
||||
|
||||
|
|
@ -204,6 +216,8 @@ export const useSegmentationState = (options: UseSegmentationStateOptions = {})
|
|||
defaultConfig,
|
||||
setDefaultConfig,
|
||||
toggleRule,
|
||||
summaryIndexSetting,
|
||||
handleSummaryIndexSettingChange,
|
||||
|
||||
// Parent-child config
|
||||
parentChildConfig,
|
||||
|
|
|
|||
|
|
@ -65,7 +65,9 @@ const StepTwo: FC<StepTwoProps> = ({
|
|||
// Custom hooks
|
||||
const segmentation = useSegmentationState({
|
||||
initialSegmentationType: currentDataset?.doc_form === ChunkingMode.parentChild ? ProcessMode.parentChild : ProcessMode.general,
|
||||
initialSummaryIndexSetting: currentDataset?.summary_index_setting,
|
||||
})
|
||||
const showSummaryIndexSetting = !currentDataset
|
||||
const indexing = useIndexingConfig({
|
||||
initialIndexType: propsIndexingType,
|
||||
initialEmbeddingModel: currentDataset?.embedding_model ? { provider: currentDataset.embedding_model_provider, model: currentDataset.embedding_model } : undefined,
|
||||
|
|
@ -156,7 +158,7 @@ const StepTwo: FC<StepTwoProps> = ({
|
|||
})
|
||||
if (!isValid)
|
||||
return
|
||||
const params = creation.buildCreationParams(currentDocForm, docLanguage, segmentation.getProcessRule(currentDocForm), indexing.retrievalConfig, indexing.embeddingModel, indexing.getIndexingTechnique())
|
||||
const params = creation.buildCreationParams(currentDocForm, docLanguage, segmentation.getProcessRule(currentDocForm), indexing.retrievalConfig, indexing.embeddingModel, indexing.getIndexingTechnique(), segmentation.summaryIndexSetting)
|
||||
if (!params)
|
||||
return
|
||||
await creation.executeCreation(params, indexing.indexType, indexing.retrievalConfig)
|
||||
|
|
@ -217,6 +219,9 @@ const StepTwo: FC<StepTwoProps> = ({
|
|||
onPreview={updatePreview}
|
||||
onReset={segmentation.resetToDefaults}
|
||||
locale={locale}
|
||||
showSummaryIndexSetting={showSummaryIndexSetting}
|
||||
summaryIndexSetting={segmentation.summaryIndexSetting}
|
||||
onSummaryIndexSettingChange={segmentation.handleSummaryIndexSettingChange}
|
||||
/>
|
||||
)}
|
||||
{showParentChildOption && (
|
||||
|
|
@ -236,6 +241,9 @@ const StepTwo: FC<StepTwoProps> = ({
|
|||
onRuleToggle={segmentation.toggleRule}
|
||||
onPreview={updatePreview}
|
||||
onReset={segmentation.resetToDefaults}
|
||||
showSummaryIndexSetting={showSummaryIndexSetting}
|
||||
summaryIndexSetting={segmentation.summaryIndexSetting}
|
||||
onSummaryIndexSettingChange={segmentation.handleSummaryIndexSettingChange}
|
||||
/>
|
||||
)}
|
||||
<Divider className="my-5" />
|
||||
|
|
|
|||
|
|
@ -30,12 +30,13 @@ import { useDatasetDetailContextWithSelector as useDatasetDetailContext } from '
|
|||
import useTimestamp from '@/hooks/use-timestamp'
|
||||
import { ChunkingMode, DataSourceType, DocumentActionType } from '@/models/datasets'
|
||||
import { DatasourceType } from '@/models/pipeline'
|
||||
import { useDocumentArchive, useDocumentBatchRetryIndex, useDocumentDelete, useDocumentDisable, useDocumentDownloadZip, useDocumentEnable } from '@/service/knowledge/use-document'
|
||||
import { useDocumentArchive, useDocumentBatchRetryIndex, useDocumentDelete, useDocumentDisable, useDocumentDownloadZip, useDocumentEnable, useDocumentSummary } from '@/service/knowledge/use-document'
|
||||
import { asyncRunSafe } from '@/utils'
|
||||
import { cn } from '@/utils/classnames'
|
||||
import { downloadBlob } from '@/utils/download'
|
||||
import { formatNumber } from '@/utils/format'
|
||||
import BatchAction from '../detail/completed/common/batch-action'
|
||||
import SummaryStatus from '../detail/completed/common/summary-status'
|
||||
import StatusItem from '../status-item'
|
||||
import s from '../style.module.css'
|
||||
import Operations from './operations'
|
||||
|
|
@ -219,6 +220,7 @@ const DocumentList: FC<IDocumentListProps> = ({
|
|||
onSelectedIdChange(uniq([...selectedIds, ...localDocs.map(doc => doc.id)]))
|
||||
}, [isAllSelected, localDocs, onSelectedIdChange, selectedIds])
|
||||
const { mutateAsync: archiveDocument } = useDocumentArchive()
|
||||
const { mutateAsync: generateSummary } = useDocumentSummary()
|
||||
const { mutateAsync: enableDocument } = useDocumentEnable()
|
||||
const { mutateAsync: disableDocument } = useDocumentDisable()
|
||||
const { mutateAsync: deleteDocument } = useDocumentDelete()
|
||||
|
|
@ -232,6 +234,9 @@ const DocumentList: FC<IDocumentListProps> = ({
|
|||
case DocumentActionType.archive:
|
||||
opApi = archiveDocument
|
||||
break
|
||||
case DocumentActionType.summary:
|
||||
opApi = generateSummary
|
||||
break
|
||||
case DocumentActionType.enable:
|
||||
opApi = enableDocument
|
||||
break
|
||||
|
|
@ -444,6 +449,13 @@ const DocumentList: FC<IDocumentListProps> = ({
|
|||
>
|
||||
<span className="grow-1 truncate text-sm">{doc.name}</span>
|
||||
</Tooltip>
|
||||
{
|
||||
doc.summary_index_status && (
|
||||
<div className="ml-1 hidden shrink-0 group-hover:flex">
|
||||
<SummaryStatus status={doc.summary_index_status} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<div className="hidden shrink-0 group-hover:ml-auto group-hover:flex">
|
||||
<Tooltip
|
||||
popupContent={t('list.table.rename', { ns: 'datasetDocuments' })}
|
||||
|
|
@ -496,6 +508,7 @@ const DocumentList: FC<IDocumentListProps> = ({
|
|||
className="absolute bottom-16 left-0 z-20"
|
||||
selectedIds={selectedIds}
|
||||
onArchive={handleAction(DocumentActionType.archive)}
|
||||
onBatchSummary={handleAction(DocumentActionType.summary)}
|
||||
onBatchEnable={handleAction(DocumentActionType.enable)}
|
||||
onBatchDisable={handleAction(DocumentActionType.disable)}
|
||||
onBatchDownload={downloadableSelectedIds.length > 0 ? handleBatchDownload : undefined}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ vi.mock('@/service/knowledge/use-document', () => ({
|
|||
useSyncWebsite: () => ({ mutateAsync: vi.fn().mockResolvedValue({}) }),
|
||||
useDocumentPause: () => ({ mutateAsync: vi.fn().mockResolvedValue({}) }),
|
||||
useDocumentResume: () => ({ mutateAsync: vi.fn().mockResolvedValue({}) }),
|
||||
useDocumentSummary: () => ({ mutateAsync: vi.fn().mockResolvedValue({}) }),
|
||||
}))
|
||||
|
||||
// Mock utils
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import { useTranslation } from 'react-i18next'
|
|||
import { useContext } from 'use-context-selector'
|
||||
import Confirm from '@/app/components/base/confirm'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import { SearchLinesSparkle } from '@/app/components/base/icons/src/vender/knowledge'
|
||||
import CustomPopover from '@/app/components/base/popover'
|
||||
import Switch from '@/app/components/base/switch'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
|
|
@ -34,6 +35,7 @@ import {
|
|||
useDocumentEnable,
|
||||
useDocumentPause,
|
||||
useDocumentResume,
|
||||
useDocumentSummary,
|
||||
useDocumentUnArchive,
|
||||
useSyncDocument,
|
||||
useSyncWebsite,
|
||||
|
|
@ -87,6 +89,7 @@ const Operations = ({
|
|||
const { mutateAsync: downloadDocument, isPending: isDownloading } = useDocumentDownload()
|
||||
const { mutateAsync: syncDocument } = useSyncDocument()
|
||||
const { mutateAsync: syncWebsite } = useSyncWebsite()
|
||||
const { mutateAsync: generateSummary } = useDocumentSummary()
|
||||
const { mutateAsync: pauseDocument } = useDocumentPause()
|
||||
const { mutateAsync: resumeDocument } = useDocumentResume()
|
||||
const isListScene = scene === 'list'
|
||||
|
|
@ -112,6 +115,9 @@ const Operations = ({
|
|||
else
|
||||
opApi = syncWebsite
|
||||
break
|
||||
case 'summary':
|
||||
opApi = generateSummary
|
||||
break
|
||||
case 'pause':
|
||||
opApi = pauseDocument
|
||||
break
|
||||
|
|
@ -257,6 +263,10 @@ const Operations = ({
|
|||
<span className={s.actionName}>{t('list.action.sync', { ns: 'datasetDocuments' })}</span>
|
||||
</div>
|
||||
)}
|
||||
<div className={s.actionItem} onClick={() => onOperate('summary')}>
|
||||
<SearchLinesSparkle className="h-4 w-4 text-text-tertiary" />
|
||||
<span className={s.actionName}>{t('list.action.summary', { ns: 'datasetDocuments' })}</span>
|
||||
</div>
|
||||
<Divider className="my-1" />
|
||||
</>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { useTranslation } from 'react-i18next'
|
|||
import Badge from '@/app/components/base/badge'
|
||||
import Button from '@/app/components/base/button'
|
||||
import { SkeletonContainer, SkeletonPoint, SkeletonRectangle, SkeletonRow } from '@/app/components/base/skeleton'
|
||||
import SummaryLabel from '@/app/components/datasets/documents/detail/completed/common/summary-label'
|
||||
import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail'
|
||||
import { ChunkingMode } from '@/models/datasets'
|
||||
import { DatasourceType } from '@/models/pipeline'
|
||||
|
|
@ -181,6 +182,7 @@ const ChunkPreview = ({
|
|||
characterCount={item.content.length}
|
||||
>
|
||||
{item.content}
|
||||
{item.summary && <SummaryLabel summary={item.summary} />}
|
||||
</ChunkContainer>
|
||||
))
|
||||
)}
|
||||
|
|
@ -207,6 +209,7 @@ const ChunkPreview = ({
|
|||
/>
|
||||
)
|
||||
})}
|
||||
{item.summary && <SummaryLabel summary={item.summary} />}
|
||||
</FormattedText>
|
||||
</ChunkContainer>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next'
|
|||
import Button from '@/app/components/base/button'
|
||||
import Confirm from '@/app/components/base/confirm'
|
||||
import Divider from '@/app/components/base/divider'
|
||||
import { SearchLinesSparkle } from '@/app/components/base/icons/src/vender/knowledge'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
const i18nPrefix = 'batchAction'
|
||||
|
|
@ -16,6 +17,7 @@ type IBatchActionProps = {
|
|||
onBatchDisable: () => void
|
||||
onBatchDownload?: () => void
|
||||
onBatchDelete: () => Promise<void>
|
||||
onBatchSummary?: () => void
|
||||
onArchive?: () => void
|
||||
onEditMetadata?: () => void
|
||||
onBatchReIndex?: () => void
|
||||
|
|
@ -27,6 +29,7 @@ const BatchAction: FC<IBatchActionProps> = ({
|
|||
selectedIds,
|
||||
onBatchEnable,
|
||||
onBatchDisable,
|
||||
onBatchSummary,
|
||||
onBatchDownload,
|
||||
onArchive,
|
||||
onBatchDelete,
|
||||
|
|
@ -84,7 +87,16 @@ const BatchAction: FC<IBatchActionProps> = ({
|
|||
<span className="px-0.5">{t('metadata.metadata', { ns: 'dataset' })}</span>
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{onBatchSummary && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="gap-x-0.5 px-3"
|
||||
onClick={onBatchSummary}
|
||||
>
|
||||
<SearchLinesSparkle className="size-4" />
|
||||
<span className="px-0.5">{t('list.action.summary', { ns: 'datasetDocuments' })}</span>
|
||||
</Button>
|
||||
)}
|
||||
{onArchive && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
import { memo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
type SummaryLabelProps = {
|
||||
summary?: string
|
||||
className?: string
|
||||
}
|
||||
const SummaryLabel = ({
|
||||
summary,
|
||||
className,
|
||||
}: SummaryLabelProps) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className={cn('space-y-1', className)}>
|
||||
<div className="system-xs-medium-uppercase mt-2 flex items-center justify-between text-text-tertiary">
|
||||
{t('segment.summary', { ns: 'datasetDocuments' })}
|
||||
<div className="ml-2 h-px grow bg-divider-regular"></div>
|
||||
</div>
|
||||
<div className="body-xs-regular text-text-tertiary">{summary}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(SummaryLabel)
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import { memo, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Badge from '@/app/components/base/badge'
|
||||
import { SearchLinesSparkle } from '@/app/components/base/icons/src/vender/knowledge'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
|
||||
type SummaryStatusProps = {
|
||||
status: string
|
||||
}
|
||||
|
||||
const SummaryStatus = ({ status }: SummaryStatusProps) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const tip = useMemo(() => {
|
||||
if (status === 'SUMMARIZING') {
|
||||
return t('list.summary.generatingSummary', { ns: 'datasetDocuments' })
|
||||
}
|
||||
return ''
|
||||
}, [status, t])
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
popupContent={tip}
|
||||
>
|
||||
{
|
||||
status === 'SUMMARIZING' && (
|
||||
<Badge className="border-text-accent-secondary text-text-accent-secondary">
|
||||
<SearchLinesSparkle className="mr-0.5 h-3 w-3" />
|
||||
<span>{t('list.summary.generating', { ns: 'datasetDocuments' })}</span>
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(SummaryStatus)
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import { memo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Textarea from 'react-textarea-autosize'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
||||
type SummaryTextProps = {
|
||||
value?: string
|
||||
onChange?: (value: string) => void
|
||||
disabled?: boolean
|
||||
}
|
||||
const SummaryText = ({
|
||||
value,
|
||||
onChange,
|
||||
disabled,
|
||||
}: SummaryTextProps) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className="space-y-1">
|
||||
<div className="system-xs-medium-uppercase text-text-tertiary">{t('segment.summary', { ns: 'datasetDocuments' })}</div>
|
||||
<Textarea
|
||||
className={cn(
|
||||
'body-sm-regular w-full resize-none bg-transparent leading-6 text-text-secondary outline-none',
|
||||
)}
|
||||
placeholder={t('segment.summaryPlaceholder', { ns: 'datasetDocuments' })}
|
||||
minRows={1}
|
||||
value={value ?? ''}
|
||||
onChange={e => onChange?.(e.target.value)}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(SummaryText)
|
||||
|
|
@ -22,6 +22,7 @@ type DrawerGroupProps = {
|
|||
answer: string,
|
||||
keywords: string[],
|
||||
attachments: FileEntity[],
|
||||
summary?: string,
|
||||
needRegenerate?: boolean,
|
||||
) => Promise<void>
|
||||
isRegenerationModalOpen: boolean
|
||||
|
|
|
|||
|
|
@ -614,7 +614,7 @@ describe('useSegmentListData', () => {
|
|||
})
|
||||
|
||||
await act(async () => {
|
||||
await result.current.handleUpdateSegment('seg-1', 'content', '', [], [], true)
|
||||
await result.current.handleUpdateSegment('seg-1', 'content', '', [], [], 'summary', true)
|
||||
})
|
||||
|
||||
expect(onCloseSegmentDetail).not.toHaveBeenCalled()
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ export type UseSegmentListDataReturn = {
|
|||
answer: string,
|
||||
keywords: string[],
|
||||
attachments: FileEntity[],
|
||||
summary?: string,
|
||||
needRegenerate?: boolean,
|
||||
) => Promise<void>
|
||||
resetList: () => void
|
||||
|
|
@ -248,6 +249,7 @@ export const useSegmentListData = (options: UseSegmentListDataOptions): UseSegme
|
|||
answer: string,
|
||||
keywords: string[],
|
||||
attachments: FileEntity[],
|
||||
summary?: string,
|
||||
needRegenerate = false,
|
||||
) => {
|
||||
const params: SegmentUpdater = { content: '', attachment_ids: [] }
|
||||
|
|
@ -285,6 +287,8 @@ export const useSegmentListData = (options: UseSegmentListDataOptions): UseSegme
|
|||
params.attachment_ids = attachments.map(item => item.uploadedId!)
|
||||
}
|
||||
|
||||
params.summary = summary ?? ''
|
||||
|
||||
if (needRegenerate)
|
||||
params.regenerate_child_chunks = needRegenerate
|
||||
|
||||
|
|
@ -302,6 +306,7 @@ export const useSegmentListData = (options: UseSegmentListDataOptions): UseSegme
|
|||
sign_content: res.data.sign_content,
|
||||
keywords: res.data.keywords,
|
||||
attachments: res.data.attachments,
|
||||
summary: res.data.summary,
|
||||
word_count: res.data.word_count,
|
||||
hit_count: res.data.hit_count,
|
||||
enabled: res.data.enabled,
|
||||
|
|
|
|||
|
|
@ -19,13 +19,14 @@ import { useDocumentContext } from '../../context'
|
|||
import ChildSegmentList from '../child-segment-list'
|
||||
import Dot from '../common/dot'
|
||||
import { SegmentIndexTag } from '../common/segment-index-tag'
|
||||
import SummaryLabel from '../common/summary-label'
|
||||
import Tag from '../common/tag'
|
||||
import ParentChunkCardSkeleton from '../skeleton/parent-chunk-card-skeleton'
|
||||
import ChunkContent from './chunk-content'
|
||||
|
||||
type ISegmentCardProps = {
|
||||
loading: boolean
|
||||
detail?: SegmentDetailModel & { document?: { name: string } }
|
||||
detail?: SegmentDetailModel & { document?: { name: string }, status?: string }
|
||||
onClick?: () => void
|
||||
onChangeSwitch?: (enabled: boolean, segId?: string) => Promise<void>
|
||||
onDelete?: (segId: string) => Promise<void>
|
||||
|
|
@ -43,7 +44,7 @@ type ISegmentCardProps = {
|
|||
}
|
||||
|
||||
const SegmentCard: FC<ISegmentCardProps> = ({
|
||||
detail = {},
|
||||
detail = { status: '' },
|
||||
onClick,
|
||||
onChangeSwitch,
|
||||
onDelete,
|
||||
|
|
@ -67,6 +68,7 @@ const SegmentCard: FC<ISegmentCardProps> = ({
|
|||
word_count,
|
||||
hit_count,
|
||||
answer,
|
||||
summary,
|
||||
keywords,
|
||||
child_chunks = [],
|
||||
created_at,
|
||||
|
|
@ -237,6 +239,11 @@ const SegmentCard: FC<ISegmentCardProps> = ({
|
|||
className={contentOpacity}
|
||||
/>
|
||||
{images.length > 0 && <ImageList images={images} size="md" className="py-1" />}
|
||||
{
|
||||
summary && (
|
||||
<SummaryLabel summary={summary} className="mt-2" />
|
||||
)
|
||||
}
|
||||
{isGeneralMode && (
|
||||
<div className={cn('flex flex-wrap items-center gap-2 py-1.5', contentOpacity)}>
|
||||
{keywords?.map(keyword => <Tag key={keyword} text={keyword} />)}
|
||||
|
|
|
|||
|
|
@ -356,6 +356,8 @@ describe('SegmentDetail', () => {
|
|||
expect.any(String),
|
||||
expect.any(Array),
|
||||
expect.any(Array),
|
||||
expect.any(String),
|
||||
expect.any(Boolean),
|
||||
)
|
||||
})
|
||||
|
||||
|
|
@ -545,6 +547,8 @@ describe('SegmentDetail', () => {
|
|||
expect.any(String),
|
||||
expect.any(Array),
|
||||
expect.arrayContaining([expect.objectContaining({ id: 'new-attachment' })]),
|
||||
expect.any(String),
|
||||
expect.any(Boolean),
|
||||
)
|
||||
})
|
||||
|
||||
|
|
@ -585,6 +589,7 @@ describe('SegmentDetail', () => {
|
|||
expect.any(String),
|
||||
expect.any(Array),
|
||||
expect.any(Array),
|
||||
expect.any(String),
|
||||
true,
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import Dot from './common/dot'
|
|||
import Keywords from './common/keywords'
|
||||
import RegenerationModal from './common/regeneration-modal'
|
||||
import { SegmentIndexTag } from './common/segment-index-tag'
|
||||
import SummaryText from './common/summary-text'
|
||||
import { useSegmentListContext } from './index'
|
||||
|
||||
type ISegmentDetailProps = {
|
||||
|
|
@ -35,6 +36,7 @@ type ISegmentDetailProps = {
|
|||
a: string,
|
||||
k: string[],
|
||||
attachments: FileEntity[],
|
||||
summary?: string,
|
||||
needRegenerate?: boolean,
|
||||
) => void
|
||||
onCancel: () => void
|
||||
|
|
@ -57,6 +59,7 @@ const SegmentDetail: FC<ISegmentDetailProps> = ({
|
|||
const { t } = useTranslation()
|
||||
const [question, setQuestion] = useState(isEditMode ? segInfo?.content || '' : segInfo?.sign_content || '')
|
||||
const [answer, setAnswer] = useState(segInfo?.answer || '')
|
||||
const [summary, setSummary] = useState(segInfo?.summary || '')
|
||||
const [attachments, setAttachments] = useState<FileEntity[]>(() => {
|
||||
return segInfo?.attachments?.map(item => ({
|
||||
id: uuid4(),
|
||||
|
|
@ -91,8 +94,8 @@ const SegmentDetail: FC<ISegmentDetailProps> = ({
|
|||
}, [onCancel])
|
||||
|
||||
const handleSave = useCallback(() => {
|
||||
onUpdate(segInfo?.id || '', question, answer, keywords, attachments)
|
||||
}, [onUpdate, segInfo?.id, question, answer, keywords, attachments])
|
||||
onUpdate(segInfo?.id || '', question, answer, keywords, attachments, summary, false)
|
||||
}, [onUpdate, segInfo?.id, question, answer, keywords, attachments, summary])
|
||||
|
||||
const handleRegeneration = useCallback(() => {
|
||||
setShowRegenerationModal(true)
|
||||
|
|
@ -111,8 +114,8 @@ const SegmentDetail: FC<ISegmentDetailProps> = ({
|
|||
}, [onCancel, onModalStateChange])
|
||||
|
||||
const onConfirmRegeneration = useCallback(() => {
|
||||
onUpdate(segInfo?.id || '', question, answer, keywords, attachments, true)
|
||||
}, [onUpdate, segInfo?.id, question, answer, keywords, attachments])
|
||||
onUpdate(segInfo?.id || '', question, answer, keywords, attachments, summary, true)
|
||||
}, [onUpdate, segInfo?.id, question, answer, keywords, attachments, summary])
|
||||
|
||||
const onAttachmentsChange = useCallback((attachments: FileEntity[]) => {
|
||||
setAttachments(attachments)
|
||||
|
|
@ -197,6 +200,11 @@ const SegmentDetail: FC<ISegmentDetailProps> = ({
|
|||
value={attachments}
|
||||
onChange={onAttachmentsChange}
|
||||
/>
|
||||
<SummaryText
|
||||
value={summary}
|
||||
onChange={summary => setSummary(summary)}
|
||||
disabled={!isEditMode}
|
||||
/>
|
||||
{isECOIndexing && (
|
||||
<Keywords
|
||||
className="w-full"
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
export type OperationName = 'delete' | 'archive' | 'enable' | 'disable' | 'sync' | 'un_archive' | 'pause' | 'resume'
|
||||
export type OperationName = 'delete' | 'archive' | 'enable' | 'disable' | 'sync' | 'un_archive' | 'pause' | 'resume' | 'summary'
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { cn } from '@/utils/classnames'
|
|||
import ImageList from '../../common/image-list'
|
||||
import Dot from '../../documents/detail/completed/common/dot'
|
||||
import { SegmentIndexTag } from '../../documents/detail/completed/common/segment-index-tag'
|
||||
import SummaryText from '../../documents/detail/completed/common/summary-text'
|
||||
import ChildChunksItem from './child-chunks-item'
|
||||
import Mask from './mask'
|
||||
import Score from './score'
|
||||
|
|
@ -28,7 +29,7 @@ const ChunkDetailModal = ({
|
|||
onHide,
|
||||
}: ChunkDetailModalProps) => {
|
||||
const { t } = useTranslation()
|
||||
const { segment, score, child_chunks, files } = payload
|
||||
const { segment, score, child_chunks, files, summary } = payload
|
||||
const { position, content, sign_content, keywords, document, answer } = segment
|
||||
const isParentChildRetrieval = !!(child_chunks && child_chunks.length > 0)
|
||||
const extension = document.name.split('.').slice(-1)[0] as FileAppearanceTypeEnum
|
||||
|
|
@ -104,11 +105,14 @@ const ChunkDetailModal = ({
|
|||
{/* Mask */}
|
||||
<Mask className="absolute inset-x-0 bottom-0" />
|
||||
</div>
|
||||
{(showImages || showKeywords) && (
|
||||
{(showImages || showKeywords || !!summary) && (
|
||||
<div className="flex flex-col gap-y-3 pt-3">
|
||||
{showImages && (
|
||||
<ImageList images={images} size="md" className="py-1" />
|
||||
)}
|
||||
{!!summary && (
|
||||
<SummaryText value={summary} disabled />
|
||||
)}
|
||||
{showKeywords && (
|
||||
<div className="flex flex-col gap-y-1">
|
||||
<div className="text-xs font-medium uppercase text-text-tertiary">{t(`${i18nPrefix}keyword`, { ns: 'datasetHitTesting' })}</div>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import * as React from 'react'
|
|||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Markdown } from '@/app/components/base/markdown'
|
||||
import SummaryLabel from '@/app/components/datasets/documents/detail/completed/common/summary-label'
|
||||
import Tag from '@/app/components/datasets/documents/detail/completed/common/tag'
|
||||
import { extensionToFileType } from '@/app/components/datasets/hit-testing/utils/extension-to-file-type'
|
||||
import { cn } from '@/utils/classnames'
|
||||
|
|
@ -25,7 +26,7 @@ const ResultItem = ({
|
|||
payload,
|
||||
}: ResultItemProps) => {
|
||||
const { t } = useTranslation()
|
||||
const { segment, score, child_chunks, files } = payload
|
||||
const { segment, score, child_chunks, files, summary } = payload
|
||||
const data = segment
|
||||
const { position, word_count, content, sign_content, keywords, document } = data
|
||||
const isParentChildRetrieval = !!(child_chunks && child_chunks.length > 0)
|
||||
|
|
@ -98,6 +99,9 @@ const ResultItem = ({
|
|||
))}
|
||||
</div>
|
||||
)}
|
||||
{summary && (
|
||||
<SummaryLabel summary={summary} className="mt-2" />
|
||||
)}
|
||||
</div>
|
||||
{/* Foot */}
|
||||
<ResultItemFooter docType={fileType} docTitle={document.name} showDetailModal={showDetailModal} />
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import type { AppIconSelection } from '@/app/components/base/app-icon-picker'
|
||||
import type { DefaultModel } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import type { Member } from '@/models/common'
|
||||
import type { IconInfo } from '@/models/datasets'
|
||||
import type { IconInfo, SummaryIndexSetting as SummaryIndexSettingType } from '@/models/datasets'
|
||||
import type { AppIconType, RetrievalConfig } from '@/types/app'
|
||||
import { RiAlertFill } from '@remixicon/react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
|
|
@ -33,6 +33,7 @@ import RetrievalSettings from '../../external-knowledge-base/create/RetrievalSet
|
|||
import ChunkStructure from '../chunk-structure'
|
||||
import IndexMethod from '../index-method'
|
||||
import PermissionSelector from '../permission-selector'
|
||||
import SummaryIndexSetting from '../summary-index-setting'
|
||||
import { checkShowMultiModalTip } from '../utils'
|
||||
|
||||
const rowClass = 'flex gap-x-1'
|
||||
|
|
@ -76,6 +77,12 @@ const Form = () => {
|
|||
model: '',
|
||||
},
|
||||
)
|
||||
const [summaryIndexSetting, setSummaryIndexSetting] = useState(currentDataset?.summary_index_setting)
|
||||
const handleSummaryIndexSettingChange = useCallback((payload: SummaryIndexSettingType) => {
|
||||
setSummaryIndexSetting((prev) => {
|
||||
return { ...prev, ...payload }
|
||||
})
|
||||
}, [])
|
||||
const { data: rerankModelList } = useModelList(ModelTypeEnum.rerank)
|
||||
const { data: embeddingModelList } = useModelList(ModelTypeEnum.textEmbedding)
|
||||
const { data: membersData } = useMembers()
|
||||
|
|
@ -167,6 +174,7 @@ const Form = () => {
|
|||
},
|
||||
}),
|
||||
keyword_number: keywordNumber,
|
||||
summary_index_setting: summaryIndexSetting,
|
||||
},
|
||||
} as any
|
||||
if (permission === DatasetPermission.partialMembers) {
|
||||
|
|
@ -348,6 +356,23 @@ const Form = () => {
|
|||
</div>
|
||||
</div>
|
||||
)}
|
||||
{
|
||||
indexMethod === IndexingType.QUALIFIED
|
||||
&& [ChunkingMode.text, ChunkingMode.parentChild].includes(currentDataset?.doc_form as ChunkingMode)
|
||||
&& (
|
||||
<>
|
||||
<Divider
|
||||
type="horizontal"
|
||||
className="my-1 h-px bg-divider-subtle"
|
||||
/>
|
||||
<SummaryIndexSetting
|
||||
entry="dataset-settings"
|
||||
summaryIndexSetting={summaryIndexSetting}
|
||||
onSummaryIndexSettingChange={handleSummaryIndexSettingChange}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
{/* Retrieval Method Config */}
|
||||
{currentDataset?.provider === 'external'
|
||||
? (
|
||||
|
|
|
|||
|
|
@ -0,0 +1,228 @@
|
|||
import type { ChangeEvent } from 'react'
|
||||
import type { DefaultModel } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import type { SummaryIndexSetting as SummaryIndexSettingType } from '@/models/datasets'
|
||||
import {
|
||||
memo,
|
||||
useCallback,
|
||||
useMemo,
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Switch from '@/app/components/base/switch'
|
||||
import Textarea from '@/app/components/base/textarea'
|
||||
import Tooltip from '@/app/components/base/tooltip'
|
||||
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
|
||||
|
||||
type SummaryIndexSettingProps = {
|
||||
entry?: 'knowledge-base' | 'dataset-settings' | 'create-document'
|
||||
summaryIndexSetting?: SummaryIndexSettingType
|
||||
onSummaryIndexSettingChange?: (payload: SummaryIndexSettingType) => void
|
||||
readonly?: boolean
|
||||
}
|
||||
const SummaryIndexSetting = ({
|
||||
entry = 'knowledge-base',
|
||||
summaryIndexSetting,
|
||||
onSummaryIndexSettingChange,
|
||||
readonly = false,
|
||||
}: SummaryIndexSettingProps) => {
|
||||
const { t } = useTranslation()
|
||||
const {
|
||||
data: textGenerationModelList,
|
||||
} = useModelList(ModelTypeEnum.textGeneration)
|
||||
const summaryIndexModelConfig = useMemo(() => {
|
||||
if (!summaryIndexSetting?.model_name || !summaryIndexSetting?.model_provider_name)
|
||||
return undefined
|
||||
|
||||
return {
|
||||
providerName: summaryIndexSetting?.model_provider_name,
|
||||
modelName: summaryIndexSetting?.model_name,
|
||||
}
|
||||
}, [summaryIndexSetting?.model_name, summaryIndexSetting?.model_provider_name])
|
||||
|
||||
const handleSummaryIndexEnableChange = useCallback((value: boolean) => {
|
||||
onSummaryIndexSettingChange?.({
|
||||
enable: value,
|
||||
})
|
||||
}, [onSummaryIndexSettingChange])
|
||||
|
||||
const handleSummaryIndexModelChange = useCallback((model: DefaultModel) => {
|
||||
onSummaryIndexSettingChange?.({
|
||||
model_provider_name: model.provider,
|
||||
model_name: model.model,
|
||||
})
|
||||
}, [onSummaryIndexSettingChange])
|
||||
|
||||
const handleSummaryIndexPromptChange = useCallback((e: ChangeEvent<HTMLTextAreaElement>) => {
|
||||
onSummaryIndexSettingChange?.({
|
||||
summary_prompt: e.target.value,
|
||||
})
|
||||
}, [onSummaryIndexSettingChange])
|
||||
|
||||
if (entry === 'knowledge-base') {
|
||||
return (
|
||||
<div>
|
||||
<div className="flex h-6 items-center justify-between">
|
||||
<div className="system-sm-semibold-uppercase flex items-center text-text-secondary">
|
||||
{t('form.summaryAutoGen', { ns: 'datasetSettings' })}
|
||||
<Tooltip
|
||||
triggerClassName="ml-1 h-4 w-4 shrink-0"
|
||||
popupContent={t('form.summaryAutoGenTip', { ns: 'datasetSettings' })}
|
||||
>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Switch
|
||||
defaultValue={summaryIndexSetting?.enable ?? false}
|
||||
onChange={handleSummaryIndexEnableChange}
|
||||
size="md"
|
||||
/>
|
||||
</div>
|
||||
{
|
||||
summaryIndexSetting?.enable && (
|
||||
<div>
|
||||
<div className="system-xs-medium-uppercase mb-1.5 mt-2 flex h-6 items-center text-text-tertiary">
|
||||
{t('form.summaryModel', { ns: 'datasetSettings' })}
|
||||
</div>
|
||||
<ModelSelector
|
||||
defaultModel={summaryIndexModelConfig && { provider: summaryIndexModelConfig.providerName, model: summaryIndexModelConfig.modelName }}
|
||||
modelList={textGenerationModelList}
|
||||
onSelect={handleSummaryIndexModelChange}
|
||||
readonly={readonly}
|
||||
showDeprecatedWarnIcon
|
||||
/>
|
||||
<div className="system-xs-medium-uppercase mt-3 flex h-6 items-center text-text-tertiary">
|
||||
{t('form.summaryInstructions', { ns: 'datasetSettings' })}
|
||||
</div>
|
||||
<Textarea
|
||||
value={summaryIndexSetting?.summary_prompt ?? ''}
|
||||
onChange={handleSummaryIndexPromptChange}
|
||||
disabled={readonly}
|
||||
placeholder={t('form.summaryInstructionsPlaceholder', { ns: 'datasetSettings' })}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (entry === 'dataset-settings') {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex gap-x-1">
|
||||
<div className="flex h-7 w-[180px] shrink-0 items-center pt-1">
|
||||
<div className="system-sm-semibold text-text-secondary">
|
||||
{t('form.summaryAutoGen', { ns: 'datasetSettings' })}
|
||||
</div>
|
||||
</div>
|
||||
<div className="py-1.5">
|
||||
<div className="system-sm-semibold flex items-center text-text-secondary">
|
||||
<Switch
|
||||
className="mr-2"
|
||||
defaultValue={summaryIndexSetting?.enable ?? false}
|
||||
onChange={handleSummaryIndexEnableChange}
|
||||
size="md"
|
||||
/>
|
||||
{
|
||||
summaryIndexSetting?.enable ? t('list.status.enabled', { ns: 'datasetDocuments' }) : t('list.status.disabled', { ns: 'datasetDocuments' })
|
||||
}
|
||||
</div>
|
||||
<div className="system-sm-regular mt-2 text-text-tertiary">
|
||||
{
|
||||
summaryIndexSetting?.enable && t('form.summaryAutoGenTip', { ns: 'datasetSettings' })
|
||||
}
|
||||
{
|
||||
!summaryIndexSetting?.enable && t('form.summaryAutoGenEnableTip', { ns: 'datasetSettings' })
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
summaryIndexSetting?.enable && (
|
||||
<>
|
||||
<div className="flex gap-x-1">
|
||||
<div className="flex h-7 w-[180px] shrink-0 items-center pt-1">
|
||||
<div className="system-sm-medium text-text-tertiary">
|
||||
{t('form.summaryModel', { ns: 'datasetSettings' })}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grow">
|
||||
<ModelSelector
|
||||
defaultModel={summaryIndexModelConfig && { provider: summaryIndexModelConfig.providerName, model: summaryIndexModelConfig.modelName }}
|
||||
modelList={textGenerationModelList}
|
||||
onSelect={handleSummaryIndexModelChange}
|
||||
readonly={readonly}
|
||||
showDeprecatedWarnIcon
|
||||
triggerClassName="h-8"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<div className="flex h-7 w-[180px] shrink-0 items-center pt-1">
|
||||
<div className="system-sm-medium text-text-tertiary">
|
||||
{t('form.summaryInstructions', { ns: 'datasetSettings' })}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grow">
|
||||
<Textarea
|
||||
value={summaryIndexSetting?.summary_prompt ?? ''}
|
||||
onChange={handleSummaryIndexPromptChange}
|
||||
disabled={readonly}
|
||||
placeholder={t('form.summaryInstructionsPlaceholder', { ns: 'datasetSettings' })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<div className="flex h-6 items-center">
|
||||
<Switch
|
||||
className="mr-2"
|
||||
defaultValue={summaryIndexSetting?.enable ?? false}
|
||||
onChange={handleSummaryIndexEnableChange}
|
||||
size="md"
|
||||
/>
|
||||
<div className="system-sm-semibold text-text-secondary">
|
||||
{t('form.summaryAutoGen', { ns: 'datasetSettings' })}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
summaryIndexSetting?.enable && (
|
||||
<>
|
||||
<div>
|
||||
<div className="system-sm-medium mb-1.5 flex h-6 items-center text-text-secondary">
|
||||
{t('form.summaryModel', { ns: 'datasetSettings' })}
|
||||
</div>
|
||||
<ModelSelector
|
||||
defaultModel={summaryIndexModelConfig && { provider: summaryIndexModelConfig.providerName, model: summaryIndexModelConfig.modelName }}
|
||||
modelList={textGenerationModelList}
|
||||
onSelect={handleSummaryIndexModelChange}
|
||||
readonly={readonly}
|
||||
showDeprecatedWarnIcon
|
||||
triggerClassName="h-8"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div className="system-sm-medium mb-1.5 flex h-6 items-center text-text-secondary">
|
||||
{t('form.summaryInstructions', { ns: 'datasetSettings' })}
|
||||
</div>
|
||||
<Textarea
|
||||
value={summaryIndexSetting?.summary_prompt ?? ''}
|
||||
onChange={handleSummaryIndexPromptChange}
|
||||
disabled={readonly}
|
||||
placeholder={t('form.summaryInstructionsPlaceholder', { ns: 'datasetSettings' })}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default memo(SummaryIndexSetting)
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
import type { QAChunk } from './types'
|
||||
import type { GeneralChunk, ParentChildChunk, QAChunk } from './types'
|
||||
import type { ParentMode } from '@/models/datasets'
|
||||
import * as React from 'react'
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Dot from '@/app/components/datasets/documents/detail/completed/common/dot'
|
||||
import SegmentIndexTag from '@/app/components/datasets/documents/detail/completed/common/segment-index-tag'
|
||||
import SummaryLabel from '@/app/components/datasets/documents/detail/completed/common/summary-label'
|
||||
import { PreviewSlice } from '@/app/components/datasets/formatted-text/flavours/preview-slice'
|
||||
import { ChunkingMode } from '@/models/datasets'
|
||||
import { formatNumber } from '@/utils/format'
|
||||
|
|
@ -14,7 +15,7 @@ import { QAItemType } from './types'
|
|||
type ChunkCardProps = {
|
||||
chunkType: ChunkingMode
|
||||
parentMode?: ParentMode
|
||||
content: string | string[] | QAChunk
|
||||
content: ParentChildChunk | QAChunk | GeneralChunk
|
||||
positionId?: string | number
|
||||
wordCount: number
|
||||
}
|
||||
|
|
@ -33,7 +34,7 @@ const ChunkCard = (props: ChunkCardProps) => {
|
|||
|
||||
const contentElement = useMemo(() => {
|
||||
if (chunkType === ChunkingMode.parentChild) {
|
||||
return (content as string[]).map((child, index) => {
|
||||
return (content as ParentChildChunk).child_contents.map((child, index) => {
|
||||
const indexForLabel = index + 1
|
||||
return (
|
||||
<PreviewSlice
|
||||
|
|
@ -57,7 +58,17 @@ const ChunkCard = (props: ChunkCardProps) => {
|
|||
)
|
||||
}
|
||||
|
||||
return content as string
|
||||
return (content as GeneralChunk).content
|
||||
}, [content, chunkType])
|
||||
|
||||
const summaryElement = useMemo(() => {
|
||||
if (chunkType === ChunkingMode.parentChild) {
|
||||
return (content as ParentChildChunk).parent_summary
|
||||
}
|
||||
if (chunkType === ChunkingMode.text) {
|
||||
return (content as GeneralChunk).summary
|
||||
}
|
||||
return null
|
||||
}, [content, chunkType])
|
||||
|
||||
return (
|
||||
|
|
@ -73,6 +84,7 @@ const ChunkCard = (props: ChunkCardProps) => {
|
|||
</div>
|
||||
)}
|
||||
<div className="body-md-regular text-text-secondary">{contentElement}</div>
|
||||
{summaryElement && <SummaryLabel summary={summaryElement} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ import { QAItemType } from './types'
|
|||
// Test Data Factories
|
||||
// =============================================================================
|
||||
|
||||
const createGeneralChunks = (overrides: string[] = []): GeneralChunks => {
|
||||
const createGeneralChunks = (overrides: GeneralChunks = []): GeneralChunks => {
|
||||
if (overrides.length > 0)
|
||||
return overrides
|
||||
return [
|
||||
'This is the first chunk of text content.',
|
||||
'This is the second chunk with different content.',
|
||||
'Third chunk here with more text.',
|
||||
{ content: 'This is the first chunk of text content.' },
|
||||
{ content: 'This is the second chunk with different content.' },
|
||||
{ content: 'Third chunk here with more text.' },
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -152,14 +152,14 @@ describe('ChunkCard', () => {
|
|||
render(
|
||||
<ChunkCard
|
||||
chunkType={ChunkingMode.text}
|
||||
content="This is plain text content."
|
||||
content={createGeneralChunks()[0]}
|
||||
wordCount={27}
|
||||
positionId={1}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Assert
|
||||
expect(screen.getByText('This is plain text content.')).toBeInTheDocument()
|
||||
expect(screen.getByText('This is the first chunk of text content.')).toBeInTheDocument()
|
||||
expect(screen.getByText(/Chunk-01/)).toBeInTheDocument()
|
||||
})
|
||||
|
||||
|
|
@ -196,7 +196,7 @@ describe('ChunkCard', () => {
|
|||
<ChunkCard
|
||||
chunkType={ChunkingMode.parentChild}
|
||||
parentMode="paragraph"
|
||||
content={childContents}
|
||||
content={createParentChildChunk({ child_contents: childContents })}
|
||||
wordCount={50}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -218,7 +218,7 @@ describe('ChunkCard', () => {
|
|||
<ChunkCard
|
||||
chunkType={ChunkingMode.parentChild}
|
||||
parentMode="paragraph"
|
||||
content={['Child content']}
|
||||
content={createParentChildChunk({ child_contents: ['Child content'] })}
|
||||
wordCount={13}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -234,7 +234,7 @@ describe('ChunkCard', () => {
|
|||
<ChunkCard
|
||||
chunkType={ChunkingMode.parentChild}
|
||||
parentMode="full-doc"
|
||||
content={['Child content']}
|
||||
content={createParentChildChunk({ child_contents: ['Child content'] })}
|
||||
wordCount={13}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -250,7 +250,7 @@ describe('ChunkCard', () => {
|
|||
render(
|
||||
<ChunkCard
|
||||
chunkType={ChunkingMode.text}
|
||||
content="Text content"
|
||||
content={createGeneralChunks()[0]}
|
||||
wordCount={12}
|
||||
positionId={5}
|
||||
/>,
|
||||
|
|
@ -268,7 +268,7 @@ describe('ChunkCard', () => {
|
|||
render(
|
||||
<ChunkCard
|
||||
chunkType={ChunkingMode.text}
|
||||
content="Some content"
|
||||
content={createGeneralChunks()[0]}
|
||||
wordCount={1234}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -283,7 +283,7 @@ describe('ChunkCard', () => {
|
|||
render(
|
||||
<ChunkCard
|
||||
chunkType={ChunkingMode.text}
|
||||
content="Some content"
|
||||
content={createGeneralChunks()[0]}
|
||||
wordCount={100}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -299,7 +299,7 @@ describe('ChunkCard', () => {
|
|||
<ChunkCard
|
||||
chunkType={ChunkingMode.parentChild}
|
||||
parentMode="full-doc"
|
||||
content={['Child']}
|
||||
content={createParentChildChunk({ child_contents: ['Child'] })}
|
||||
wordCount={500}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -317,7 +317,7 @@ describe('ChunkCard', () => {
|
|||
render(
|
||||
<ChunkCard
|
||||
chunkType={ChunkingMode.text}
|
||||
content="Content"
|
||||
content={createGeneralChunks()[0]}
|
||||
wordCount={7}
|
||||
positionId={42}
|
||||
/>,
|
||||
|
|
@ -332,7 +332,7 @@ describe('ChunkCard', () => {
|
|||
render(
|
||||
<ChunkCard
|
||||
chunkType={ChunkingMode.text}
|
||||
content="Content"
|
||||
content={createGeneralChunks()[0]}
|
||||
wordCount={7}
|
||||
positionId="99"
|
||||
/>,
|
||||
|
|
@ -347,7 +347,7 @@ describe('ChunkCard', () => {
|
|||
render(
|
||||
<ChunkCard
|
||||
chunkType={ChunkingMode.text}
|
||||
content="Content"
|
||||
content={createGeneralChunks()[0]}
|
||||
wordCount={7}
|
||||
positionId={3}
|
||||
/>,
|
||||
|
|
@ -366,7 +366,7 @@ describe('ChunkCard', () => {
|
|||
<ChunkCard
|
||||
chunkType={ChunkingMode.parentChild}
|
||||
parentMode="paragraph"
|
||||
content={['Child']}
|
||||
content={createParentChildChunk({ child_contents: ['Child'] })}
|
||||
wordCount={5}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -380,7 +380,7 @@ describe('ChunkCard', () => {
|
|||
<ChunkCard
|
||||
chunkType={ChunkingMode.parentChild}
|
||||
parentMode="full-doc"
|
||||
content={['Child']}
|
||||
content={createParentChildChunk({ child_contents: ['Child'] })}
|
||||
wordCount={5}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -392,10 +392,13 @@ describe('ChunkCard', () => {
|
|||
|
||||
it('should update contentElement memo when content changes', () => {
|
||||
// Arrange
|
||||
const initialContent = { content: 'Initial content' }
|
||||
const updatedContent = { content: 'Updated content' }
|
||||
|
||||
const { rerender } = render(
|
||||
<ChunkCard
|
||||
chunkType={ChunkingMode.text}
|
||||
content="Initial content"
|
||||
content={initialContent}
|
||||
wordCount={15}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -408,7 +411,7 @@ describe('ChunkCard', () => {
|
|||
rerender(
|
||||
<ChunkCard
|
||||
chunkType={ChunkingMode.text}
|
||||
content="Updated content"
|
||||
content={updatedContent}
|
||||
wordCount={15}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -421,10 +424,11 @@ describe('ChunkCard', () => {
|
|||
|
||||
it('should update contentElement memo when chunkType changes', () => {
|
||||
// Arrange
|
||||
const textContent = { content: 'Text content' }
|
||||
const { rerender } = render(
|
||||
<ChunkCard
|
||||
chunkType={ChunkingMode.text}
|
||||
content="Text content"
|
||||
content={textContent}
|
||||
wordCount={12}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -458,7 +462,7 @@ describe('ChunkCard', () => {
|
|||
<ChunkCard
|
||||
chunkType={ChunkingMode.parentChild}
|
||||
parentMode="paragraph"
|
||||
content={[]}
|
||||
content={createParentChildChunk({ child_contents: [] })}
|
||||
wordCount={0}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -490,12 +494,13 @@ describe('ChunkCard', () => {
|
|||
it('should handle very long content', () => {
|
||||
// Arrange
|
||||
const longContent = 'A'.repeat(10000)
|
||||
const longContentChunk = { content: longContent }
|
||||
|
||||
// Act
|
||||
render(
|
||||
<ChunkCard
|
||||
chunkType={ChunkingMode.text}
|
||||
content={longContent}
|
||||
content={longContentChunk}
|
||||
wordCount={10000}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -510,7 +515,7 @@ describe('ChunkCard', () => {
|
|||
render(
|
||||
<ChunkCard
|
||||
chunkType={ChunkingMode.text}
|
||||
content=""
|
||||
content={createGeneralChunks()[0]}
|
||||
wordCount={0}
|
||||
positionId={1}
|
||||
/>,
|
||||
|
|
@ -546,9 +551,9 @@ describe('ChunkCardList', () => {
|
|||
)
|
||||
|
||||
// Assert
|
||||
expect(screen.getByText(chunks[0])).toBeInTheDocument()
|
||||
expect(screen.getByText(chunks[1])).toBeInTheDocument()
|
||||
expect(screen.getByText(chunks[2])).toBeInTheDocument()
|
||||
expect(screen.getByText(chunks[0].content)).toBeInTheDocument()
|
||||
expect(screen.getByText(chunks[1].content)).toBeInTheDocument()
|
||||
expect(screen.getByText(chunks[2].content)).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render parent-child chunks correctly', () => {
|
||||
|
|
@ -594,7 +599,10 @@ describe('ChunkCardList', () => {
|
|||
describe('Memoization - chunkList', () => {
|
||||
it('should extract chunks from GeneralChunks for text mode', () => {
|
||||
// Arrange
|
||||
const chunks: GeneralChunks = ['Chunk 1', 'Chunk 2']
|
||||
const chunks: GeneralChunks = [
|
||||
{ content: 'Chunk 1' },
|
||||
{ content: 'Chunk 2' },
|
||||
]
|
||||
|
||||
// Act
|
||||
render(
|
||||
|
|
@ -653,7 +661,7 @@ describe('ChunkCardList', () => {
|
|||
|
||||
it('should update chunkList when chunkInfo changes', () => {
|
||||
// Arrange
|
||||
const initialChunks = createGeneralChunks(['Initial chunk'])
|
||||
const initialChunks = createGeneralChunks([{ content: 'Initial chunk' }])
|
||||
|
||||
const { rerender } = render(
|
||||
<ChunkCardList
|
||||
|
|
@ -666,7 +674,7 @@ describe('ChunkCardList', () => {
|
|||
expect(screen.getByText('Initial chunk')).toBeInTheDocument()
|
||||
|
||||
// Act - update chunks
|
||||
const updatedChunks = createGeneralChunks(['Updated chunk'])
|
||||
const updatedChunks = createGeneralChunks([{ content: 'Updated chunk' }])
|
||||
rerender(
|
||||
<ChunkCardList
|
||||
chunkType={ChunkingMode.text}
|
||||
|
|
@ -684,7 +692,7 @@ describe('ChunkCardList', () => {
|
|||
describe('Word Count Calculation', () => {
|
||||
it('should calculate word count for text chunks using string length', () => {
|
||||
// Arrange - "Hello" has 5 characters
|
||||
const chunks = createGeneralChunks(['Hello'])
|
||||
const chunks = createGeneralChunks([{ content: 'Hello' }])
|
||||
|
||||
// Act
|
||||
render(
|
||||
|
|
@ -747,7 +755,11 @@ describe('ChunkCardList', () => {
|
|||
describe('Position ID', () => {
|
||||
it('should assign 1-based position IDs to chunks', () => {
|
||||
// Arrange
|
||||
const chunks = createGeneralChunks(['First', 'Second', 'Third'])
|
||||
const chunks = createGeneralChunks([
|
||||
{ content: 'First' },
|
||||
{ content: 'Second' },
|
||||
{ content: 'Third' },
|
||||
])
|
||||
|
||||
// Act
|
||||
render(
|
||||
|
|
@ -768,7 +780,7 @@ describe('ChunkCardList', () => {
|
|||
describe('Custom className', () => {
|
||||
it('should apply custom className to container', () => {
|
||||
// Arrange
|
||||
const chunks = createGeneralChunks(['Test'])
|
||||
const chunks = createGeneralChunks([{ content: 'Test' }])
|
||||
|
||||
// Act
|
||||
const { container } = render(
|
||||
|
|
@ -785,7 +797,7 @@ describe('ChunkCardList', () => {
|
|||
|
||||
it('should merge custom className with default classes', () => {
|
||||
// Arrange
|
||||
const chunks = createGeneralChunks(['Test'])
|
||||
const chunks = createGeneralChunks([{ content: 'Test' }])
|
||||
|
||||
// Act
|
||||
const { container } = render(
|
||||
|
|
@ -805,7 +817,7 @@ describe('ChunkCardList', () => {
|
|||
|
||||
it('should render without className prop', () => {
|
||||
// Arrange
|
||||
const chunks = createGeneralChunks(['Test'])
|
||||
const chunks = createGeneralChunks([{ content: 'Test' }])
|
||||
|
||||
// Act
|
||||
const { container } = render(
|
||||
|
|
@ -860,7 +872,7 @@ describe('ChunkCardList', () => {
|
|||
|
||||
it('should not use parentMode for text type', () => {
|
||||
// Arrange
|
||||
const chunks = createGeneralChunks(['Text'])
|
||||
const chunks = createGeneralChunks([{ content: 'Text' }])
|
||||
|
||||
// Act
|
||||
render(
|
||||
|
|
@ -937,7 +949,7 @@ describe('ChunkCardList', () => {
|
|||
|
||||
it('should handle single item in chunks', () => {
|
||||
// Arrange
|
||||
const chunks = createGeneralChunks(['Single chunk'])
|
||||
const chunks = createGeneralChunks([{ content: 'Single chunk' }])
|
||||
|
||||
// Act
|
||||
render(
|
||||
|
|
@ -954,7 +966,7 @@ describe('ChunkCardList', () => {
|
|||
|
||||
it('should handle large number of chunks', () => {
|
||||
// Arrange
|
||||
const chunks = Array.from({ length: 100 }, (_, i) => `Chunk number ${i + 1}`)
|
||||
const chunks = Array.from({ length: 100 }, (_, i) => ({ content: `Chunk number ${i + 1}` }))
|
||||
|
||||
// Act
|
||||
render(
|
||||
|
|
@ -975,8 +987,11 @@ describe('ChunkCardList', () => {
|
|||
describe('Key Generation', () => {
|
||||
it('should generate unique keys for chunks', () => {
|
||||
// Arrange - chunks with same content
|
||||
const chunks = createGeneralChunks(['Same content', 'Same content', 'Same content'])
|
||||
|
||||
const chunks = createGeneralChunks([
|
||||
{ content: 'Same content' },
|
||||
{ content: 'Same content' },
|
||||
{ content: 'Same content' },
|
||||
])
|
||||
// Act
|
||||
const { container } = render(
|
||||
<ChunkCardList
|
||||
|
|
@ -1006,9 +1021,9 @@ describe('ChunkCardList Integration', () => {
|
|||
it('should render complete text chunking workflow', () => {
|
||||
// Arrange
|
||||
const textChunks = createGeneralChunks([
|
||||
'First paragraph of the document.',
|
||||
'Second paragraph with more information.',
|
||||
'Final paragraph concluding the content.',
|
||||
{ content: 'First paragraph of the document.' },
|
||||
{ content: 'Second paragraph with more information.' },
|
||||
{ content: 'Final paragraph concluding the content.' },
|
||||
])
|
||||
|
||||
// Act
|
||||
|
|
@ -1104,7 +1119,7 @@ describe('ChunkCardList Integration', () => {
|
|||
describe('Type Switching', () => {
|
||||
it('should handle switching from text to QA type', () => {
|
||||
// Arrange
|
||||
const textChunks = createGeneralChunks(['Text content'])
|
||||
const textChunks = createGeneralChunks([{ content: 'Text content' }])
|
||||
const qaChunks = createQAChunks()
|
||||
|
||||
const { rerender } = render(
|
||||
|
|
@ -1132,7 +1147,7 @@ describe('ChunkCardList Integration', () => {
|
|||
|
||||
it('should handle switching from text to parent-child type', () => {
|
||||
// Arrange
|
||||
const textChunks = createGeneralChunks(['Simple text'])
|
||||
const textChunks = createGeneralChunks([{ content: 'Simple text' }])
|
||||
const parentChildChunks = createParentChildChunks()
|
||||
|
||||
const { rerender } = render(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { ChunkInfo, GeneralChunks, ParentChildChunk, ParentChildChunks, QAChunk, QAChunks } from './types'
|
||||
import type { ChunkInfo, GeneralChunk, GeneralChunks, ParentChildChunk, ParentChildChunks, QAChunk, QAChunks } from './types'
|
||||
import type { ParentMode } from '@/models/datasets'
|
||||
import { useMemo } from 'react'
|
||||
import { ChunkingMode } from '@/models/datasets'
|
||||
|
|
@ -21,13 +21,13 @@ export const ChunkCardList = (props: ChunkCardListProps) => {
|
|||
if (chunkType === ChunkingMode.parentChild)
|
||||
return (chunkInfo as ParentChildChunks).parent_child_chunks
|
||||
return (chunkInfo as QAChunks).qa_chunks
|
||||
}, [chunkInfo])
|
||||
}, [chunkInfo, chunkType])
|
||||
|
||||
const getWordCount = (seg: string | ParentChildChunk | QAChunk) => {
|
||||
const getWordCount = (seg: GeneralChunk | ParentChildChunk | QAChunk) => {
|
||||
if (chunkType === ChunkingMode.parentChild)
|
||||
return (seg as ParentChildChunk).parent_content.length
|
||||
return (seg as ParentChildChunk).parent_content?.length
|
||||
if (chunkType === ChunkingMode.text)
|
||||
return (seg as string).length
|
||||
return (seg as GeneralChunk).content.length
|
||||
return (seg as QAChunk).question.length + (seg as QAChunk).answer.length
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ export const ChunkCardList = (props: ChunkCardListProps) => {
|
|||
key={`${chunkType}-${index}`}
|
||||
chunkType={chunkType}
|
||||
parentMode={parentMode}
|
||||
content={chunkType === ChunkingMode.parentChild ? (seg as ParentChildChunk).child_contents : (seg as string | QAChunk)}
|
||||
content={seg}
|
||||
wordCount={wordCount}
|
||||
positionId={index + 1}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
export type GeneralChunks = string[]
|
||||
|
||||
export type GeneralChunk = {
|
||||
content: string
|
||||
summary?: string
|
||||
}
|
||||
export type GeneralChunks = GeneralChunk[]
|
||||
export type ParentChildChunk = {
|
||||
child_contents: string[]
|
||||
parent_content: string
|
||||
parent_summary?: string
|
||||
parent_mode: string
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import type { GeneralChunks } from '@/app/components/rag-pipeline/components/chunk-card-list/types'
|
||||
import type { WorkflowRunningData } from '@/app/components/workflow/types'
|
||||
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { WorkflowRunningStatus } from '@/app/components/workflow/types'
|
||||
import { ChunkingMode } from '@/models/datasets'
|
||||
|
||||
import Header from './header'
|
||||
// Import components after mocks
|
||||
import TestRunPanel from './index'
|
||||
|
|
@ -830,17 +830,27 @@ describe('formatPreviewChunks', () => {
|
|||
const outputs = createMockGeneralOutputs(['content1', 'content2', 'content3'])
|
||||
const result = formatPreviewChunks(outputs)
|
||||
|
||||
expect(result).toEqual(['content1', 'content2', 'content3'])
|
||||
expect(result).toEqual([
|
||||
{ content: 'content1', summary: undefined },
|
||||
{ content: 'content2', summary: undefined },
|
||||
{ content: 'content3', summary: undefined },
|
||||
])
|
||||
})
|
||||
|
||||
it('should limit to RAG_PIPELINE_PREVIEW_CHUNK_NUM chunks', () => {
|
||||
const manyChunks = Array.from({ length: 10 }, (_, i) => `chunk${i}`)
|
||||
const outputs = createMockGeneralOutputs(manyChunks)
|
||||
const result = formatPreviewChunks(outputs) as string[]
|
||||
const result = formatPreviewChunks(outputs) as GeneralChunks
|
||||
|
||||
// RAG_PIPELINE_PREVIEW_CHUNK_NUM is mocked to 5
|
||||
expect(result).toHaveLength(5)
|
||||
expect(result).toEqual(['chunk0', 'chunk1', 'chunk2', 'chunk3', 'chunk4'])
|
||||
expect(result).toEqual([
|
||||
{ content: 'chunk0', summary: undefined },
|
||||
{ content: 'chunk1', summary: undefined },
|
||||
{ content: 'chunk2', summary: undefined },
|
||||
{ content: 'chunk3', summary: undefined },
|
||||
{ content: 'chunk4', summary: undefined },
|
||||
])
|
||||
})
|
||||
|
||||
it('should handle empty preview array', () => {
|
||||
|
|
|
|||
|
|
@ -590,9 +590,9 @@ describe('formatPreviewChunks', () => {
|
|||
const result = formatPreviewChunks(outputs) as GeneralChunks
|
||||
|
||||
expect(result).toHaveLength(3)
|
||||
expect(result[0]).toBe('General chunk content 1')
|
||||
expect(result[1]).toBe('General chunk content 2')
|
||||
expect(result[2]).toBe('General chunk content 3')
|
||||
expect((result as GeneralChunks)[0].content).toBe('General chunk content 1')
|
||||
expect((result as GeneralChunks)[1].content).toBe('General chunk content 2')
|
||||
expect((result as GeneralChunks)[2].content).toBe('General chunk content 3')
|
||||
})
|
||||
|
||||
it('should limit chunks to RAG_PIPELINE_PREVIEW_CHUNK_NUM', () => {
|
||||
|
|
|
|||
|
|
@ -145,9 +145,9 @@ describe('formatPreviewChunks', () => {
|
|||
|
||||
// Assert
|
||||
expect(result).toEqual([
|
||||
'First chunk content',
|
||||
'Second chunk content',
|
||||
'Third chunk content',
|
||||
{ content: 'First chunk content', summary: undefined },
|
||||
{ content: 'Second chunk content', summary: undefined },
|
||||
{ content: 'Third chunk content', summary: undefined },
|
||||
])
|
||||
})
|
||||
|
||||
|
|
@ -160,8 +160,8 @@ describe('formatPreviewChunks', () => {
|
|||
|
||||
// Assert
|
||||
expect(result).toHaveLength(20)
|
||||
expect(result[0]).toBe('Chunk content 1')
|
||||
expect(result[19]).toBe('Chunk content 20')
|
||||
expect((result as GeneralChunks)[0].content).toBe('Chunk content 1')
|
||||
expect((result as GeneralChunks)[19].content).toBe('Chunk content 20')
|
||||
})
|
||||
|
||||
it('should handle empty preview array for general chunks', () => {
|
||||
|
|
@ -186,7 +186,10 @@ describe('formatPreviewChunks', () => {
|
|||
const result = formatPreviewChunks(outputs) as GeneralChunks
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(['', 'Valid content'])
|
||||
expect(result).toEqual([
|
||||
{ content: '', summary: undefined },
|
||||
{ content: 'Valid content', summary: undefined },
|
||||
])
|
||||
})
|
||||
|
||||
it('should handle general chunks with special characters', () => {
|
||||
|
|
@ -202,9 +205,9 @@ describe('formatPreviewChunks', () => {
|
|||
|
||||
// Assert
|
||||
expect(result).toEqual([
|
||||
'<script>alert("xss")</script>',
|
||||
'中文内容 🎉',
|
||||
'Line1\nLine2\tTab',
|
||||
{ content: '<script>alert("xss")</script>', summary: undefined },
|
||||
{ content: '中文内容 🎉', summary: undefined },
|
||||
{ content: 'Line1\nLine2\tTab', summary: undefined },
|
||||
])
|
||||
})
|
||||
|
||||
|
|
@ -217,7 +220,7 @@ describe('formatPreviewChunks', () => {
|
|||
const result = formatPreviewChunks(outputs) as GeneralChunks
|
||||
|
||||
// Assert
|
||||
expect(result[0]).toHaveLength(10000)
|
||||
expect((result as GeneralChunks)[0].content).toHaveLength(10000)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -501,7 +504,7 @@ describe('formatPreviewChunks', () => {
|
|||
const result = formatPreviewChunks(outputs) as GeneralChunks
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(['Test'])
|
||||
expect(result).toEqual([{ content: 'Test', summary: undefined }])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -667,7 +670,10 @@ describe('ResultPreview', () => {
|
|||
// Assert
|
||||
const chunkList = screen.getByTestId('chunk-card-list')
|
||||
const chunkInfo = JSON.parse(chunkList.getAttribute('data-chunk-info') || '[]')
|
||||
expect(chunkInfo).toEqual(['Chunk 1', 'Chunk 2'])
|
||||
expect(chunkInfo).toEqual([
|
||||
{ content: 'Chunk 1' },
|
||||
{ content: 'Chunk 2' },
|
||||
])
|
||||
})
|
||||
|
||||
it('should handle parent-child outputs', () => {
|
||||
|
|
@ -792,7 +798,7 @@ describe('ResultPreview', () => {
|
|||
// Assert
|
||||
const chunkList = screen.getByTestId('chunk-card-list')
|
||||
const chunkInfo = JSON.parse(chunkList.getAttribute('data-chunk-info') || '[]')
|
||||
expect(chunkInfo).toEqual(['Second'])
|
||||
expect(chunkInfo).toEqual([{ content: 'Second' }])
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -820,7 +826,7 @@ describe('ResultPreview', () => {
|
|||
|
||||
let chunkList = screen.getByTestId('chunk-card-list')
|
||||
let chunkInfo = JSON.parse(chunkList.getAttribute('data-chunk-info') || '[]')
|
||||
expect(chunkInfo).toEqual(['Original'])
|
||||
expect(chunkInfo).toEqual([{ content: 'Original' }])
|
||||
|
||||
// Act - Change outputs
|
||||
const outputs2 = createGeneralChunkOutputs([{ content: 'Updated' }])
|
||||
|
|
@ -829,7 +835,7 @@ describe('ResultPreview', () => {
|
|||
// Assert
|
||||
chunkList = screen.getByTestId('chunk-card-list')
|
||||
chunkInfo = JSON.parse(chunkList.getAttribute('data-chunk-info') || '[]')
|
||||
expect(chunkInfo).toEqual(['Updated'])
|
||||
expect(chunkInfo).toEqual([{ content: 'Updated' }])
|
||||
})
|
||||
|
||||
it('should handle undefined outputs in useMemo', () => {
|
||||
|
|
|
|||
|
|
@ -5,13 +5,17 @@ import { ChunkingMode } from '@/models/datasets'
|
|||
|
||||
type GeneralChunkPreview = {
|
||||
content: string
|
||||
summary?: string
|
||||
}
|
||||
|
||||
const formatGeneralChunks = (outputs: any) => {
|
||||
const chunkInfo: GeneralChunks = []
|
||||
const chunks = outputs.preview as GeneralChunkPreview[]
|
||||
chunks.slice(0, RAG_PIPELINE_PREVIEW_CHUNK_NUM).forEach((chunk) => {
|
||||
chunkInfo.push(chunk.content)
|
||||
chunkInfo.push({
|
||||
content: chunk.content,
|
||||
summary: chunk.summary,
|
||||
})
|
||||
})
|
||||
|
||||
return chunkInfo
|
||||
|
|
@ -20,6 +24,7 @@ const formatGeneralChunks = (outputs: any) => {
|
|||
type ParentChildChunkPreview = {
|
||||
content: string
|
||||
child_chunks: string[]
|
||||
summary?: string
|
||||
}
|
||||
|
||||
const formatParentChildChunks = (outputs: any, parentMode: ParentMode) => {
|
||||
|
|
@ -32,6 +37,7 @@ const formatParentChildChunks = (outputs: any, parentMode: ParentMode) => {
|
|||
chunks.slice(0, RAG_PIPELINE_PREVIEW_CHUNK_NUM).forEach((chunk) => {
|
||||
chunkInfo.parent_child_chunks?.push({
|
||||
parent_content: chunk.content,
|
||||
parent_summary: chunk.summary,
|
||||
child_contents: chunk.child_chunks,
|
||||
parent_mode: parentMode,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type {
|
||||
KnowledgeBaseNodeType,
|
||||
RerankingModel,
|
||||
SummaryIndexSetting,
|
||||
} from '../types'
|
||||
import type { ValueSelector } from '@/app/components/workflow/types'
|
||||
import { produce } from 'immer'
|
||||
|
|
@ -246,6 +247,16 @@ export const useConfig = (id: string) => {
|
|||
})
|
||||
}, [handleNodeDataUpdate])
|
||||
|
||||
const handleSummaryIndexSettingChange = useCallback((summaryIndexSetting: SummaryIndexSetting) => {
|
||||
const nodeData = getNodeData()
|
||||
handleNodeDataUpdate({
|
||||
summary_index_setting: {
|
||||
...nodeData?.data.summary_index_setting,
|
||||
...summaryIndexSetting,
|
||||
},
|
||||
})
|
||||
}, [handleNodeDataUpdate, getNodeData])
|
||||
|
||||
return {
|
||||
handleChunkStructureChange,
|
||||
handleIndexMethodChange,
|
||||
|
|
@ -260,5 +271,6 @@ export const useConfig = (id: string) => {
|
|||
handleScoreThresholdChange,
|
||||
handleScoreThresholdEnabledChange,
|
||||
handleInputVariableChange,
|
||||
handleSummaryIndexSettingChange,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import {
|
|||
useMemo,
|
||||
} from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import SummaryIndexSetting from '@/app/components/datasets/settings/summary-index-setting'
|
||||
import { checkShowMultiModalTip } from '@/app/components/datasets/settings/utils'
|
||||
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
|
|
@ -51,6 +52,7 @@ const Panel: FC<NodePanelProps<KnowledgeBaseNodeType>> = ({
|
|||
handleScoreThresholdChange,
|
||||
handleScoreThresholdEnabledChange,
|
||||
handleInputVariableChange,
|
||||
handleSummaryIndexSettingChange,
|
||||
} = useConfig(id)
|
||||
|
||||
const filterVar = useCallback((variable: Var) => {
|
||||
|
|
@ -167,6 +169,22 @@ const Panel: FC<NodePanelProps<KnowledgeBaseNodeType>> = ({
|
|||
<div className="pt-1">
|
||||
<Split className="h-[1px]" />
|
||||
</div>
|
||||
{
|
||||
data.indexing_technique === IndexMethodEnum.QUALIFIED
|
||||
&& [ChunkStructureEnum.general, ChunkStructureEnum.parent_child].includes(data.chunk_structure)
|
||||
&& (
|
||||
<>
|
||||
<SummaryIndexSetting
|
||||
summaryIndexSetting={data.summary_index_setting}
|
||||
onSummaryIndexSettingChange={handleSummaryIndexSettingChange}
|
||||
readonly={nodesReadOnly}
|
||||
/>
|
||||
<div className="pt-1">
|
||||
<Split className="h-[1px]" />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
<RetrievalSetting
|
||||
indexMethod={data.indexing_technique}
|
||||
searchMethod={data.retrieval_model.search_method}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,12 @@ export type RetrievalSetting = {
|
|||
score_threshold: number
|
||||
reranking_mode?: RerankingModeEnum
|
||||
}
|
||||
export type SummaryIndexSetting = {
|
||||
enable?: boolean
|
||||
model_name?: string
|
||||
model_provider_name?: string
|
||||
summary_prompt?: string
|
||||
}
|
||||
export type KnowledgeBaseNodeType = CommonNodeType & {
|
||||
index_chunk_variable_selector: string[]
|
||||
chunk_structure?: ChunkStructureEnum
|
||||
|
|
@ -52,4 +58,5 @@ export type KnowledgeBaseNodeType = CommonNodeType & {
|
|||
retrieval_model: RetrievalSetting
|
||||
_embeddingModelList?: Model[]
|
||||
_rerankModelList?: Model[]
|
||||
summary_index_setting?: SummaryIndexSetting
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "إيقاف مؤقت",
|
||||
"list.action.resume": "استئناف",
|
||||
"list.action.settings": "إعدادات التقطيع",
|
||||
"list.action.summary": "إنشاء ملخص",
|
||||
"list.action.sync": "مزامنة",
|
||||
"list.action.unarchive": "إلغاء الأرشفة",
|
||||
"list.action.uploadFile": "تحميل ملف جديد",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "فهرسة",
|
||||
"list.status.paused": "متوقف مؤقتًا",
|
||||
"list.status.queuing": "في الانتظار",
|
||||
"list.summary.generating": "جارٍ الإنشاء...",
|
||||
"list.summary.generatingSummary": "جارٍ إنشاء الملخص",
|
||||
"list.summary.ready": "الملخص جاهز",
|
||||
"list.table.header.action": "إجراء",
|
||||
"list.table.header.chunkingMode": "وضع التقطيع",
|
||||
"list.table.header.fileName": "الاسم",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "نتيجة",
|
||||
"segment.searchResults_other": "نتائج",
|
||||
"segment.searchResults_zero": "نتيجة",
|
||||
"segment.summary": "ملخص",
|
||||
"segment.summaryPlaceholder": "اكتب ملخصًا موجزًا لاسترجاع أفضل…",
|
||||
"segment.vectorHash": "تجزئة المتجه: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "إعدادات الاسترجاع",
|
||||
"form.save": "حفظ",
|
||||
"form.searchModel": "نموذج البحث",
|
||||
"form.summaryAutoGen": "إنشاء الملخص التلقائي",
|
||||
"form.summaryAutoGenEnableTip": "بمجرد التمكين، سيتم إنشاء الملخصات تلقائيًا للمستندات المضافة حديثًا. يمكن لا يزال تلخيص المستندات الموجودة يدويًا.",
|
||||
"form.summaryAutoGenTip": "يتم إنشاء الملخصات تلقائيًا للمستندات المضافة حديثًا. يمكن لا يزال تلخيص المستندات الموجودة يدويًا.",
|
||||
"form.summaryInstructions": "تعليمات",
|
||||
"form.summaryInstructionsPlaceholder": "صف القواعد أو الأسلوب للملخصات المُنشأة تلقائيًا…",
|
||||
"form.summaryModel": "نموذج الملخص",
|
||||
"form.upgradeHighQualityTip": "بمجرد الترقية إلى وضع الجودة العالية، لا يتوفر الرجوع إلى الوضع الاقتصادي",
|
||||
"title": "إعدادات المعرفة"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Pause",
|
||||
"list.action.resume": "Fortsetzen",
|
||||
"list.action.settings": "Segment-Einstellungen",
|
||||
"list.action.summary": "Zusammenfassung generieren",
|
||||
"list.action.sync": "Synchronisieren",
|
||||
"list.action.unarchive": "Archivierung aufheben",
|
||||
"list.action.uploadFile": "Neue Datei hochladen",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Indizierung",
|
||||
"list.status.paused": "Pausiert",
|
||||
"list.status.queuing": "In Warteschlange",
|
||||
"list.summary.generating": "Wird generiert...",
|
||||
"list.summary.generatingSummary": "Zusammenfassung wird generiert",
|
||||
"list.summary.ready": "Zusammenfassung bereit",
|
||||
"list.table.header.action": "AKTION",
|
||||
"list.table.header.chunkingMode": "CHUNKING-MODUS",
|
||||
"list.table.header.fileName": "DATEINAME",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "ERGEBNIS",
|
||||
"segment.searchResults_other": "BEFUND",
|
||||
"segment.searchResults_zero": "ERGEBNIS",
|
||||
"segment.summary": "ZUSAMMENFASSUNG",
|
||||
"segment.summaryPlaceholder": "Schreiben Sie eine kurze Zusammenfassung für bessere Abrufbarkeit…",
|
||||
"segment.vectorHash": "Vektor-Hash: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Einstellungen für den Abruf",
|
||||
"form.save": "Speichern",
|
||||
"form.searchModel": "Modell suchen",
|
||||
"form.summaryAutoGen": "Automatische Zusammenfassungserstellung",
|
||||
"form.summaryAutoGenEnableTip": "Nach der Aktivierung werden Zusammenfassungen automatisch für neu hinzugefügte Dokumente generiert. Vorhandene Dokumente können weiterhin manuell zusammengefasst werden.",
|
||||
"form.summaryAutoGenTip": "Zusammenfassungen werden automatisch für neu hinzugefügte Dokumente generiert. Vorhandene Dokumente können weiterhin manuell zusammengefasst werden.",
|
||||
"form.summaryInstructions": "Anweisungen",
|
||||
"form.summaryInstructionsPlaceholder": "Beschreiben Sie die Regeln oder den Stil für automatisch generierte Zusammenfassungen…",
|
||||
"form.summaryModel": "Zusammenfassungsmodell",
|
||||
"form.upgradeHighQualityTip": "Nach dem Upgrade auf den Modus \"Hohe Qualität\" ist das Zurücksetzen auf den Modus \"Wirtschaftlich\" nicht mehr möglich",
|
||||
"title": "Wissenseinstellungen"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Pause",
|
||||
"list.action.resume": "Resume",
|
||||
"list.action.settings": "Chunking Settings",
|
||||
"list.action.summary": "Generate summary",
|
||||
"list.action.sync": "Sync",
|
||||
"list.action.unarchive": "Unarchive",
|
||||
"list.action.uploadFile": "Upload new file",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Indexing",
|
||||
"list.status.paused": "Paused",
|
||||
"list.status.queuing": "Queuing",
|
||||
"list.summary.generating": "Generating...",
|
||||
"list.summary.generatingSummary": "Generating summary",
|
||||
"list.summary.ready": "Summary ready",
|
||||
"list.table.header.action": "ACTION",
|
||||
"list.table.header.chunkingMode": "CHUNKING MODE",
|
||||
"list.table.header.fileName": "NAME",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "RESULT",
|
||||
"segment.searchResults_other": "RESULTS",
|
||||
"segment.searchResults_zero": "RESULT",
|
||||
"segment.summary": "SUMMARY",
|
||||
"segment.summaryPlaceholder": "Write a brief summary for better retrieval…",
|
||||
"segment.vectorHash": "Vector hash: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Retrieval Settings",
|
||||
"form.save": "Save",
|
||||
"form.searchModel": "Search model",
|
||||
"form.summaryAutoGen": "Summary Auto-Gen",
|
||||
"form.summaryAutoGenEnableTip": "Once enabled, summaries will be generated automatically for newly added documents. Existing documents can still be summarized manually.",
|
||||
"form.summaryAutoGenTip": "Summaries are automatically generated for newly added documents. Existing documents can still be summarized manually.",
|
||||
"form.summaryInstructions": "Instructions",
|
||||
"form.summaryInstructionsPlaceholder": "Describe the rules or style for auto-generated summaries…",
|
||||
"form.summaryModel": "Summary Model",
|
||||
"form.upgradeHighQualityTip": "Once upgrading to High Quality mode, reverting to Economical mode is not available",
|
||||
"title": "Knowledge settings"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Pausa",
|
||||
"list.action.resume": "Reanudar",
|
||||
"list.action.settings": "Configuración de segmento",
|
||||
"list.action.summary": "Generar resumen",
|
||||
"list.action.sync": "Sincronizar",
|
||||
"list.action.unarchive": "Desarchivar",
|
||||
"list.action.uploadFile": "Subir nuevo archivo",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Indexando",
|
||||
"list.status.paused": "Pausado",
|
||||
"list.status.queuing": "En cola",
|
||||
"list.summary.generating": "Generando...",
|
||||
"list.summary.generatingSummary": "Generando resumen",
|
||||
"list.summary.ready": "Resumen listo",
|
||||
"list.table.header.action": "ACCIÓN",
|
||||
"list.table.header.chunkingMode": "MODO DE FRAGMENTACIÓN",
|
||||
"list.table.header.fileName": "NOMBRE DEL ARCHIVO",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "RESULTADO",
|
||||
"segment.searchResults_other": "RESULTADOS",
|
||||
"segment.searchResults_zero": "RESULTADO",
|
||||
"segment.summary": "RESUMEN",
|
||||
"segment.summaryPlaceholder": "Escriba un breve resumen para una mejor recuperación…",
|
||||
"segment.vectorHash": "Hash de vector: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Configuración de recuperación",
|
||||
"form.save": "Guardar",
|
||||
"form.searchModel": "Buscar modelo",
|
||||
"form.summaryAutoGen": "Generación Automática de Resumen",
|
||||
"form.summaryAutoGenEnableTip": "Una vez habilitado, los resúmenes se generarán automáticamente para documentos recién agregados. Los documentos existentes aún se pueden resumir manualmente.",
|
||||
"form.summaryAutoGenTip": "Los resúmenes se generan automáticamente para documentos recién agregados. Los documentos existentes aún se pueden resumir manualmente.",
|
||||
"form.summaryInstructions": "Instrucciones",
|
||||
"form.summaryInstructionsPlaceholder": "Describa las reglas o el estilo para resúmenes generados automáticamente…",
|
||||
"form.summaryModel": "Modelo de Resumen",
|
||||
"form.upgradeHighQualityTip": "Una vez que se actualiza al modo de alta calidad, no está disponible volver al modo económico",
|
||||
"title": "Configuración del conjunto de datos"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "مکث",
|
||||
"list.action.resume": "ادامه",
|
||||
"list.action.settings": "تنظیمات بخشبندی",
|
||||
"list.action.summary": "ایجاد خلاصه",
|
||||
"list.action.sync": "همگامسازی",
|
||||
"list.action.unarchive": "خارج کردن از بایگانی",
|
||||
"list.action.uploadFile": "بارگذاری فایل جدید",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "ایندکسسازی",
|
||||
"list.status.paused": "متوقف شده",
|
||||
"list.status.queuing": "در صف",
|
||||
"list.summary.generating": "در حال ایجاد...",
|
||||
"list.summary.generatingSummary": "در حال ایجاد خلاصه",
|
||||
"list.summary.ready": "خلاصه آماده است",
|
||||
"list.table.header.action": "اقدام",
|
||||
"list.table.header.chunkingMode": "حالت تکه تکه کردن",
|
||||
"list.table.header.fileName": "نام فایل",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "نتیجه",
|
||||
"segment.searchResults_other": "نتیجه",
|
||||
"segment.searchResults_zero": "نتیجه",
|
||||
"segment.summary": "خلاصه",
|
||||
"segment.summaryPlaceholder": "خلاصهای کوتاه برای بازیابی بهتر بنویسید…",
|
||||
"segment.vectorHash": "هش برداری: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "تنظیمات بازیابی",
|
||||
"form.save": "ذخیره",
|
||||
"form.searchModel": "جستجوی مدل",
|
||||
"form.summaryAutoGen": "ایجاد خودکار خلاصه",
|
||||
"form.summaryAutoGenEnableTip": "پس از فعالسازی، خلاصهها بهطور خودکار برای اسناد تازه اضافهشده ایجاد میشوند. اسناد موجود همچنان میتوانند بهصورت دستی خلاصه شوند.",
|
||||
"form.summaryAutoGenTip": "خلاصهها بهطور خودکار برای اسناد تازه اضافهشده ایجاد میشوند. اسناد موجود همچنان میتوانند بهصورت دستی خلاصه شوند.",
|
||||
"form.summaryInstructions": "دستورالعملها",
|
||||
"form.summaryInstructionsPlaceholder": "قوانین یا سبک خلاصههای ایجاد شده خودکار را شرح دهید…",
|
||||
"form.summaryModel": "مدل خلاصه",
|
||||
"form.upgradeHighQualityTip": "پس از ارتقاء به حالت کیفیت بالا، بازگشت به حالت اقتصادی در دسترس نیست",
|
||||
"title": "تنظیمات دانش"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Pause",
|
||||
"list.action.resume": "Reprendre",
|
||||
"list.action.settings": "Paramètres de segment",
|
||||
"list.action.summary": "Générer un résumé",
|
||||
"list.action.sync": "Synchroniser",
|
||||
"list.action.unarchive": "Décompresser",
|
||||
"list.action.uploadFile": "Télécharger un nouveau fichier",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Indexation",
|
||||
"list.status.paused": "En pause",
|
||||
"list.status.queuing": "Mise en file d'attente",
|
||||
"list.summary.generating": "Génération...",
|
||||
"list.summary.generatingSummary": "Génération du résumé",
|
||||
"list.summary.ready": "Résumé prêt",
|
||||
"list.table.header.action": "ACTION",
|
||||
"list.table.header.chunkingMode": "MODE DE MORCEAU",
|
||||
"list.table.header.fileName": "NOM DU FICHIER",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "RÉSULTAT",
|
||||
"segment.searchResults_other": "RÉSULTATS",
|
||||
"segment.searchResults_zero": "RÉSULTAT",
|
||||
"segment.summary": "RÉSUMÉ",
|
||||
"segment.summaryPlaceholder": "Rédigez un bref résumé pour une meilleure récupération…",
|
||||
"segment.vectorHash": "Vector hash: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Paramètres de récupération",
|
||||
"form.save": "Enregistrer",
|
||||
"form.searchModel": "Rechercher un modèle",
|
||||
"form.summaryAutoGen": "Génération Auto de Résumé",
|
||||
"form.summaryAutoGenEnableTip": "Une fois activé, les résumés seront générés automatiquement pour les documents nouvellement ajoutés. Les documents existants peuvent toujours être résumés manuellement.",
|
||||
"form.summaryAutoGenTip": "Les résumés sont générés automatiquement pour les documents nouvellement ajoutés. Les documents existants peuvent toujours être résumés manuellement.",
|
||||
"form.summaryInstructions": "Instructions",
|
||||
"form.summaryInstructionsPlaceholder": "Décrivez les règles ou le style pour les résumés générés automatiquement…",
|
||||
"form.summaryModel": "Modèle de Résumé",
|
||||
"form.upgradeHighQualityTip": "Une fois la mise à niveau vers le mode Haute Qualité, il n’est pas possible de revenir au mode Économique",
|
||||
"title": "Paramètres de connaissance"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "रोकें",
|
||||
"list.action.resume": "रिज़्यूमे",
|
||||
"list.action.settings": "खंड सेटिंग्स",
|
||||
"list.action.summary": "सारांश बनाएं",
|
||||
"list.action.sync": "सिंक्रोनाइज़ करें",
|
||||
"list.action.unarchive": "संग्रह से बाहर करें",
|
||||
"list.action.uploadFile": "नई फाइल अपलोड करें",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "अनुक्रमण",
|
||||
"list.status.paused": "रुका हुआ",
|
||||
"list.status.queuing": "पंक्तिबद्ध",
|
||||
"list.summary.generating": "बना रहे हैं...",
|
||||
"list.summary.generatingSummary": "सारांश बना रहे हैं",
|
||||
"list.summary.ready": "सारांश तैयार है",
|
||||
"list.table.header.action": "क्रिया",
|
||||
"list.table.header.chunkingMode": "चंकिंग मोड",
|
||||
"list.table.header.fileName": "फाइल का नाम",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "परिणाम",
|
||||
"segment.searchResults_other": "परिणाम",
|
||||
"segment.searchResults_zero": "परिणाम",
|
||||
"segment.summary": "सारांश",
|
||||
"segment.summaryPlaceholder": "बेहतर पुनर्प्राप्ति के लिए संक्षिप्त सारांश लिखें…",
|
||||
"segment.vectorHash": "वेक्टर हैश: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "पुनर्प्राप्ति सेटिंग्स",
|
||||
"form.save": "सेवना",
|
||||
"form.searchModel": "मॉडल खोजें",
|
||||
"form.summaryAutoGen": "सारांश स्वतः निर्माण",
|
||||
"form.summaryAutoGenEnableTip": "सक्षम होने पर, नए जोड़े गए दस्तावेज़ों के लिए सारांश स्वचालित रूप से बनाए जाएंगे। मौजूदा दस्तावेज़ों को अभी भी मैन्युअल रूप से सारांशित किया जा सकता है।",
|
||||
"form.summaryAutoGenTip": "नए जोड़े गए दस्तावेज़ों के लिए सारांश स्वचालित रूप से बनाए जाते हैं। मौजूदा दस्तावेज़ों को अभी भी मैन्युअल रूप से सारांशित किया जा सकता है।",
|
||||
"form.summaryInstructions": "निर्देश",
|
||||
"form.summaryInstructionsPlaceholder": "स्वचालित रूप से बनाए गए सारांश के लिए नियम या शैली का वर्णन करें…",
|
||||
"form.summaryModel": "सारांश मॉडल",
|
||||
"form.upgradeHighQualityTip": "एक बार उच्च गुणवत्ता मोड में अपग्रेड करने के बाद, किफायती मोड में वापस जाना उपलब्ध नहीं है",
|
||||
"title": "ज्ञान सेटिंग्ज"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Jeda",
|
||||
"list.action.resume": "Melanjutkan",
|
||||
"list.action.settings": "Pengaturan Chunking",
|
||||
"list.action.summary": "Buat ringkasan",
|
||||
"list.action.sync": "Sync",
|
||||
"list.action.unarchive": "Batalkan arsip",
|
||||
"list.action.uploadFile": "Unggah file baru",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Pengindeksan",
|
||||
"list.status.paused": "Berhenti",
|
||||
"list.status.queuing": "Antrian",
|
||||
"list.summary.generating": "Membuat...",
|
||||
"list.summary.generatingSummary": "Membuat ringkasan",
|
||||
"list.summary.ready": "Ringkasan siap",
|
||||
"list.table.header.action": "PERBUATAN",
|
||||
"list.table.header.chunkingMode": "CHUNKING MODE",
|
||||
"list.table.header.fileName": "NAMA",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "HASIL",
|
||||
"segment.searchResults_other": "HASIL",
|
||||
"segment.searchResults_zero": "HASIL",
|
||||
"segment.summary": "RINGKASAN",
|
||||
"segment.summaryPlaceholder": "Tulis ringkasan singkat untuk pencarian yang lebih baik…",
|
||||
"segment.vectorHash": "Hash vektor:"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Pengaturan Pengambilan",
|
||||
"form.save": "Simpan",
|
||||
"form.searchModel": "Model pencarian",
|
||||
"form.summaryAutoGen": "Pembuatan Ringkasan Otomatis",
|
||||
"form.summaryAutoGenEnableTip": "Setelah diaktifkan, ringkasan akan dibuat secara otomatis untuk dokumen yang baru ditambahkan. Dokumen yang ada masih dapat diringkas secara manual.",
|
||||
"form.summaryAutoGenTip": "Ringkasan dibuat secara otomatis untuk dokumen yang baru ditambahkan. Dokumen yang ada masih dapat diringkas secara manual.",
|
||||
"form.summaryInstructions": "Instruksi",
|
||||
"form.summaryInstructionsPlaceholder": "Jelaskan aturan atau gaya untuk ringkasan yang dibuat secara otomatis…",
|
||||
"form.summaryModel": "Model Ringkasan",
|
||||
"form.upgradeHighQualityTip": "Setelah memutakhirkan ke mode Kualitas Tinggi, kembali ke mode Ekonomis tidak tersedia",
|
||||
"title": "Setelan pengetahuan"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Pausa",
|
||||
"list.action.resume": "Riprendi",
|
||||
"list.action.settings": "Impostazioni segmenti",
|
||||
"list.action.summary": "Genera riepilogo",
|
||||
"list.action.sync": "Sincronizza",
|
||||
"list.action.unarchive": "Disarchivia",
|
||||
"list.action.uploadFile": "Carica nuovo file",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Indicizzazione",
|
||||
"list.status.paused": "In pausa",
|
||||
"list.status.queuing": "In coda",
|
||||
"list.summary.generating": "Generazione...",
|
||||
"list.summary.generatingSummary": "Generazione riepilogo",
|
||||
"list.summary.ready": "Riepilogo pronto",
|
||||
"list.table.header.action": "AZIONE",
|
||||
"list.table.header.chunkingMode": "MODALITÀ DI SUDDIVISIONE IN BLOCCHI",
|
||||
"list.table.header.fileName": "NOME FILE",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "RISULTATO",
|
||||
"segment.searchResults_other": "RISULTATI",
|
||||
"segment.searchResults_zero": "RISULTATO",
|
||||
"segment.summary": "RIEPILOGO",
|
||||
"segment.summaryPlaceholder": "Scrivi un breve riepilogo per un migliore recupero…",
|
||||
"segment.vectorHash": "Hash del vettore: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Impostazioni di recupero",
|
||||
"form.save": "Salva",
|
||||
"form.searchModel": "Cerca modello",
|
||||
"form.summaryAutoGen": "Generazione Automatica Riepilogo",
|
||||
"form.summaryAutoGenEnableTip": "Una volta abilitato, i riepiloghi verranno generati automaticamente per i documenti appena aggiunti. I documenti esistenti possono ancora essere riassunti manualmente.",
|
||||
"form.summaryAutoGenTip": "I riepiloghi vengono generati automaticamente per i documenti appena aggiunti. I documenti esistenti possono ancora essere riassunti manualmente.",
|
||||
"form.summaryInstructions": "Istruzioni",
|
||||
"form.summaryInstructionsPlaceholder": "Descrivi le regole o lo stile per i riepiloghi generati automaticamente…",
|
||||
"form.summaryModel": "Modello di Riepilogo",
|
||||
"form.upgradeHighQualityTip": "Una volta effettuato l'aggiornamento alla modalità Alta qualità, il ripristino della modalità Risparmio non è disponibile",
|
||||
"title": "Impostazioni della Conoscenza"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "一時停止",
|
||||
"list.action.resume": "再開",
|
||||
"list.action.settings": "チャンク設定",
|
||||
"list.action.summary": "要約を生成",
|
||||
"list.action.sync": "同期",
|
||||
"list.action.unarchive": "アーカイブ解除",
|
||||
"list.action.uploadFile": "新しいファイルをアップロード",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "インデックス化中",
|
||||
"list.status.paused": "一時停止中",
|
||||
"list.status.queuing": "キューイング中",
|
||||
"list.summary.generating": "生成中...",
|
||||
"list.summary.generatingSummary": "要約を生成中",
|
||||
"list.summary.ready": "要約が完成しました",
|
||||
"list.table.header.action": "アクション",
|
||||
"list.table.header.chunkingMode": "チャンキングモード",
|
||||
"list.table.header.fileName": "ファイル名",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "検索結果",
|
||||
"segment.searchResults_other": "検索結果",
|
||||
"segment.searchResults_zero": "検索結果",
|
||||
"segment.summary": "要約",
|
||||
"segment.summaryPlaceholder": "より良い検索のために簡潔な要約を記入してください…",
|
||||
"segment.vectorHash": "ベクトルハッシュ:"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "検索設定",
|
||||
"form.save": "保存",
|
||||
"form.searchModel": "検索モデル",
|
||||
"form.summaryAutoGen": "要約自動生成",
|
||||
"form.summaryAutoGenEnableTip": "有効にすると、新しく追加されたドキュメントの要約が自動的に生成されます。既存のドキュメントは引き続き手動で要約できます。",
|
||||
"form.summaryAutoGenTip": "新しく追加されたドキュメントの要約は自動的に生成されます。既存のドキュメントは引き続き手動で要約できます。",
|
||||
"form.summaryInstructions": "指示",
|
||||
"form.summaryInstructionsPlaceholder": "自動生成される要約のルールやスタイルを記述してください…",
|
||||
"form.summaryModel": "要約モデル",
|
||||
"form.upgradeHighQualityTip": "高品質モードにアップグレードすると、経済的モードには戻せません。",
|
||||
"title": "ナレッジベースの設定"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "일시 중지",
|
||||
"list.action.resume": "재개",
|
||||
"list.action.settings": "세그먼트 설정",
|
||||
"list.action.summary": "요약 생성",
|
||||
"list.action.sync": "동기화",
|
||||
"list.action.unarchive": "아카이브 해제",
|
||||
"list.action.uploadFile": "새 파일 업로드",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "색인화 중",
|
||||
"list.status.paused": "일시 중지됨",
|
||||
"list.status.queuing": "대기 중",
|
||||
"list.summary.generating": "생성 중...",
|
||||
"list.summary.generatingSummary": "요약 생성 중",
|
||||
"list.summary.ready": "요약 완료",
|
||||
"list.table.header.action": "동작",
|
||||
"list.table.header.chunkingMode": "청크 모드",
|
||||
"list.table.header.fileName": "파일명",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "결과",
|
||||
"segment.searchResults_other": "결과",
|
||||
"segment.searchResults_zero": "결과",
|
||||
"segment.summary": "요약",
|
||||
"segment.summaryPlaceholder": "더 나은 검색을 위해 간단한 요약을 작성하세요…",
|
||||
"segment.vectorHash": "벡터 해시: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "검색 설정",
|
||||
"form.save": "저장",
|
||||
"form.searchModel": "모델 검색",
|
||||
"form.summaryAutoGen": "요약 자동 생성",
|
||||
"form.summaryAutoGenEnableTip": "활성화하면 새로 추가된 문서에 대해 요약이 자동으로 생성됩니다. 기존 문서는 여전히 수동으로 요약할 수 있습니다.",
|
||||
"form.summaryAutoGenTip": "새로 추가된 문서에 대해 요약이 자동으로 생성됩니다. 기존 문서는 여전히 수동으로 요약할 수 있습니다.",
|
||||
"form.summaryInstructions": "지침",
|
||||
"form.summaryInstructionsPlaceholder": "자동 생성 요약의 규칙이나 스타일을 설명하세요…",
|
||||
"form.summaryModel": "요약 모델",
|
||||
"form.upgradeHighQualityTip": "고품질 모드로 업그레이드한 후에는 경제적 모드로 되돌릴 수 없습니다.",
|
||||
"title": "지식 설정"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Pauza",
|
||||
"list.action.resume": "Wznów",
|
||||
"list.action.settings": "Ustawienia segmentacji",
|
||||
"list.action.summary": "Wygeneruj podsumowanie",
|
||||
"list.action.sync": "Synchronizuj",
|
||||
"list.action.unarchive": "Usuń z archiwum",
|
||||
"list.action.uploadFile": "Wgraj nowy plik",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Indeksowanie",
|
||||
"list.status.paused": "Wstrzymane",
|
||||
"list.status.queuing": "Oczekiwanie",
|
||||
"list.summary.generating": "Generowanie...",
|
||||
"list.summary.generatingSummary": "Generowanie podsumowania",
|
||||
"list.summary.ready": "Podsumowanie gotowe",
|
||||
"list.table.header.action": "AKCJA",
|
||||
"list.table.header.chunkingMode": "TRYB CHUNKINGU",
|
||||
"list.table.header.fileName": "NAZWA PLIKU",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "WYNIK",
|
||||
"segment.searchResults_other": "WYNIKI",
|
||||
"segment.searchResults_zero": "WYNIK",
|
||||
"segment.summary": "PODSUMOWANIE",
|
||||
"segment.summaryPlaceholder": "Napisz krótkie podsumowanie dla lepszego wyszukiwania…",
|
||||
"segment.vectorHash": "Wektor hash: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Ustawienia pobierania",
|
||||
"form.save": "Zapisz",
|
||||
"form.searchModel": "Szukaj modelu",
|
||||
"form.summaryAutoGen": "Automatyczne Generowanie Podsumowania",
|
||||
"form.summaryAutoGenEnableTip": "Po włączeniu podsumowania będą generowane automatycznie dla nowo dodanych dokumentów. Istniejące dokumenty nadal mogą być podsumowywane ręcznie.",
|
||||
"form.summaryAutoGenTip": "Podsumowania są generowane automatycznie dla nowo dodanych dokumentów. Istniejące dokumenty nadal mogą być podsumowywane ręcznie.",
|
||||
"form.summaryInstructions": "Instrukcje",
|
||||
"form.summaryInstructionsPlaceholder": "Opisz zasady lub styl dla automatycznie generowanych podsumowań…",
|
||||
"form.summaryModel": "Model Podsumowania",
|
||||
"form.upgradeHighQualityTip": "Po uaktualnieniu do trybu wysokiej jakości powrót do trybu ekonomicznego nie jest dostępny",
|
||||
"title": "Ustawienia wiedzy"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Pausa",
|
||||
"list.action.resume": "Retomar",
|
||||
"list.action.settings": "Configurações de segmento",
|
||||
"list.action.summary": "Gerar resumo",
|
||||
"list.action.sync": "Sincronizar",
|
||||
"list.action.unarchive": "Desarquivar",
|
||||
"list.action.uploadFile": "Enviar novo arquivo",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Indexando",
|
||||
"list.status.paused": "Pausado",
|
||||
"list.status.queuing": "Em fila",
|
||||
"list.summary.generating": "Gerando...",
|
||||
"list.summary.generatingSummary": "Gerando resumo",
|
||||
"list.summary.ready": "Resumo pronto",
|
||||
"list.table.header.action": "AÇÃO",
|
||||
"list.table.header.chunkingMode": "MODO DE FRAGMENTAÇÃO",
|
||||
"list.table.header.fileName": "NOME DO ARQUIVO",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "RESULTADO",
|
||||
"segment.searchResults_other": "RESULTADOS",
|
||||
"segment.searchResults_zero": "RESULTADO",
|
||||
"segment.summary": "RESUMO",
|
||||
"segment.summaryPlaceholder": "Escreva um breve resumo para melhor recuperação…",
|
||||
"segment.vectorHash": "Hash do vetor: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Configurações de recuperação",
|
||||
"form.save": "Salvar",
|
||||
"form.searchModel": "Pesquisar modelo",
|
||||
"form.summaryAutoGen": "Geração Automática de Resumo",
|
||||
"form.summaryAutoGenEnableTip": "Uma vez ativado, resumos serão gerados automaticamente para documentos recém-adicionados. Documentos existentes ainda podem ser resumidos manualmente.",
|
||||
"form.summaryAutoGenTip": "Resumos são gerados automaticamente para documentos recém-adicionados. Documentos existentes ainda podem ser resumidos manualmente.",
|
||||
"form.summaryInstructions": "Instruções",
|
||||
"form.summaryInstructionsPlaceholder": "Descreva as regras ou estilo para resumos gerados automaticamente…",
|
||||
"form.summaryModel": "Modelo de Resumo",
|
||||
"form.upgradeHighQualityTip": "Depois de atualizar para o modo de alta qualidade, reverter para o modo econômico não está disponível",
|
||||
"title": "Configurações do conhecimento"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Pauză",
|
||||
"list.action.resume": "Reia",
|
||||
"list.action.settings": "Setări de segment",
|
||||
"list.action.summary": "Generați rezumat",
|
||||
"list.action.sync": "Sincronizează",
|
||||
"list.action.unarchive": "Dezarhivează",
|
||||
"list.action.uploadFile": "Încarcă un fișier nou",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Indexare",
|
||||
"list.status.paused": "Întrerupt",
|
||||
"list.status.queuing": "În coadă",
|
||||
"list.summary.generating": "Generare...",
|
||||
"list.summary.generatingSummary": "Generare rezumat",
|
||||
"list.summary.ready": "Rezumat gata",
|
||||
"list.table.header.action": "ACȚIUNE",
|
||||
"list.table.header.chunkingMode": "MOD DE FRAGMENTARE",
|
||||
"list.table.header.fileName": "NUMELE FIȘIERULUI",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "REZULTAT",
|
||||
"segment.searchResults_other": "REZULTATELE",
|
||||
"segment.searchResults_zero": "REZULTAT",
|
||||
"segment.summary": "REZUMAT",
|
||||
"segment.summaryPlaceholder": "Scrieți un rezumat scurt pentru o recuperare mai bună…",
|
||||
"segment.vectorHash": "Vector hash: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Setări de recuperare",
|
||||
"form.save": "Salvare",
|
||||
"form.searchModel": "Căutare model",
|
||||
"form.summaryAutoGen": "Generare Automată Rezumat",
|
||||
"form.summaryAutoGenEnableTip": "Odată activat, rezumatele vor fi generate automat pentru documentele nou adăugate. Documentele existente pot fi încă rezumate manual.",
|
||||
"form.summaryAutoGenTip": "Rezumatele sunt generate automat pentru documentele nou adăugate. Documentele existente pot fi încă rezumate manual.",
|
||||
"form.summaryInstructions": "Instrucțiuni",
|
||||
"form.summaryInstructionsPlaceholder": "Descrieți regulile sau stilul pentru rezumatele generate automat…",
|
||||
"form.summaryModel": "Model Rezumat",
|
||||
"form.upgradeHighQualityTip": "După ce faceți upgrade la modul Înaltă calitate, revenirea la modul Economic nu este disponibilă",
|
||||
"title": "Setări de cunoștințe"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Пауза",
|
||||
"list.action.resume": "Возобновить",
|
||||
"list.action.settings": "Настройки сегментации",
|
||||
"list.action.summary": "Создать резюме",
|
||||
"list.action.sync": "Синхронизировать",
|
||||
"list.action.unarchive": "Разархивировать",
|
||||
"list.action.uploadFile": "Загрузить новый файл",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Индексация",
|
||||
"list.status.paused": "Приостановлено",
|
||||
"list.status.queuing": "В очереди",
|
||||
"list.summary.generating": "Создание...",
|
||||
"list.summary.generatingSummary": "Создание резюме",
|
||||
"list.summary.ready": "Резюме готово",
|
||||
"list.table.header.action": "ДЕЙСТВИЕ",
|
||||
"list.table.header.chunkingMode": "РЕЖИМ ДРОБЛЕНИЯ",
|
||||
"list.table.header.fileName": "НАЗВАНИЕ ФАЙЛА",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "РЕЗУЛЬТАТ",
|
||||
"segment.searchResults_other": "РЕЗУЛЬТАТЫ",
|
||||
"segment.searchResults_zero": "РЕЗУЛЬТАТ",
|
||||
"segment.summary": "РЕЗЮМЕ",
|
||||
"segment.summaryPlaceholder": "Напишите краткое резюме для лучшего поиска…",
|
||||
"segment.vectorHash": "Векторный хэш: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Настройки извлечения",
|
||||
"form.save": "Сохранить",
|
||||
"form.searchModel": "Поиск модели",
|
||||
"form.summaryAutoGen": "Автоматическое создание резюме",
|
||||
"form.summaryAutoGenEnableTip": "После включения резюме будут автоматически генерироваться для вновь добавленных документов. Существующие документы по-прежнему можно резюмировать вручную.",
|
||||
"form.summaryAutoGenTip": "Резюме автоматически генерируются для вновь добавленных документов. Существующие документы по-прежнему можно резюмировать вручную.",
|
||||
"form.summaryInstructions": "Инструкции",
|
||||
"form.summaryInstructionsPlaceholder": "Опишите правила или стиль для автоматически сгенерированных резюме…",
|
||||
"form.summaryModel": "Модель резюме",
|
||||
"form.upgradeHighQualityTip": "После обновления до режима «Высокое качество» возврат к экономичному режиму невозможен",
|
||||
"title": "Настройки базы знаний"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Zaustavi",
|
||||
"list.action.resume": "Nadaljuj",
|
||||
"list.action.settings": "Nastavitve segmenta",
|
||||
"list.action.summary": "Ustvari povzetek",
|
||||
"list.action.sync": "Sinhroniziraj",
|
||||
"list.action.unarchive": "Razveljavi arhiviranje",
|
||||
"list.action.uploadFile": "Naloži novo datoteko",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Indeksiranje",
|
||||
"list.status.paused": "Zaustavljeno",
|
||||
"list.status.queuing": "V čakalni vrsti",
|
||||
"list.summary.generating": "Ustvarjanje...",
|
||||
"list.summary.generatingSummary": "Ustvarjanje povzetka",
|
||||
"list.summary.ready": "Povzetek pripravljen",
|
||||
"list.table.header.action": "DEJANJE",
|
||||
"list.table.header.chunkingMode": "NAČIN KOŠČENJA",
|
||||
"list.table.header.fileName": "IME DATOTEKE",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "REZULTAT",
|
||||
"segment.searchResults_other": "REZULTATI",
|
||||
"segment.searchResults_zero": "REZULTAT",
|
||||
"segment.summary": "POVZETEK",
|
||||
"segment.summaryPlaceholder": "Napišite kratek povzetek za boljše iskanje…",
|
||||
"segment.vectorHash": "Vektorski hash: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Nastavitve pridobivanja",
|
||||
"form.save": "Shrani",
|
||||
"form.searchModel": "Išči model",
|
||||
"form.summaryAutoGen": "Samodejna Tvorba Povzetka",
|
||||
"form.summaryAutoGenEnableTip": "Ko je omogočeno, bodo povzetki samodejno ustvarjeni za novo dodane dokumente. Obstoječe dokumente lahko še vedno povzamete ročno.",
|
||||
"form.summaryAutoGenTip": "Povzetki so samodejno ustvarjeni za novo dodane dokumente. Obstoječe dokumente lahko še vedno povzamete ročno.",
|
||||
"form.summaryInstructions": "Navodila",
|
||||
"form.summaryInstructionsPlaceholder": "Opišite pravila ali slog za samodejno ustvarjene povzetke…",
|
||||
"form.summaryModel": "Model Povzetka",
|
||||
"form.upgradeHighQualityTip": "Ko nadgradite na način visoke kakovosti, vrnitev v ekonomični način ni na voljo",
|
||||
"title": "Nastavitve znanja"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "หยุด",
|
||||
"list.action.resume": "ดำเนิน",
|
||||
"list.action.settings": "การตั้งค่ากลุ่ม",
|
||||
"list.action.summary": "สร้างสรุป",
|
||||
"list.action.sync": "ซิงค์",
|
||||
"list.action.unarchive": "ยกเลิกการเก็บถาวร",
|
||||
"list.action.uploadFile": "อัปโหลดไฟล์ใหม่",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "ดัชนี",
|
||||
"list.status.paused": "หยุดชั่วคราว",
|
||||
"list.status.queuing": "จัด คิว",
|
||||
"list.summary.generating": "กำลังสร้าง...",
|
||||
"list.summary.generatingSummary": "กำลังสร้างสรุป",
|
||||
"list.summary.ready": "สรุปพร้อมแล้ว",
|
||||
"list.table.header.action": "การเคลื่อนไหว",
|
||||
"list.table.header.chunkingMode": "โหมดก้อน",
|
||||
"list.table.header.fileName": "ชื่อไฟล์",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "ผล",
|
||||
"segment.searchResults_other": "ผลลัพธ์",
|
||||
"segment.searchResults_zero": "ผล",
|
||||
"segment.summary": "สรุป",
|
||||
"segment.summaryPlaceholder": "เขียนสรุปสั้นๆ เพื่อการค้นหาที่ดีขึ้น…",
|
||||
"segment.vectorHash": "แฮชเวกเตอร์:"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "การตั้งค่าการดึงข้อมูล",
|
||||
"form.save": "ประหยัด",
|
||||
"form.searchModel": "ค้นหารุ่น",
|
||||
"form.summaryAutoGen": "สร้างสรุปอัตโนมัติ",
|
||||
"form.summaryAutoGenEnableTip": "เมื่อเปิดใช้งาน สรุปจะถูกสร้างขึ้นโดยอัตโนมัติสำหรับเอกสารที่เพิ่มใหม่ เอกสารที่มีอยู่ยังคงสามารถสรุปด้วยตนเองได้",
|
||||
"form.summaryAutoGenTip": "สรุปจะถูกสร้างขึ้นโดยอัตโนมัติสำหรับเอกสารที่เพิ่มใหม่ เอกสารที่มีอยู่ยังคงสามารถสรุปด้วยตนเองได้",
|
||||
"form.summaryInstructions": "คำแนะนำ",
|
||||
"form.summaryInstructionsPlaceholder": "อธิบายกฎหรือรูปแบบสำหรับการสรุปที่สร้างขึ้นอัตโนมัติ…",
|
||||
"form.summaryModel": "โมเดลสรุป",
|
||||
"form.upgradeHighQualityTip": "เมื่ออัปเกรดเป็นโหมดคุณภาพสูงแล้ว จะไม่สามารถเปลี่ยนกลับเป็นโหมดประหยัดได้",
|
||||
"title": "การตั้งค่าความรู้"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Duraklat",
|
||||
"list.action.resume": "Devam Et",
|
||||
"list.action.settings": "Segment ayarları",
|
||||
"list.action.summary": "Özet oluştur",
|
||||
"list.action.sync": "Senkronize et",
|
||||
"list.action.unarchive": "Arşivden Çıkar",
|
||||
"list.action.uploadFile": "Yeni dosya yükle",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Dizine Ekleniyor",
|
||||
"list.status.paused": "Durduruldu",
|
||||
"list.status.queuing": "Kuyrukta",
|
||||
"list.summary.generating": "Oluşturuluyor...",
|
||||
"list.summary.generatingSummary": "Özet oluşturuluyor",
|
||||
"list.summary.ready": "Özet hazır",
|
||||
"list.table.header.action": "EYLEM",
|
||||
"list.table.header.chunkingMode": "PARÇALAMA MODU",
|
||||
"list.table.header.fileName": "DOSYA ADI",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "SONUÇ",
|
||||
"segment.searchResults_other": "SONUÇ -LARI",
|
||||
"segment.searchResults_zero": "SONUÇ",
|
||||
"segment.summary": "ÖZET",
|
||||
"segment.summaryPlaceholder": "Daha iyi arama için kısa bir özet yazın…",
|
||||
"segment.vectorHash": "Vektör hash: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Alma Ayarları",
|
||||
"form.save": "Kaydet",
|
||||
"form.searchModel": "Model Ara",
|
||||
"form.summaryAutoGen": "Özet Otomatik Oluşturma",
|
||||
"form.summaryAutoGenEnableTip": "Etkinleştirildiğinde, yeni eklenen belgeler için özetler otomatik olarak oluşturulacaktır. Mevcut belgeler hala manuel olarak özetlenebilir.",
|
||||
"form.summaryAutoGenTip": "Yeni eklenen belgeler için özetler otomatik olarak oluşturulur. Mevcut belgeler hala manuel olarak özetlenebilir.",
|
||||
"form.summaryInstructions": "Talimatlar",
|
||||
"form.summaryInstructionsPlaceholder": "Otomatik oluşturulan özetler için kuralları veya stili açıklayın…",
|
||||
"form.summaryModel": "Özet Modeli",
|
||||
"form.upgradeHighQualityTip": "Yüksek Kalite moduna yükselttikten sonra Ekonomik moda geri dönülemez",
|
||||
"title": "Bilgi ayarları"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Пауза",
|
||||
"list.action.resume": "Продовжити",
|
||||
"list.action.settings": "Налаштування сегмента",
|
||||
"list.action.summary": "Створити резюме",
|
||||
"list.action.sync": "Синхронізувати",
|
||||
"list.action.unarchive": "Розархівувати",
|
||||
"list.action.uploadFile": "Завантажити новий файл",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Індексування",
|
||||
"list.status.paused": "Призупинено",
|
||||
"list.status.queuing": "В черзі",
|
||||
"list.summary.generating": "Створення...",
|
||||
"list.summary.generatingSummary": "Створення резюме",
|
||||
"list.summary.ready": "Резюме готове",
|
||||
"list.table.header.action": "ДІЯ",
|
||||
"list.table.header.chunkingMode": "РЕЖИМ ФРАГМЕНТАЦІЇ",
|
||||
"list.table.header.fileName": "НАЗВА ФАЙЛУ",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "РЕЗУЛЬТАТ",
|
||||
"segment.searchResults_other": "РЕЗУЛЬТАТІВ",
|
||||
"segment.searchResults_zero": "РЕЗУЛЬТАТ",
|
||||
"segment.summary": "РЕЗЮМЕ",
|
||||
"segment.summaryPlaceholder": "Напишіть короткий опис для кращого пошуку…",
|
||||
"segment.vectorHash": "Векторний хеш: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Налаштування отримання",
|
||||
"form.save": "Зберегти",
|
||||
"form.searchModel": "Пошук моделі",
|
||||
"form.summaryAutoGen": "Автоматичне створення резюме",
|
||||
"form.summaryAutoGenEnableTip": "Після увімкнення резюме будуть автоматично генеруватися для нових документів. Існуючі документи все ще можна резюмувати вручну.",
|
||||
"form.summaryAutoGenTip": "Резюме автоматично генеруються для нових документів. Існуючі документи все ще можна резюмувати вручну.",
|
||||
"form.summaryInstructions": "Інструкції",
|
||||
"form.summaryInstructionsPlaceholder": "Опишіть правила або стиль для автоматично згенерованих резюме…",
|
||||
"form.summaryModel": "Модель резюме",
|
||||
"form.upgradeHighQualityTip": "Після оновлення до режиму високої якості повернення до економного режиму недоступне",
|
||||
"title": "Налаштування бази знань"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "Tạm dừng",
|
||||
"list.action.resume": "Tiếp tục",
|
||||
"list.action.settings": "Cài đặt phân đoạn",
|
||||
"list.action.summary": "Tạo tóm tắt",
|
||||
"list.action.sync": "Đồng bộ",
|
||||
"list.action.unarchive": "Khôi phục",
|
||||
"list.action.uploadFile": "Tải lên tệp mới",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "Đang lập chỉ mục",
|
||||
"list.status.paused": "Tạm dừng",
|
||||
"list.status.queuing": "Đang chờ",
|
||||
"list.summary.generating": "Đang tạo...",
|
||||
"list.summary.generatingSummary": "Đang tạo tóm tắt",
|
||||
"list.summary.ready": "Tóm tắt đã sẵn sàng",
|
||||
"list.table.header.action": "THAO TÁC",
|
||||
"list.table.header.chunkingMode": "CHẾ ĐỘ CHUNKING",
|
||||
"list.table.header.fileName": "TÊN TỆP",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "KẾT QUẢ",
|
||||
"segment.searchResults_other": "KẾT QUẢ",
|
||||
"segment.searchResults_zero": "KẾT QUẢ",
|
||||
"segment.summary": "TÓM TẮT",
|
||||
"segment.summaryPlaceholder": "Viết tóm tắt ngắn gọn để tìm kiếm tốt hơn…",
|
||||
"segment.vectorHash": "Mã băm vector: "
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "Cài đặt truy xuất",
|
||||
"form.save": "Lưu",
|
||||
"form.searchModel": "Tìm kiếm mô hình",
|
||||
"form.summaryAutoGen": "Tự động Tạo Tóm tắt",
|
||||
"form.summaryAutoGenEnableTip": "Sau khi bật, tóm tắt sẽ được tạo tự động cho các tài liệu mới được thêm. Các tài liệu hiện có vẫn có thể được tóm tắt thủ công.",
|
||||
"form.summaryAutoGenTip": "Tóm tắt được tạo tự động cho các tài liệu mới được thêm. Các tài liệu hiện có vẫn có thể được tóm tắt thủ công.",
|
||||
"form.summaryInstructions": "Hướng dẫn",
|
||||
"form.summaryInstructionsPlaceholder": "Mô tả các quy tắc hoặc phong cách cho tóm tắt được tạo tự động…",
|
||||
"form.summaryModel": "Mô hình Tóm tắt",
|
||||
"form.upgradeHighQualityTip": "Sau khi nâng cấp lên chế độ Chất lượng cao, không thể hoàn nguyên về chế độ Tiết kiệm",
|
||||
"title": "Cài đặt Kiến thức"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "暂停",
|
||||
"list.action.resume": "恢复",
|
||||
"list.action.settings": "分段设置",
|
||||
"list.action.summary": "生成摘要",
|
||||
"list.action.sync": "同步",
|
||||
"list.action.unarchive": "撤销归档",
|
||||
"list.action.uploadFile": "上传新文件",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "索引中",
|
||||
"list.status.paused": "已暂停",
|
||||
"list.status.queuing": "排队中",
|
||||
"list.summary.generating": "生成中...",
|
||||
"list.summary.generatingSummary": "生成摘要中",
|
||||
"list.summary.ready": "摘要已生成",
|
||||
"list.table.header.action": "操作",
|
||||
"list.table.header.chunkingMode": "分段模式",
|
||||
"list.table.header.fileName": "名称",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "搜索结果",
|
||||
"segment.searchResults_other": "搜索结果",
|
||||
"segment.searchResults_zero": "搜索结果",
|
||||
"segment.summary": "摘要",
|
||||
"segment.summaryPlaceholder": "写一个简短的摘要,以便更好地检索…",
|
||||
"segment.vectorHash": "向量哈希:"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "检索设置",
|
||||
"form.save": "保存",
|
||||
"form.searchModel": "搜索模型",
|
||||
"form.summaryAutoGen": "摘要自动生成",
|
||||
"form.summaryAutoGenEnableTip": "启用后,将自动为新添加的文档生成摘要。已有的文档仍可以手动摘要。",
|
||||
"form.summaryAutoGenTip": "将自动为新添加的文档生成摘要。已有的文档仍可以手动摘要。",
|
||||
"form.summaryInstructions": "指令",
|
||||
"form.summaryInstructionsPlaceholder": "描述自动生成摘要的规则或风格…",
|
||||
"form.summaryModel": "摘要模型",
|
||||
"form.upgradeHighQualityTip": "一旦升级为高质量模式,将无法切换回经济模式。",
|
||||
"title": "知识库设置"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
"list.action.pause": "暫停",
|
||||
"list.action.resume": "恢復",
|
||||
"list.action.settings": "分段設定",
|
||||
"list.action.summary": "產生摘要",
|
||||
"list.action.sync": "同步",
|
||||
"list.action.unarchive": "撤銷歸檔",
|
||||
"list.action.uploadFile": "上傳新檔案",
|
||||
|
|
@ -75,6 +76,9 @@
|
|||
"list.status.indexing": "索引中",
|
||||
"list.status.paused": "已暫停",
|
||||
"list.status.queuing": "排隊中",
|
||||
"list.summary.generating": "產生中...",
|
||||
"list.summary.generatingSummary": "產生摘要中",
|
||||
"list.summary.ready": "摘要已完成",
|
||||
"list.table.header.action": "操作",
|
||||
"list.table.header.chunkingMode": "分塊模式",
|
||||
"list.table.header.fileName": "檔名",
|
||||
|
|
@ -329,5 +333,7 @@
|
|||
"segment.searchResults_one": "結果",
|
||||
"segment.searchResults_other": "結果",
|
||||
"segment.searchResults_zero": "結果",
|
||||
"segment.summary": "摘要",
|
||||
"segment.summaryPlaceholder": "撰寫簡短的摘要以便更好地檢索…",
|
||||
"segment.vectorHash": "向量雜湊:"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,12 @@
|
|||
"form.retrievalSettings": "檢索設置",
|
||||
"form.save": "儲存",
|
||||
"form.searchModel": "搜索模型",
|
||||
"form.summaryAutoGen": "摘要自動產生",
|
||||
"form.summaryAutoGenEnableTip": "啟用後,將自動為新添加的文件產生摘要。現有文件仍可手動摘要。",
|
||||
"form.summaryAutoGenTip": "將自動為新添加的文件產生摘要。現有文件仍可手動摘要。",
|
||||
"form.summaryInstructions": "指令",
|
||||
"form.summaryInstructionsPlaceholder": "描述自動產生摘要的規則或風格…",
|
||||
"form.summaryModel": "摘要模型",
|
||||
"form.upgradeHighQualityTip": "升級到高品質模式后,無法恢復到經濟模式",
|
||||
"title": "知識庫設定"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,13 @@ export type IconInfo = {
|
|||
icon_url?: string
|
||||
}
|
||||
|
||||
export type SummaryIndexSetting = {
|
||||
enable?: boolean
|
||||
model_name?: string
|
||||
model_provider_name?: string
|
||||
summary_prompt?: string
|
||||
}
|
||||
|
||||
export type DataSet = {
|
||||
id: string
|
||||
name: string
|
||||
|
|
@ -88,6 +95,7 @@ export type DataSet = {
|
|||
runtime_mode: 'rag_pipeline' | 'general'
|
||||
enable_api: boolean // Indicates if the service API is enabled
|
||||
is_multimodal: boolean // Indicates if the dataset supports multimodal
|
||||
summary_index_setting?: SummaryIndexSetting
|
||||
}
|
||||
|
||||
export type ExternalAPIItem = {
|
||||
|
|
@ -225,7 +233,7 @@ export type IndexingEstimateResponse = {
|
|||
total_price: number
|
||||
currency: string
|
||||
total_segments: number
|
||||
preview: Array<{ content: string, child_chunks: string[] }>
|
||||
preview: Array<{ content: string, child_chunks: string[], summary?: string }>
|
||||
qa_preview?: QA[]
|
||||
}
|
||||
|
||||
|
|
@ -262,6 +270,7 @@ export type ProcessRuleResponse = {
|
|||
mode: ProcessMode
|
||||
rules: Rules
|
||||
limits: Limits
|
||||
summary_index_setting?: SummaryIndexSetting
|
||||
}
|
||||
|
||||
export type Rules = {
|
||||
|
|
@ -392,6 +401,7 @@ export type InitialDocumentDetail = {
|
|||
total_segments?: number
|
||||
doc_form: ChunkingMode
|
||||
doc_language: string
|
||||
summary_index_status?: string
|
||||
}
|
||||
|
||||
export type SimpleDocumentDetail = InitialDocumentDetail & {
|
||||
|
|
@ -425,6 +435,7 @@ export type DocumentReq = {
|
|||
doc_form: ChunkingMode
|
||||
doc_language: string
|
||||
process_rule: ProcessRule
|
||||
summary_index_setting?: SummaryIndexSetting
|
||||
}
|
||||
|
||||
export type CreateDocumentReq = DocumentReq & {
|
||||
|
|
@ -467,6 +478,7 @@ export type NotionPage = {
|
|||
export type ProcessRule = {
|
||||
mode: ProcessMode
|
||||
rules: Rules
|
||||
summary_index_setting?: SummaryIndexSetting
|
||||
}
|
||||
|
||||
export type createDocumentResponse = {
|
||||
|
|
@ -575,6 +587,7 @@ export type SegmentDetailModel = {
|
|||
error: string | null
|
||||
stopped_at: number
|
||||
answer?: string
|
||||
summary?: string
|
||||
child_chunks?: ChildChunkDetail[]
|
||||
updated_at: number
|
||||
attachments: Attachment[]
|
||||
|
|
@ -618,6 +631,7 @@ export type HitTesting = {
|
|||
tsne_position: TsnePosition
|
||||
child_chunks: HitTestingChildChunk[] | null
|
||||
files: Attachment[]
|
||||
summary?: string
|
||||
}
|
||||
|
||||
export type ExternalKnowledgeBaseHitTesting = {
|
||||
|
|
@ -697,6 +711,7 @@ export type RelatedAppResponse = {
|
|||
export type SegmentUpdater = {
|
||||
content: string
|
||||
answer?: string
|
||||
summary?: string
|
||||
keywords?: string[]
|
||||
regenerate_child_chunks?: boolean
|
||||
attachment_ids?: string[]
|
||||
|
|
@ -778,6 +793,7 @@ export enum DocumentActionType {
|
|||
archive = 'archive',
|
||||
unArchive = 'un_archive',
|
||||
delete = 'delete',
|
||||
summary = 'summary',
|
||||
}
|
||||
|
||||
export type UpdateDocumentBatchParams = {
|
||||
|
|
|
|||
|
|
@ -107,6 +107,18 @@ export const useSyncDocument = () => {
|
|||
})
|
||||
}
|
||||
|
||||
export const useDocumentSummary = () => {
|
||||
return useMutation({
|
||||
mutationFn: ({ datasetId, documentIds, documentId }: UpdateDocumentBatchParams) => {
|
||||
return post<CommonResponse>(`/datasets/${datasetId}/documents/generate-summary`, {
|
||||
body: {
|
||||
document_list: documentId ? [documentId] : documentIds!,
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export const useSyncWebsite = () => {
|
||||
return useMutation({
|
||||
mutationFn: ({ datasetId, documentId }: UpdateDocumentBatchParams) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue