diff --git a/web/src/components/chunk-method-modal/hooks.ts b/web/src/components/chunk-method-modal/hooks.ts index 413309caa0a..788af2ea3d6 100644 --- a/web/src/components/chunk-method-modal/hooks.ts +++ b/web/src/components/chunk-method-modal/hooks.ts @@ -14,25 +14,59 @@ const ParserListMap = new Map([ 'presentation', 'one', 'qa', + 'knowledge_graph', ], ], [ ['doc', 'docx'], - ['naive', 'resume', 'book', 'laws', 'one', 'qa', 'manual'], + [ + 'naive', + 'resume', + 'book', + 'laws', + 'one', + 'qa', + 'manual', + 'knowledge_graph', + ], ], [ ['xlsx', 'xls'], - ['naive', 'qa', 'table', 'one'], + ['naive', 'qa', 'table', 'one', 'knowledge_graph'], ], [['ppt', 'pptx'], ['presentation']], [ ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tif', 'tiff', 'webp', 'svg', 'ico'], ['picture'], ], - [['txt'], ['naive', 'resume', 'book', 'laws', 'one', 'qa', 'table']], - [['csv'], ['naive', 'resume', 'book', 'laws', 'one', 'qa', 'table']], - [['md'], ['naive', 'qa']], - [['json'], ['naive']], + [ + ['txt'], + [ + 'naive', + 'resume', + 'book', + 'laws', + 'one', + 'qa', + 'table', + 'knowledge_graph', + ], + ], + [ + ['csv'], + [ + 'naive', + 'resume', + 'book', + 'laws', + 'one', + 'qa', + 'table', + 'knowledge_graph', + ], + ], + [['md'], ['naive', 'qa', 'knowledge_graph']], + [['json'], ['naive', 'knowledge_graph']], ]); const getParserList = ( diff --git a/web/src/components/chunk-method-modal/index.tsx b/web/src/components/chunk-method-modal/index.tsx index 71aa6ac3079..ce0f2aaf134 100644 --- a/web/src/components/chunk-method-modal/index.tsx +++ b/web/src/components/chunk-method-modal/index.tsx @@ -119,7 +119,7 @@ const ChunkMethodModal: React.FC = ({ - ); - } - const isLongTag = tag.length > 20; - const tagElem = ( - handleClose(tag)} - > - { - if (index !== 0) { - setEditInputIndex(index); - setEditInputValue(tag); - e.preventDefault(); - } - }} - > - {isLongTag ? `${tag.slice(0, 20)}...` : tag} - - - ); - return isLongTag ? ( - - {tagElem} - - ) : ( - tagElem - ); - })} - {inputVisible ? ( - - ) : ( - - 添加关键词 - - )} - - ); -}; - -export default EditTag; diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/constant.ts b/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/constant.ts new file mode 100644 index 00000000000..fc7d3561f8d --- /dev/null +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/constant.ts @@ -0,0 +1,241 @@ +const nodes = [ + { + type: '"ORGANIZATION"', + description: + '"厦门象屿是一家公司,其营业收入和市场占有率在2018年至2022年间有所变化。"', + source_id: '0', + id: '"厦门象屿"', + }, + { + type: '"EVENT"', + description: + '"2018年是一个时间点,标志着厦门象屿营业收入和市场占有率的记录开始。"', + source_id: '0', + entity_type: '"EVENT"', + id: '"2018"', + }, + { + type: '"EVENT"', + description: + '"2019年是一个时间点,厦门象屿的营业收入和市场占有率在此期间有所变化。"', + source_id: '0', + entity_type: '"EVENT"', + id: '"2019"', + }, + { + type: '"EVENT"', + description: + '"2020年是一个时间点,厦门象屿的营业收入和市场占有率在此期间有所变化。"', + source_id: '0', + entity_type: '"EVENT"', + id: '"2020"', + }, + { + type: '"EVENT"', + description: + '"2021年是一个时间点,厦门象屿的营业收入和市场占有率在此期间有所变化。"', + source_id: '0', + entity_type: '"EVENT"', + id: '"2021"', + }, + { + type: '"EVENT"', + description: + '"2022年是一个时间点,厦门象屿的营业收入和市场占有率在此期间有所变化。"', + source_id: '0', + entity_type: '"EVENT"', + id: '"2022"', + }, + { + type: '"ORGANIZATION"', + description: + '"厦门象屿股份有限公司是一家公司,中文简称为厦门象屿,外文名称为Xiamen Xiangyu Co.,Ltd.,外文名称缩写为Xiangyu,法定代表人为邓启东。"', + source_id: '1', + id: '"厦门象屿股份有限公司"', + }, + { + type: '"PERSON"', + description: '"邓启东是厦门象屿股份有限公司的法定代表人。"', + source_id: '1', + entity_type: '"PERSON"', + id: '"邓启东"', + }, + { + type: '"GEO"', + description: '"厦门是一个地理位置,与厦门象屿股份有限公司相关。"', + source_id: '1', + entity_type: '"GEO"', + id: '"厦门"', + }, + { + type: '"PERSON"', + description: + '"廖杰 is the Board Secretary, responsible for handling board-related matters and communications."', + source_id: '2', + id: '"廖杰"', + }, + { + type: '"PERSON"', + description: + '"史经洋 is the Securities Affairs Representative, responsible for handling securities-related matters and communications."', + source_id: '2', + entity_type: '"PERSON"', + id: '"史经洋"', + }, + { + type: '"GEO"', + description: + '"A geographic location in Xiamen, specifically in the Free Trade Zone, where the company\'s office is situated."', + source_id: '2', + entity_type: '"GEO"', + id: '"厦门市湖里区自由贸易试验区厦门片区"', + }, + { + type: '"GEO"', + description: + '"The building where the company\'s office is located, situated at Xiangyu Road, Xiamen."', + source_id: '2', + entity_type: '"GEO"', + id: '"象屿集团大厦"', + }, + { + type: '"EVENT"', + description: + '"Refers to the year 2021, used for comparing financial metrics with the year 2022."', + source_id: '3', + id: '"2021年"', + }, + { + type: '"EVENT"', + description: + '"Refers to the year 2022, used for presenting current financial metrics and comparing them with the year 2021."', + source_id: '3', + entity_type: '"EVENT"', + id: '"2022年"', + }, + { + type: '"EVENT"', + description: + '"Indicates the focus on key financial metrics in the table, such as weighted averages and percentages."', + source_id: '3', + entity_type: '"EVENT"', + id: '"主要财务指标"', + }, +].map(({ type, ...x }) => ({ ...x })); + +const edges = [ + { + weight: 2.0, + description: '"厦门象屿在2018年的营业收入和市场占有率被记录。"', + source_id: '0', + source: '"厦门象屿"', + target: '"2018"', + }, + { + weight: 2.0, + description: '"厦门象屿在2019年的营业收入和市场占有率有所变化。"', + source_id: '0', + source: '"厦门象屿"', + target: '"2019"', + }, + { + weight: 2.0, + description: '"厦门象屿在2020年的营业收入和市场占有率有所变化。"', + source_id: '0', + source: '"厦门象屿"', + target: '"2020"', + }, + { + weight: 2.0, + description: '"厦门象屿在2021年的营业收入和市场占有率有所变化。"', + source_id: '0', + source: '"厦门象屿"', + target: '"2021"', + }, + { + weight: 2.0, + description: '"厦门象屿在2022年的营业收入和市场占有率有所变化。"', + source_id: '0', + source: '"厦门象屿"', + target: '"2022"', + }, + { + weight: 2.0, + description: '"厦门象屿股份有限公司的法定代表人是邓启东。"', + source_id: '1', + source: '"厦门象屿股份有限公司"', + target: '"邓启东"', + }, + { + weight: 2.0, + description: '"厦门象屿股份有限公司位于厦门。"', + source_id: '1', + source: '"厦门象屿股份有限公司"', + target: '"厦门"', + }, + { + weight: 2.0, + description: + '"廖杰\'s office is located in the Xiangyu Group Building, indicating his workplace."', + source_id: '2', + source: '"廖杰"', + target: '"象屿集团大厦"', + }, + { + weight: 2.0, + description: + '"廖杰 works in the Xiamen Free Trade Zone, a specific area within Xiamen."', + source_id: '2', + source: '"廖杰"', + target: '"厦门市湖里区自由贸易试验区厦门片区"', + }, + { + weight: 2.0, + description: + '"史经洋\'s office is also located in the Xiangyu Group Building, indicating his workplace."', + source_id: '2', + source: '"史经洋"', + target: '"象屿集团大厦"', + }, + { + weight: 2.0, + description: + '"史经洋 works in the Xiamen Free Trade Zone, a specific area within Xiamen."', + source_id: '2', + source: '"史经洋"', + target: '"厦门市湖里区自由贸易试验区厦门片区"', + }, + { + weight: 2.0, + description: + '"The years 2021 and 2022 are related as they are used for comparing financial metrics, showing changes and adjustments over time."', + source_id: '3', + source: '"2021年"', + target: '"2022年"', + }, + { + weight: 2.0, + description: + '"The \'主要财务指标\' is related to the year 2021 as it provides the basis for financial comparisons and adjustments."', + source_id: '3', + source: '"2021年"', + target: '"主要财务指标"', + }, + { + weight: 2.0, + description: + '"The \'主要财务指标\' is related to the year 2022 as it presents the current financial metrics and their changes compared to 2021."', + source_id: '3', + source: '"2022年"', + target: '"主要财务指标"', + }, +]; + +export const graphData = { + directed: false, + multigraph: false, + graph: {}, + nodes, + edges, + combos: [], +}; diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/force-graph.tsx b/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/force-graph.tsx new file mode 100644 index 00000000000..c81acd6a2f1 --- /dev/null +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/force-graph.tsx @@ -0,0 +1,123 @@ +import { Graph } from '@antv/g6'; +import { useSize } from 'ahooks'; +import { useCallback, useEffect, useMemo, useRef } from 'react'; +import { graphData } from './constant'; +import { Converter, buildNodesAndCombos, isDataExist } from './util'; + +import { useFetchKnowledgeGraph } from '@/hooks/chunk-hooks'; +import styles from './index.less'; + +const converter = new Converter(); + +const nextData = converter.buildNodesAndCombos( + graphData.nodes, + graphData.edges, +); +console.log('🚀 ~ nextData:', nextData); + +const finalData = { ...graphData, ...nextData }; + +const ForceGraph = () => { + const containerRef = useRef(null); + const size = useSize(containerRef); + const { data } = useFetchKnowledgeGraph(); + + const nextData = useMemo(() => { + if (isDataExist(data)) { + const graphData = data.data; + const mi = buildNodesAndCombos(graphData.nodes); + return { edges: graphData.links, ...mi }; + } + return { nodes: [], edges: [] }; + }, [data]); + console.log('🚀 ~ nextData ~ nextData:', nextData); + + const render = useCallback(() => { + const graph = new Graph({ + container: containerRef.current!, + autoFit: 'view', + behaviors: [ + 'drag-element', + 'drag-canvas', + 'zoom-canvas', + 'collapse-expand', + { + type: 'hover-activate', + degree: 1, // 👈🏻 Activate relations. + }, + ], + plugins: [ + { + type: 'tooltip', + getContent: (e, items) => { + if (items.every((x) => x?.description)) { + let result = ``; + items.forEach((item) => { + result += `

${item?.id}

`; + if (item?.description) { + result += `

${item?.description}

`; + } + }); + return result; + } + return undefined; + }, + }, + ], + layout: { + type: 'combo-combined', + preventOverlap: true, + comboPadding: 1, + spacing: 20, + }, + node: { + style: { + size: 20, + labelText: (d) => d.id, + labelPadding: 30, + // labelOffsetX: 20, + // labelOffsetY: 5, + labelPlacement: 'center', + labelWordWrap: true, + }, + palette: { + type: 'group', + field: (d) => d.combo, + }, + // state: { + // highlight: { + // fill: '#D580FF', + // halo: true, + // lineWidth: 0, + // }, + // dim: { + // fill: '#99ADD1', + // }, + // }, + }, + edge: { + style: (model) => { + const { size, color } = model.data; + return { + stroke: color || '#99ADD1', + lineWidth: size || 1, + }; + }, + }, + }); + + graph.setData(nextData); + + graph.render(); + }, [nextData]); + + useEffect(() => { + if (isDataExist(data)) { + render(); + } + }, [data, render]); + + return
; +}; + +export default ForceGraph; diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/index.less b/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/index.less new file mode 100644 index 00000000000..3616cce4fb2 --- /dev/null +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/index.less @@ -0,0 +1,9 @@ +.forceContainer { + width: 100%; + height: 100%; +} + +.modalContainer { + width: 90vw; + height: 80vh; +} diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/index.tsx b/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/index.tsx new file mode 100644 index 00000000000..facb7d14301 --- /dev/null +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/index.tsx @@ -0,0 +1,5 @@ +const KnowledgeGraph = () => { + return
KnowledgeGraph
; +}; + +export default KnowledgeGraph; diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/modal.tsx b/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/modal.tsx new file mode 100644 index 00000000000..327e3148e2b --- /dev/null +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/modal.tsx @@ -0,0 +1,43 @@ +import { useFetchKnowledgeGraph } from '@/hooks/chunk-hooks'; +import { Modal } from 'antd'; +import React, { useEffect, useState } from 'react'; +import ForceGraph from './force-graph'; + +import styles from './index.less'; + +const KnowledgeGraphModal: React.FC = () => { + const [isModalOpen, setIsModalOpen] = useState(false); + const { data } = useFetchKnowledgeGraph(); + + const handleOk = () => { + setIsModalOpen(false); + }; + + const handleCancel = () => { + setIsModalOpen(false); + }; + + useEffect(() => { + if (data?.data && typeof data?.data !== 'boolean') { + console.log('🚀 ~ useEffect ~ data:', data); + setIsModalOpen(true); + } + }, [setIsModalOpen, data]); + + return ( + +
+ +
+
+ ); +}; + +export default KnowledgeGraphModal; diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/util.ts b/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/util.ts new file mode 100644 index 00000000000..247f18bf01c --- /dev/null +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/components/knowledge-graph/util.ts @@ -0,0 +1,80 @@ +class KeyGenerator { + idx = 0; + chars: string[] = []; + constructor() { + const chars = Array(26) + .fill(1) + .map((x, idx) => String.fromCharCode(97 + idx)); // 26 char + this.chars = chars; + } + generateKey() { + const key = this.chars[this.idx]; + this.idx++; + return key; + } +} + +// Classify nodes based on edge relationships +export class Converter { + keyGenerator; + dict: Record = {}; // key is node id, value is combo + constructor() { + this.keyGenerator = new KeyGenerator(); + } + buildDict(edges: { source: string; target: string }[]) { + edges.forEach((x) => { + if (this.dict[x.source] && !this.dict[x.target]) { + this.dict[x.target] = this.dict[x.source]; + } else if (!this.dict[x.source] && this.dict[x.target]) { + this.dict[x.source] = this.dict[x.target]; + } else if (!this.dict[x.source] && !this.dict[x.target]) { + this.dict[x.source] = this.dict[x.target] = + this.keyGenerator.generateKey(); + } + }); + return this.dict; + } + buildNodesAndCombos(nodes: any[], edges: any[]) { + this.buildDict(edges); + const nextNodes = nodes.map((x) => ({ ...x, combo: this.dict[x.id] })); + + const combos = Object.values(this.dict).reduce((pre, cur) => { + if (pre.every((x) => x.id !== cur)) { + pre.push({ + id: cur, + data: { + label: `Combo ${cur}`, + }, + }); + } + return pre; + }, []); + + return { nodes: nextNodes, combos }; + } +} + +export const isDataExist = (data: any) => { + return data?.data && typeof data?.data !== 'boolean'; +}; + +export const buildNodesAndCombos = (nodes: any[]) => { + const combos: any[] = []; + const nextNodes = nodes.map((x) => { + const combo = Array.isArray(x?.communities) ? x.communities[0] : undefined; + if (combo && combos.every((y) => y.id !== combo)) { + combos.push({ + id: combo, + data: { + label: `Combo ${combo}`, + }, + }); + } + return { + ...x, + combo, + }; + }); + + return { nodes: nextNodes, combos }; +}; diff --git a/web/src/pages/add-knowledge/components/knowledge-chunk/index.tsx b/web/src/pages/add-knowledge/components/knowledge-chunk/index.tsx index 23d8900b14a..37db88da89c 100644 --- a/web/src/pages/add-knowledge/components/knowledge-chunk/index.tsx +++ b/web/src/pages/add-knowledge/components/knowledge-chunk/index.tsx @@ -8,6 +8,7 @@ import ChunkCard from './components/chunk-card'; import CreatingModal from './components/chunk-creating-modal'; import ChunkToolBar from './components/chunk-toolbar'; import DocumentPreview from './components/document-preview/preview'; +import KnowledgeGraphModal from './components/knowledge-graph/modal'; import { useChangeChunkTextMode, useDeleteChunkByIds, @@ -52,7 +53,6 @@ const Chunk = () => { ) => { setSelectedChunkIds([]); pagination.onChange?.(page, size); - // getChunkList(); }; const selectAllChunk = useCallback( @@ -110,16 +110,9 @@ const Chunk = () => { doc_id: documentId, }); if (!chunkIds && resCode === 0) { - // getChunkList(); } }, - [ - switchChunk, - documentId, - // getChunkList, - selectedChunkIds, - showSelectedChunkWarning, - ], + [switchChunk, documentId, selectedChunkIds, showSelectedChunkWarning], ); const { highlights, setWidthAndHeight } = @@ -202,6 +195,7 @@ const Chunk = () => { onOk={onChunkUpdatingOk} /> )} + ); }; diff --git a/web/src/services/knowledge-service.ts b/web/src/services/knowledge-service.ts index dffd5528621..c9b199d0c27 100644 --- a/web/src/services/knowledge-service.ts +++ b/web/src/services/knowledge-service.ts @@ -27,6 +27,7 @@ const { get_document_file, document_upload, web_crawl, + knowledge_graph, } = api; const methods = { @@ -121,6 +122,10 @@ const methods = { url: retrieval_test, method: 'post', }, + knowledge_graph: { + url: knowledge_graph, + method: 'get', + }, }; const kbService = registerServer(methods, request); diff --git a/web/src/utils/api.ts b/web/src/utils/api.ts index bcd201cad64..53dcc137006 100644 --- a/web/src/utils/api.ts +++ b/web/src/utils/api.ts @@ -1,94 +1,95 @@ -let api_host = `/v1`; - -export { api_host }; - -export default { - // user - login: `${api_host}/user/login`, - logout: `${api_host}/user/logout`, - register: `${api_host}/user/register`, - setting: `${api_host}/user/setting`, - user_info: `${api_host}/user/info`, - tenant_info: `${api_host}/user/tenant_info`, - set_tenant_info: `${api_host}/user/set_tenant_info`, - - // llm model - factories_list: `${api_host}/llm/factories`, - llm_list: `${api_host}/llm/list`, - my_llm: `${api_host}/llm/my_llms`, - set_api_key: `${api_host}/llm/set_api_key`, - add_llm: `${api_host}/llm/add_llm`, - delete_llm: `${api_host}/llm/delete_llm`, - - // knowledge base - kb_list: `${api_host}/kb/list`, - create_kb: `${api_host}/kb/create`, - update_kb: `${api_host}/kb/update`, - rm_kb: `${api_host}/kb/rm`, - get_kb_detail: `${api_host}/kb/detail`, - - // chunk - chunk_list: `${api_host}/chunk/list`, - create_chunk: `${api_host}/chunk/create`, - set_chunk: `${api_host}/chunk/set`, - get_chunk: `${api_host}/chunk/get`, - switch_chunk: `${api_host}/chunk/switch`, - rm_chunk: `${api_host}/chunk/rm`, - retrieval_test: `${api_host}/chunk/retrieval_test`, - - // document - upload: `${api_host}/document/upload`, - get_document_list: `${api_host}/document/list`, - document_change_status: `${api_host}/document/change_status`, - document_rm: `${api_host}/document/rm`, - document_rename: `${api_host}/document/rename`, - document_create: `${api_host}/document/create`, - document_run: `${api_host}/document/run`, - document_change_parser: `${api_host}/document/change_parser`, - document_thumbnails: `${api_host}/document/thumbnails`, - get_document_file: `${api_host}/document/get`, - document_upload: `${api_host}/document/upload`, - web_crawl: `${api_host}/document/web_crawl`, - - // chat - setDialog: `${api_host}/dialog/set`, - getDialog: `${api_host}/dialog/get`, - removeDialog: `${api_host}/dialog/rm`, - listDialog: `${api_host}/dialog/list`, - setConversation: `${api_host}/conversation/set`, - getConversation: `${api_host}/conversation/get`, - listConversation: `${api_host}/conversation/list`, - removeConversation: `${api_host}/conversation/rm`, - completeConversation: `${api_host}/conversation/completion`, - // chat for external - createToken: `${api_host}/api/new_token`, - listToken: `${api_host}/api/token_list`, - removeToken: `${api_host}/api/rm`, - getStats: `${api_host}/api/stats`, - createExternalConversation: `${api_host}/api/new_conversation`, - getExternalConversation: `${api_host}/api/conversation`, - completeExternalConversation: `${api_host}/api/completion`, - - // file manager - listFile: `${api_host}/file/list`, - uploadFile: `${api_host}/file/upload`, - removeFile: `${api_host}/file/rm`, - renameFile: `${api_host}/file/rename`, - getAllParentFolder: `${api_host}/file/all_parent_folder`, - createFolder: `${api_host}/file/create`, - connectFileToKnowledge: `${api_host}/file2document/convert`, - getFile: `${api_host}/file/get`, - - // system - getSystemVersion: `${api_host}/system/version`, - getSystemStatus: `${api_host}/system/status`, - - // flow - listTemplates: `${api_host}/canvas/templates`, - listCanvas: `${api_host}/canvas/list`, - getCanvas: `${api_host}/canvas/get`, - removeCanvas: `${api_host}/canvas/rm`, - setCanvas: `${api_host}/canvas/set`, - resetCanvas: `${api_host}/canvas/reset`, - runCanvas: `${api_host}/canvas/completion`, -}; +let api_host = `/v1`; + +export { api_host }; + +export default { + // user + login: `${api_host}/user/login`, + logout: `${api_host}/user/logout`, + register: `${api_host}/user/register`, + setting: `${api_host}/user/setting`, + user_info: `${api_host}/user/info`, + tenant_info: `${api_host}/user/tenant_info`, + set_tenant_info: `${api_host}/user/set_tenant_info`, + + // llm model + factories_list: `${api_host}/llm/factories`, + llm_list: `${api_host}/llm/list`, + my_llm: `${api_host}/llm/my_llms`, + set_api_key: `${api_host}/llm/set_api_key`, + add_llm: `${api_host}/llm/add_llm`, + delete_llm: `${api_host}/llm/delete_llm`, + + // knowledge base + kb_list: `${api_host}/kb/list`, + create_kb: `${api_host}/kb/create`, + update_kb: `${api_host}/kb/update`, + rm_kb: `${api_host}/kb/rm`, + get_kb_detail: `${api_host}/kb/detail`, + + // chunk + chunk_list: `${api_host}/chunk/list`, + create_chunk: `${api_host}/chunk/create`, + set_chunk: `${api_host}/chunk/set`, + get_chunk: `${api_host}/chunk/get`, + switch_chunk: `${api_host}/chunk/switch`, + rm_chunk: `${api_host}/chunk/rm`, + retrieval_test: `${api_host}/chunk/retrieval_test`, + knowledge_graph: `${api_host}/chunk/knowledge_graph`, + + // document + upload: `${api_host}/document/upload`, + get_document_list: `${api_host}/document/list`, + document_change_status: `${api_host}/document/change_status`, + document_rm: `${api_host}/document/rm`, + document_rename: `${api_host}/document/rename`, + document_create: `${api_host}/document/create`, + document_run: `${api_host}/document/run`, + document_change_parser: `${api_host}/document/change_parser`, + document_thumbnails: `${api_host}/document/thumbnails`, + get_document_file: `${api_host}/document/get`, + document_upload: `${api_host}/document/upload`, + web_crawl: `${api_host}/document/web_crawl`, + + // chat + setDialog: `${api_host}/dialog/set`, + getDialog: `${api_host}/dialog/get`, + removeDialog: `${api_host}/dialog/rm`, + listDialog: `${api_host}/dialog/list`, + setConversation: `${api_host}/conversation/set`, + getConversation: `${api_host}/conversation/get`, + listConversation: `${api_host}/conversation/list`, + removeConversation: `${api_host}/conversation/rm`, + completeConversation: `${api_host}/conversation/completion`, + // chat for external + createToken: `${api_host}/api/new_token`, + listToken: `${api_host}/api/token_list`, + removeToken: `${api_host}/api/rm`, + getStats: `${api_host}/api/stats`, + createExternalConversation: `${api_host}/api/new_conversation`, + getExternalConversation: `${api_host}/api/conversation`, + completeExternalConversation: `${api_host}/api/completion`, + + // file manager + listFile: `${api_host}/file/list`, + uploadFile: `${api_host}/file/upload`, + removeFile: `${api_host}/file/rm`, + renameFile: `${api_host}/file/rename`, + getAllParentFolder: `${api_host}/file/all_parent_folder`, + createFolder: `${api_host}/file/create`, + connectFileToKnowledge: `${api_host}/file2document/convert`, + getFile: `${api_host}/file/get`, + + // system + getSystemVersion: `${api_host}/system/version`, + getSystemStatus: `${api_host}/system/status`, + + // flow + listTemplates: `${api_host}/canvas/templates`, + listCanvas: `${api_host}/canvas/list`, + getCanvas: `${api_host}/canvas/get`, + removeCanvas: `${api_host}/canvas/rm`, + setCanvas: `${api_host}/canvas/set`, + resetCanvas: `${api_host}/canvas/reset`, + runCanvas: `${api_host}/canvas/completion`, +};