parent
ac7091f8d6
commit
30f83f848d
@ -10,6 +10,7 @@ weight: 799
|
||||
## 🚀 新增内容
|
||||
|
||||
1. 商业版支持单团队模式,更好的管理内部成员。
|
||||
2. 知识库分块阅读器。
|
||||
|
||||
## ⚙️ 优化
|
||||
|
||||
|
||||
@ -16,23 +16,23 @@ export const DatasetDataIndexMap: Record<
|
||||
}
|
||||
> = {
|
||||
[DatasetDataIndexTypeEnum.default]: {
|
||||
label: i18nT('dataset:data_index_default'),
|
||||
label: i18nT('common:data_index_default'),
|
||||
color: 'gray'
|
||||
},
|
||||
[DatasetDataIndexTypeEnum.custom]: {
|
||||
label: i18nT('dataset:data_index_custom'),
|
||||
label: i18nT('common:data_index_custom'),
|
||||
color: 'blue'
|
||||
},
|
||||
[DatasetDataIndexTypeEnum.summary]: {
|
||||
label: i18nT('dataset:data_index_summary'),
|
||||
label: i18nT('common:data_index_summary'),
|
||||
color: 'green'
|
||||
},
|
||||
[DatasetDataIndexTypeEnum.question]: {
|
||||
label: i18nT('dataset:data_index_question'),
|
||||
label: i18nT('common:data_index_question'),
|
||||
color: 'red'
|
||||
},
|
||||
[DatasetDataIndexTypeEnum.image]: {
|
||||
label: i18nT('dataset:data_index_image'),
|
||||
label: i18nT('common:data_index_image'),
|
||||
color: 'purple'
|
||||
}
|
||||
};
|
||||
|
||||
@ -74,41 +74,42 @@ export async function saveChat({
|
||||
(node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput
|
||||
)?.inputs;
|
||||
|
||||
await mongoSessionRun(async (session) => {
|
||||
const processedContent = content.map((item) => {
|
||||
if (item.obj === ChatRoleEnum.AI) {
|
||||
const nodeResponse = item[DispatchNodeResponseKeyEnum.nodeResponse];
|
||||
// Format save chat content: Remove quote q/a
|
||||
const processedContent = content.map((item) => {
|
||||
if (item.obj === ChatRoleEnum.AI) {
|
||||
const nodeResponse = item[DispatchNodeResponseKeyEnum.nodeResponse];
|
||||
|
||||
if (nodeResponse) {
|
||||
return {
|
||||
...item,
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: nodeResponse.map((responseItem) => {
|
||||
if (
|
||||
responseItem.moduleType === FlowNodeTypeEnum.datasetSearchNode &&
|
||||
responseItem.quoteList
|
||||
) {
|
||||
return {
|
||||
...item,
|
||||
quoteList: responseItem.quoteList.map((quote: any) => ({
|
||||
id: quote.id,
|
||||
chunkIndex: quote.chunkIndex,
|
||||
datasetId: quote.datasetId,
|
||||
collectionId: quote.collectionId,
|
||||
sourceId: quote.sourceId,
|
||||
sourceName: quote.sourceName,
|
||||
score: quote.score,
|
||||
tokens: quote.tokens
|
||||
}))
|
||||
};
|
||||
}
|
||||
return item;
|
||||
})
|
||||
};
|
||||
}
|
||||
if (nodeResponse) {
|
||||
return {
|
||||
...item,
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: nodeResponse.map((responseItem) => {
|
||||
if (
|
||||
responseItem.moduleType === FlowNodeTypeEnum.datasetSearchNode &&
|
||||
responseItem.quoteList
|
||||
) {
|
||||
return {
|
||||
...responseItem,
|
||||
quoteList: responseItem.quoteList.map((quote: any) => ({
|
||||
id: quote.id,
|
||||
chunkIndex: quote.chunkIndex,
|
||||
datasetId: quote.datasetId,
|
||||
collectionId: quote.collectionId,
|
||||
sourceId: quote.sourceId,
|
||||
sourceName: quote.sourceName,
|
||||
score: quote.score,
|
||||
tokens: quote.tokens
|
||||
}))
|
||||
};
|
||||
}
|
||||
return responseItem;
|
||||
})
|
||||
};
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
return item;
|
||||
});
|
||||
|
||||
await mongoSessionRun(async (session) => {
|
||||
const [{ _id: chatItemIdHuman }, { _id: chatItemIdAi }] = await MongoChatItem.insertMany(
|
||||
processedContent.map((item) => ({
|
||||
chatId,
|
||||
|
||||
@ -98,15 +98,11 @@ try {
|
||||
chunkIndex: 1,
|
||||
updateTime: -1
|
||||
});
|
||||
// FullText tmp full text index
|
||||
// DatasetDataSchema.index({ teamId: 1, datasetId: 1, fullTextToken: 'text' });
|
||||
// Recall vectors after data matching
|
||||
DatasetDataSchema.index({ teamId: 1, datasetId: 1, collectionId: 1, 'indexes.dataId': 1 });
|
||||
DatasetDataSchema.index({ updateTime: 1 });
|
||||
// rebuild data
|
||||
DatasetDataSchema.index({ rebuilding: 1, teamId: 1, datasetId: 1 });
|
||||
|
||||
DatasetDataSchema.index({ initFullText: 1 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" >
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.2703 9.04924C15.2703 10.8968 13.8022 12.4015 11.9689 12.4602V12.462H11.7009C11.3327 12.462 11.0342 12.1635 11.0342 11.7953C11.0342 11.4271 11.3327 11.1287 11.7009 11.1287H11.8689C13.0121 11.1226 13.937 10.1939 13.937 9.04924C13.937 8.07583 13.2669 7.25561 12.361 7.03087L11.5956 6.84096L11.3934 6.0787C10.9949 4.57696 9.62484 3.47188 8.00003 3.47188C6.37523 3.47188 5.00513 4.57696 4.60668 6.0787L4.40444 6.84096L3.63901 7.03087C2.73317 7.25561 2.06307 8.07583 2.06307 9.04924C2.06307 10.1977 2.99405 11.1287 4.14248 11.1287L4.14588 11.1286L4.33524 11.1287C4.70343 11.1287 5.00191 11.4271 5.00191 11.7953C5.00191 12.1635 4.70343 12.462 4.33524 12.462H4.14248H4.06858V12.4612C2.2179 12.4219 0.729736 10.9093 0.729736 9.04924C0.729736 7.44874 1.83149 6.10557 3.31794 5.73677C3.86757 3.6652 5.75552 2.13855 8.00003 2.13855C10.2445 2.13855 12.1325 3.6652 12.6821 5.73677C14.1686 6.10557 15.2703 7.44874 15.2703 9.04924ZM8.00002 7.30026C7.63183 7.30026 7.33335 7.59874 7.33335 7.96693V11.8435L6.96682 11.477C6.74816 11.2583 6.39364 11.2583 6.17498 11.477C5.95632 11.6957 5.95632 12.0502 6.17498 12.2688L7.50545 13.5993C7.52049 13.6159 7.53634 13.6318 7.55296 13.6468L7.60322 13.6971C7.82237 13.9162 8.17767 13.9162 8.39682 13.6971L8.44709 13.6468C8.4637 13.6318 8.47955 13.6159 8.49457 13.5993L9.82418 12.2697C10.0433 12.0506 10.0433 11.6953 9.82418 11.4761C9.60503 11.257 9.24973 11.257 9.03058 11.4761L8.66668 11.84V7.96693C8.66668 7.59874 8.36821 7.30026 8.00002 7.30026Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@ -20,6 +20,7 @@
|
||||
"custom_input_guide_url": "Custom Lexicon URL",
|
||||
"dataset_quote_type error": "Knowledge base reference type is wrong, correct type: { datasetId: string }[]",
|
||||
"delete_all_input_guide_confirm": "Are you sure you want to clear the input guide lexicon?",
|
||||
"download_chunks": "Download data",
|
||||
"empty_directory": "This directory is empty~",
|
||||
"file_amount_over": "Exceeded maximum file quantity {{max}}",
|
||||
"file_input": "File input",
|
||||
@ -42,6 +43,7 @@
|
||||
"query_extension_IO_tokens": "Problem Optimization Input/Output Tokens",
|
||||
"query_extension_result": "Problem optimization results",
|
||||
"question_tip": "From top to bottom, the response order of each module",
|
||||
"read_raw_source": "Open the original text",
|
||||
"reasoning_text": "Thinking process",
|
||||
"response.child total points": "Sub-workflow point consumption",
|
||||
"response.dataset_concat_length": "Combined total",
|
||||
@ -52,6 +54,7 @@
|
||||
"select_img": "Upload Image",
|
||||
"source_cronJob": "Scheduled execution",
|
||||
"stream_output": "Stream Output",
|
||||
"to_dataset": "Go to the Knowledge Base",
|
||||
"unsupported_file_type": "Unsupported file types",
|
||||
"upload": "Upload",
|
||||
"view_citations": "View References",
|
||||
|
||||
@ -498,12 +498,9 @@
|
||||
"core.dataset.Dataset": "Dataset",
|
||||
"core.dataset.Dataset ID": "Dataset ID",
|
||||
"core.dataset.Delete Confirm": "Confirm to Delete This Dataset? Data Cannot Be Recovered After Deletion, Please Confirm!",
|
||||
"core.dataset.Download the parsed content": "Download the parsed content",
|
||||
"core.dataset.Empty Dataset": "Empty Dataset",
|
||||
"core.dataset.Empty Dataset Tips": "No Dataset Yet, Create One Now!",
|
||||
"core.dataset.Folder placeholder": "This is a Directory",
|
||||
"core.dataset.Get the raw data": "Get the raw data",
|
||||
"core.dataset.Go Dataset": "Go to Dataset",
|
||||
"core.dataset.Intro Placeholder": "This Dataset Has No Introduction Yet",
|
||||
"core.dataset.Manual collection": "Manual Dataset",
|
||||
"core.dataset.My Dataset": "My Dataset",
|
||||
@ -832,6 +829,11 @@
|
||||
"core.workflow.variable": "Variable",
|
||||
"create": "Create",
|
||||
"cron_job_run_app": "Scheduled Task",
|
||||
"data_index_custom": "Custom index",
|
||||
"data_index_default": "Default index",
|
||||
"data_index_image": "Image Index",
|
||||
"data_index_question": "Inferred question index",
|
||||
"data_index_summary": "Summary Index",
|
||||
"dataset.Confirm move the folder": "Confirm to Move to This Directory",
|
||||
"dataset.Confirm to delete the data": "Confirm to Delete This Data?",
|
||||
"dataset.Confirm to delete the file": "Confirm to Delete This File and All Its Data?",
|
||||
|
||||
@ -27,12 +27,7 @@
|
||||
"custom_data_process_params_desc": "Customize data processing rules",
|
||||
"data.ideal_chunk_length": "ideal block length",
|
||||
"data_amount": "{{dataAmount}} Datas, {{indexAmount}} Indexes",
|
||||
"data_index_custom": "Custom index",
|
||||
"data_index_default": "Default index",
|
||||
"data_index_image": "Image Index",
|
||||
"data_index_num": "Index {{index}}",
|
||||
"data_index_question": "Inferred question index",
|
||||
"data_index_summary": "Summary index",
|
||||
"data_process_params": "Params",
|
||||
"data_process_setting": "Processing config",
|
||||
"dataset.Unsupported operation": "dataset.Unsupported operation",
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
"custom_input_guide_url": "自定义词库地址",
|
||||
"dataset_quote_type error": "知识库引用类型错误,正确类型:{ datasetId: string }[]",
|
||||
"delete_all_input_guide_confirm": "确定要清空输入引导词库吗?",
|
||||
"download_chunks": "下载数据",
|
||||
"empty_directory": "这个目录已经没东西可选了~",
|
||||
"file_amount_over": "超出最大文件数量 {{max}}",
|
||||
"file_input": "系统文件",
|
||||
@ -42,6 +43,7 @@
|
||||
"query_extension_IO_tokens": "问题优化输入/输出 Tokens",
|
||||
"query_extension_result": "问题优化结果",
|
||||
"question_tip": "从上到下,为各个模块的响应顺序",
|
||||
"read_raw_source": "打开原文",
|
||||
"reasoning_text": "思考过程",
|
||||
"response.child total points": "子工作流积分消耗",
|
||||
"response.dataset_concat_length": "合并后总数",
|
||||
@ -52,6 +54,7 @@
|
||||
"select_img": "上传图片",
|
||||
"source_cronJob": "定时执行",
|
||||
"stream_output": "流输出",
|
||||
"to_dataset": "前往知识库",
|
||||
"unsupported_file_type": "不支持的文件类型",
|
||||
"upload": "上传",
|
||||
"view_citations": "查看引用",
|
||||
|
||||
@ -501,12 +501,9 @@
|
||||
"core.dataset.Dataset": "知识库",
|
||||
"core.dataset.Dataset ID": "知识库 ID",
|
||||
"core.dataset.Delete Confirm": "确认删除该知识库?删除后数据无法恢复,请确认!",
|
||||
"core.dataset.Download the parsed content": "下载解析内容",
|
||||
"core.dataset.Empty Dataset": "空数据集",
|
||||
"core.dataset.Empty Dataset Tips": "还没有知识库,快去创建一个吧!",
|
||||
"core.dataset.Folder placeholder": "这是一个目录",
|
||||
"core.dataset.Get the raw data": "获取源数据",
|
||||
"core.dataset.Go Dataset": "前往知识库",
|
||||
"core.dataset.Intro Placeholder": "这个知识库还没有介绍~",
|
||||
"core.dataset.Manual collection": "手动数据集",
|
||||
"core.dataset.My Dataset": "我的知识库",
|
||||
@ -836,6 +833,11 @@
|
||||
"core.workflow.variable": "变量",
|
||||
"create": "去创建",
|
||||
"cron_job_run_app": "定时任务",
|
||||
"data_index_custom": "自定义索引",
|
||||
"data_index_default": "默认索引",
|
||||
"data_index_image": "图片索引",
|
||||
"data_index_question": "推测问题索引",
|
||||
"data_index_summary": "摘要索引",
|
||||
"dataset.Confirm move the folder": "确认移动到该目录",
|
||||
"dataset.Confirm to delete the data": "确认删除该数据?",
|
||||
"dataset.Confirm to delete the file": "确认删除该文件及其所有数据?",
|
||||
|
||||
@ -27,12 +27,7 @@
|
||||
"custom_data_process_params_desc": "自定义设置数据处理规则",
|
||||
"data.ideal_chunk_length": "理想分块长度",
|
||||
"data_amount": "{{dataAmount}} 组数据, {{indexAmount}} 组索引",
|
||||
"data_index_custom": "自定义索引",
|
||||
"data_index_default": "默认索引",
|
||||
"data_index_image": "图片索引",
|
||||
"data_index_num": "索引 {{index}}",
|
||||
"data_index_question": "推测问题索引",
|
||||
"data_index_summary": "摘要索引",
|
||||
"data_process_params": "处理参数",
|
||||
"data_process_setting": "数据处理配置",
|
||||
"dataset.Unsupported operation": "操作不支持",
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
"custom_input_guide_url": "自訂詞彙庫網址",
|
||||
"dataset_quote_type error": "知識庫引用類型錯誤,正確類型:{ datasetId: string }[]",
|
||||
"delete_all_input_guide_confirm": "確定要清除輸入導引詞彙庫嗎?",
|
||||
"download_chunks": "下載數據",
|
||||
"empty_directory": "此目錄中已無項目可選~",
|
||||
"file_amount_over": "超出檔案數量上限 {{max}}",
|
||||
"file_input": "檔案輸入",
|
||||
@ -41,6 +42,7 @@
|
||||
"plugins_output": "外掛程式輸出",
|
||||
"query_extension_IO_tokens": "問題優化輸入/輸出 Tokens",
|
||||
"question_tip": "由上至下,各個模組的回應順序",
|
||||
"read_raw_source": "打開原文",
|
||||
"reasoning_text": "思考過程",
|
||||
"response.child total points": "子工作流程點數消耗",
|
||||
"response.dataset_concat_length": "合併總數",
|
||||
@ -51,6 +53,7 @@
|
||||
"select_img": "上傳圖片",
|
||||
"source_cronJob": "定時執行",
|
||||
"stream_output": "串流輸出",
|
||||
"to_dataset": "前往知識庫",
|
||||
"unsupported_file_type": "不支援的檔案類型",
|
||||
"upload": "上傳",
|
||||
"view_citations": "檢視引用",
|
||||
|
||||
@ -497,12 +497,9 @@
|
||||
"core.dataset.Dataset": "知識庫",
|
||||
"core.dataset.Dataset ID": "知識庫 ID",
|
||||
"core.dataset.Delete Confirm": "確認刪除此知識庫?刪除後資料無法復原,請確認!",
|
||||
"core.dataset.Download the parsed content": "下載解析內容",
|
||||
"core.dataset.Empty Dataset": "空資料集",
|
||||
"core.dataset.Empty Dataset Tips": "還沒有知識庫,快來建立一個吧!",
|
||||
"core.dataset.Folder placeholder": "這是一個目錄",
|
||||
"core.dataset.Get the raw data": "獲取源數據",
|
||||
"core.dataset.Go Dataset": "前往知識庫",
|
||||
"core.dataset.Intro Placeholder": "這個知識庫還沒有介紹",
|
||||
"core.dataset.Manual collection": "手動資料集",
|
||||
"core.dataset.My Dataset": "我的知識庫",
|
||||
@ -831,6 +828,11 @@
|
||||
"core.workflow.variable": "變數",
|
||||
"create": "建立",
|
||||
"cron_job_run_app": "排程任務",
|
||||
"data_index_custom": "自定義索引",
|
||||
"data_index_default": "默認索引",
|
||||
"data_index_image": "圖片索引",
|
||||
"data_index_question": "推測問題索引",
|
||||
"data_index_summary": "摘要索引",
|
||||
"dataset.Confirm move the folder": "確認移動到此目錄",
|
||||
"dataset.Confirm to delete the data": "確認刪除此資料?",
|
||||
"dataset.Confirm to delete the file": "確認刪除此檔案及其所有資料?",
|
||||
|
||||
@ -27,12 +27,7 @@
|
||||
"custom_data_process_params_desc": "自訂資料處理規則",
|
||||
"data.ideal_chunk_length": "理想分塊長度",
|
||||
"data_amount": "{{dataAmount}} 組數據, {{indexAmount}} 組索引",
|
||||
"data_index_custom": "自定義索引",
|
||||
"data_index_default": "默認索引",
|
||||
"data_index_image": "圖片索引",
|
||||
"data_index_num": "索引 {{index}}",
|
||||
"data_index_question": "推測問題索引",
|
||||
"data_index_summary": "摘要索引",
|
||||
"data_process_params": "處理參數",
|
||||
"data_process_setting": "資料處理設定",
|
||||
"dataset.Unsupported operation": "操作不支持",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "app",
|
||||
"version": "4.9.0",
|
||||
"version": "4.9.1",
|
||||
"private": false,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@ -9,7 +9,7 @@ interface Props extends BoxProps {
|
||||
|
||||
const SideBar = (e?: Props) => {
|
||||
const {
|
||||
w = ['100%', '0 0 250px', '0 0 270px', '0 0 290px', '0 0 310px'],
|
||||
w = ['100%', '0 0 250px', '0 0 250px', '0 0 270px', '0 0 290px'],
|
||||
children,
|
||||
externalTrigger,
|
||||
...props
|
||||
|
||||
@ -79,10 +79,10 @@ const DetailLogsModal = ({ appId, chatId, onClose }: Props) => {
|
||||
zIndex={3}
|
||||
position={['fixed', 'absolute']}
|
||||
top={[0, '2%']}
|
||||
right={quoteData ? 600 : 0}
|
||||
right={0}
|
||||
h={['100%', '96%']}
|
||||
w={'100%'}
|
||||
maxW={['100%', '600px']}
|
||||
maxW={quoteData ? ['100%', '1080px'] : ['100%', '600px']}
|
||||
bg={'white'}
|
||||
boxShadow={'3px 0 20px rgba(0,0,0,0.2)'}
|
||||
borderRadius={'md'}
|
||||
@ -151,46 +151,49 @@ const DetailLogsModal = ({ appId, chatId, onClose }: Props) => {
|
||||
)}
|
||||
|
||||
{/* Chat container */}
|
||||
<Box pt={2} flex={'1 0 0'} h={0}>
|
||||
{isPlugin ? (
|
||||
<Box h={'100%'} overflow={'auto'}>
|
||||
<Flex pt={2} flex={'1 0 0'} h={0}>
|
||||
<Box flex={'1 0 0'} h={'100%'} overflow={'auto'}>
|
||||
{isPlugin ? (
|
||||
<Box px={5} py={2}>
|
||||
<PluginRunBox appId={appId} chatId={chatId} />
|
||||
</Box>
|
||||
) : (
|
||||
<ChatBox
|
||||
isReady
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
feedbackType={'admin'}
|
||||
showMarkIcon
|
||||
showVoiceIcon={false}
|
||||
chatType="log"
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{quoteData && (
|
||||
<Box
|
||||
flex={'1 0 0'}
|
||||
w={0}
|
||||
mr={4}
|
||||
maxW={'460px'}
|
||||
h={'98%'}
|
||||
bg={'white'}
|
||||
boxShadow={
|
||||
'0px 4px 10px 0px rgba(19, 51, 107, 0.10), 0px 0px 1px 0px rgba(19, 51, 107, 0.10)'
|
||||
}
|
||||
borderRadius={'md'}
|
||||
>
|
||||
<ChatQuoteList
|
||||
chatTime={quoteData.chatTime}
|
||||
rawSearch={quoteData.rawSearch}
|
||||
metadata={quoteData.metadata}
|
||||
onClose={() => setQuoteData(undefined)}
|
||||
/>
|
||||
</Box>
|
||||
) : (
|
||||
<ChatBox
|
||||
isReady
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
feedbackType={'admin'}
|
||||
showMarkIcon
|
||||
showVoiceIcon={false}
|
||||
chatType="log"
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Flex>
|
||||
</MyBox>
|
||||
{quoteData && (
|
||||
<Box
|
||||
w={['full', '588px']}
|
||||
zIndex={300}
|
||||
position={'absolute'}
|
||||
top={5}
|
||||
right={0}
|
||||
h={'95%'}
|
||||
bg={'white'}
|
||||
boxShadow={'3px 0 20px rgba(0,0,0,0.2)'}
|
||||
borderRadius={'md'}
|
||||
>
|
||||
<ChatQuoteList
|
||||
chatTime={quoteData.chatTime}
|
||||
rawSearch={quoteData.rawSearch}
|
||||
metadata={quoteData.metadata}
|
||||
onClose={() => setQuoteData(undefined)}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Box zIndex={2} position={'fixed'} top={0} left={0} bottom={0} right={0} onClick={onClose} />
|
||||
</>
|
||||
);
|
||||
|
||||
@ -51,12 +51,13 @@ const ChatTest = ({ appForm, setRenderEdit }: Props) => {
|
||||
return (
|
||||
<Flex h={'full'} gap={2}>
|
||||
<MyBox
|
||||
flex={'1 0 0'}
|
||||
w={0}
|
||||
isLoading={loading}
|
||||
display={'flex'}
|
||||
position={'relative'}
|
||||
flexDirection={'column'}
|
||||
h={'full'}
|
||||
w={quoteData ? '' : 'full'}
|
||||
py={4}
|
||||
{...cardStyles}
|
||||
boxShadow={'3'}
|
||||
@ -85,7 +86,7 @@ const ChatTest = ({ appForm, setRenderEdit }: Props) => {
|
||||
</Box>
|
||||
</MyBox>
|
||||
{quoteData && (
|
||||
<Box w={['full', '588px']} {...cardStyles} boxShadow={'3'}>
|
||||
<Box flex={'1 0 0'} w={0} maxW={'560px'} {...cardStyles} boxShadow={'3'}>
|
||||
<ChatQuoteList
|
||||
chatTime={quoteData.chatTime}
|
||||
rawSearch={quoteData.rawSearch}
|
||||
|
||||
@ -69,9 +69,9 @@ const ChatTest = ({ isOpen, nodes = [], edges = [], onClose }: Props) => {
|
||||
flexDirection={'column'}
|
||||
position={'absolute'}
|
||||
top={5}
|
||||
right={quoteData ? 600 : 0}
|
||||
right={0}
|
||||
h={isOpen ? '95%' : '0'}
|
||||
w={isOpen ? ['100%', '460px'] : '0'}
|
||||
w={isOpen ? (quoteData ? ['100%', '960px'] : ['100%', '460px']) : '0'}
|
||||
bg={'white'}
|
||||
boxShadow={'3px 0 20px rgba(0,0,0,0.2)'}
|
||||
borderRadius={'md'}
|
||||
@ -144,30 +144,34 @@ const ChatTest = ({ isOpen, nodes = [], edges = [], onClose }: Props) => {
|
||||
</Flex>
|
||||
)}
|
||||
|
||||
<Box flex={'1 0 0'} overflow={'auto'}>
|
||||
<ChatContainer />
|
||||
</Box>
|
||||
<Flex flex={'1 0 0'} alignItems={'end'}>
|
||||
<Box flex={'1 0 0'} h={'100%'} overflow={'auto'}>
|
||||
<ChatContainer />
|
||||
</Box>
|
||||
|
||||
{quoteData && (
|
||||
<Box
|
||||
flex={'1 0 0'}
|
||||
w={0}
|
||||
mr={4}
|
||||
maxW={'440px'}
|
||||
h={'98%'}
|
||||
bg={'white'}
|
||||
boxShadow={
|
||||
'0px 4px 10px 0px rgba(19, 51, 107, 0.10), 0px 0px 1px 0px rgba(19, 51, 107, 0.10)'
|
||||
}
|
||||
borderRadius={'md'}
|
||||
>
|
||||
<ChatQuoteList
|
||||
chatTime={quoteData.chatTime}
|
||||
rawSearch={quoteData.rawSearch}
|
||||
metadata={quoteData.metadata}
|
||||
onClose={() => setQuoteData(undefined)}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</Flex>
|
||||
</MyBox>
|
||||
{quoteData && (
|
||||
<Box
|
||||
w={['full', '588px']}
|
||||
zIndex={300}
|
||||
position={'absolute'}
|
||||
top={5}
|
||||
right={0}
|
||||
h={'95%'}
|
||||
bg={'white'}
|
||||
boxShadow={'3px 0 20px rgba(0,0,0,0.2)'}
|
||||
borderRadius={'md'}
|
||||
>
|
||||
<ChatQuoteList
|
||||
chatTime={quoteData.chatTime}
|
||||
rawSearch={quoteData.rawSearch}
|
||||
metadata={quoteData.metadata}
|
||||
onClose={() => setQuoteData(undefined)}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Box, Button, Flex } from '@chakra-ui/react';
|
||||
import { Box, Button, Flex, HStack } from '@chakra-ui/react';
|
||||
import { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type';
|
||||
import { getSourceNameIcon } from '@fastgpt/global/core/dataset/utils';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
@ -21,6 +21,10 @@ import { DatasetDataListItemType } from '@/global/core/dataset/type';
|
||||
import { metadataType } from '@/web/core/chat/context/chatItemContext';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
import { getCollectionQuote } from '@/web/core/chat/api';
|
||||
import MyIconButton from '@fastgpt/web/components/common/Icon/button';
|
||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||
import { getCollectionSourceAndOpen } from '@/web/core/dataset/hooks/readCollectionSource';
|
||||
|
||||
const CollectionReader = ({
|
||||
rawSearch,
|
||||
@ -105,10 +109,10 @@ const CollectionReader = ({
|
||||
setDatasetDataList([]);
|
||||
}, [collectionId, setDatasetDataList]);
|
||||
|
||||
const { runAsync: handleDownload, loading: downloadLoading } = useRequest2(async () => {
|
||||
const { runAsync: handleDownload } = useRequest2(async () => {
|
||||
await downloadFetch({
|
||||
url: '/api/core/dataset/collection/export',
|
||||
filename: 'parsed_content.md',
|
||||
filename: 'data.csv',
|
||||
body: {
|
||||
collectionId: collectionId,
|
||||
chatTime: chatTime,
|
||||
@ -117,27 +121,11 @@ const CollectionReader = ({
|
||||
});
|
||||
});
|
||||
|
||||
const { runAsync: handleRead, loading: readLoading } = useRequest2(
|
||||
async () => await getCollectionSource({ ...metadata, appId, chatId }),
|
||||
{
|
||||
onSuccess: (res) => {
|
||||
if (!res.value) {
|
||||
throw new Error('No file found');
|
||||
}
|
||||
if (res.value.startsWith('/')) {
|
||||
window.open(`${location.origin}${res.value}`, '_blank');
|
||||
} else {
|
||||
window.open(res.value, '_blank');
|
||||
}
|
||||
},
|
||||
onError: (err) => {
|
||||
toast({
|
||||
title: t(getErrText(err, t('common:error.fileNotFound'))),
|
||||
status: 'error'
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
const handleRead = getCollectionSourceAndOpen({
|
||||
appId,
|
||||
chatId,
|
||||
...metadata
|
||||
});
|
||||
|
||||
const handleNavigate = useCallback(
|
||||
async (targetIndex: number) => {
|
||||
@ -164,77 +152,61 @@ const CollectionReader = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex flexDirection={'column'} h={'full'}>
|
||||
<MyBox display={'flex'} flexDirection={'column'} h={'full'}>
|
||||
{/* title */}
|
||||
<Flex
|
||||
w={'full'}
|
||||
alignItems={'center'}
|
||||
px={5}
|
||||
borderBottom={'1px solid'}
|
||||
borderColor={'myGray.150'}
|
||||
>
|
||||
<Box flex={1} py={4}>
|
||||
<Flex mb={1} alignItems={['flex-start', 'center']} flexDirection={['column', 'row']}>
|
||||
<Flex gap={2} mr={2}>
|
||||
<MyIcon
|
||||
name={getSourceNameIcon({ sourceId, sourceName }) as any}
|
||||
w={['1rem', '1.25rem']}
|
||||
color={'primary.600'}
|
||||
/>
|
||||
<Box
|
||||
maxW={['200px', '300px']}
|
||||
className={'textEllipsis'}
|
||||
wordBreak={'break-all'}
|
||||
color={'myGray.900'}
|
||||
fontWeight={'medium'}
|
||||
>
|
||||
{sourceName || t('common:common.UnKnow Source')}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex gap={3} mt={[2, 0]} alignItems={'center'}>
|
||||
{!!userInfo && permissionData?.permission?.hasReadPer && (
|
||||
<Button
|
||||
variant={'primaryGhost'}
|
||||
size={'xs'}
|
||||
fontSize={'mini'}
|
||||
border={'none'}
|
||||
_hover={{
|
||||
bg: 'primary.100'
|
||||
}}
|
||||
<Box borderBottom={'1px solid'} borderBottomColor={'myGray.150'} px={3} py={2}>
|
||||
{/* name */}
|
||||
<HStack>
|
||||
<Flex alignItems={'center'} flex={'1 0 0'} w={0}>
|
||||
<MyIcon
|
||||
name={getSourceNameIcon({ sourceId, sourceName }) as any}
|
||||
w={['1rem', '1.25rem']}
|
||||
color={'primary.600'}
|
||||
/>
|
||||
<Box
|
||||
ml={1}
|
||||
maxW={['200px', '220px']}
|
||||
className={'textEllipsis'}
|
||||
wordBreak={'break-all'}
|
||||
fontSize={'sm'}
|
||||
color={'myGray.900'}
|
||||
fontWeight={'medium'}
|
||||
>
|
||||
{sourceName || t('common:common.UnKnow Source')}
|
||||
</Box>
|
||||
{!!userInfo && permissionData?.permission?.hasReadPer && (
|
||||
<MyTooltip label={t('chat:to_dataset')}>
|
||||
<MyIconButton
|
||||
ml={3}
|
||||
icon="core/dataset/datasetLight"
|
||||
size="1rem"
|
||||
onClick={() => {
|
||||
router.push(
|
||||
`/dataset/detail?datasetId=${datasetId}¤tTab=dataCard&collectionId=${collectionId}`
|
||||
);
|
||||
}}
|
||||
>
|
||||
{t('common:core.dataset.Go Dataset')}
|
||||
<MyIcon name="common/upperRight" w={4} ml={1} />
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
</MyTooltip>
|
||||
)}
|
||||
<Box ml={1}>
|
||||
<DownloadButton
|
||||
canAccessRawData={true}
|
||||
onDownload={handleDownload}
|
||||
onRead={handleRead}
|
||||
isLoading={downloadLoading || readLoading}
|
||||
/>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Flex>
|
||||
<Box fontSize={'mini'} color={'myGray.500'}>
|
||||
{t('common:core.chat.quote.Quote Tip')}
|
||||
</Box>
|
||||
<MyIconButton
|
||||
icon={'common/closeLight'}
|
||||
size={'1.25rem'}
|
||||
color={'myGray.900'}
|
||||
onClick={onClose}
|
||||
/>
|
||||
</HStack>
|
||||
<Box fontSize={'mini'} color={'myGray.500'}>
|
||||
{t('common:core.chat.quote.Quote Tip')}
|
||||
</Box>
|
||||
<Box
|
||||
cursor={'pointer'}
|
||||
borderRadius={'sm'}
|
||||
p={1}
|
||||
_hover={{
|
||||
bg: 'myGray.100'
|
||||
}}
|
||||
onClick={onClose}
|
||||
>
|
||||
<MyIcon name="common/closeLight" color={'myGray.900'} w={6} />
|
||||
</Box>
|
||||
</Flex>
|
||||
</Box>
|
||||
|
||||
{/* header control */}
|
||||
{datasetDataList.length > 0 && (
|
||||
@ -299,7 +271,7 @@ const CollectionReader = ({
|
||||
{/* quote list */}
|
||||
{loading || datasetDataList.length > 0 ? (
|
||||
<ScrollData flex={'1 0 0'} mt={2} px={5} py={1} isLoading={loading}>
|
||||
<Flex flexDir={'column'} gap={3}>
|
||||
<Flex flexDir={'column'}>
|
||||
{formatedDataList.map((item, index) => (
|
||||
<CollectionQuoteItem
|
||||
key={item._id}
|
||||
@ -338,7 +310,7 @@ const CollectionReader = ({
|
||||
</Box>
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
</MyBox>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -1,18 +1,15 @@
|
||||
import { Button } from '@chakra-ui/react';
|
||||
import MyMenu from '@fastgpt/web/components/common/MyMenu';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import MyIconButton from '@fastgpt/web/components/common/Icon/button';
|
||||
|
||||
const DownloadButton = ({
|
||||
canAccessRawData,
|
||||
onDownload,
|
||||
onRead,
|
||||
isLoading
|
||||
onRead
|
||||
}: {
|
||||
canAccessRawData: boolean;
|
||||
onDownload: () => void;
|
||||
onRead: () => void;
|
||||
isLoading: boolean;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -20,27 +17,17 @@ const DownloadButton = ({
|
||||
return (
|
||||
<MyMenu
|
||||
size={'xs'}
|
||||
Button={
|
||||
<Button
|
||||
variant={'whitePrimary'}
|
||||
size={'xs'}
|
||||
fontSize={'mini'}
|
||||
leftIcon={<MyIcon name={'common/download'} w={'4'} />}
|
||||
isLoading={isLoading}
|
||||
>
|
||||
{t('common:Download')}
|
||||
</Button>
|
||||
}
|
||||
Button={<MyIconButton icon="common/download" size={'1rem'} />}
|
||||
menuList={[
|
||||
{
|
||||
children: [
|
||||
{
|
||||
label: t('common:core.dataset.Download the parsed content'),
|
||||
label: t('chat:download_chunks'),
|
||||
type: 'grayBg',
|
||||
onClick: onDownload
|
||||
},
|
||||
{
|
||||
label: t('common:core.dataset.Get the raw data'),
|
||||
label: t('chat:read_raw_source'),
|
||||
type: 'grayBg',
|
||||
onClick: onRead
|
||||
}
|
||||
@ -51,18 +38,7 @@ const DownloadButton = ({
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant={'whitePrimary'}
|
||||
size={'xs'}
|
||||
fontSize={'mini'}
|
||||
leftIcon={<MyIcon name={'common/download'} w={'4'} />}
|
||||
onClick={onDownload}
|
||||
isLoading={isLoading}
|
||||
>
|
||||
{t('common:Download')}
|
||||
</Button>
|
||||
);
|
||||
return <MyIconButton icon="common/download" size={'1rem'} onClick={onDownload} />;
|
||||
};
|
||||
|
||||
export default DownloadButton;
|
||||
|
||||
@ -13,9 +13,9 @@ const ScoreTag = (score: { primaryScore?: ScoreItemType; secondaryScore: ScoreIt
|
||||
<MyTooltip
|
||||
label={
|
||||
score.secondaryScore.length ? (
|
||||
<Box>
|
||||
<Flex flexDir={'column'} gap={4}>
|
||||
{score.secondaryScore.map((item, i) => (
|
||||
<Box fontSize={'xs'} key={i}>
|
||||
<Box fontSize={'sm'} key={i}>
|
||||
<Flex alignItems={'flex-start'} lineHeight={1.2} mb={1}>
|
||||
<Box
|
||||
px={'5px'}
|
||||
@ -47,7 +47,7 @@ const ScoreTag = (score: { primaryScore?: ScoreItemType; secondaryScore: ScoreIt
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</Flex>
|
||||
) : (
|
||||
t(SearchScoreTypeMap[score.primaryScore.type]?.desc as any)
|
||||
)
|
||||
|
||||
@ -6,6 +6,8 @@ import { ApiRequestProps } from '@fastgpt/service/type/next';
|
||||
import { LinkedListResponse, LinkedPaginationProps } from '@fastgpt/web/common/fetch/type';
|
||||
import { FilterQuery, Types } from 'mongoose';
|
||||
import { dataFieldSelector, processChatTimeFilter } from './getQuote';
|
||||
import { authDatasetCollection } from '@fastgpt/service/support/permission/dataset/auth';
|
||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||
|
||||
export type GetCollectionQuoteProps = LinkedPaginationProps & {
|
||||
chatTime: Date;
|
||||
@ -36,8 +38,8 @@ async function handler(
|
||||
nextId,
|
||||
nextIndex,
|
||||
chatTime,
|
||||
|
||||
isInitialLoad,
|
||||
|
||||
collectionId,
|
||||
chatItemId,
|
||||
appId,
|
||||
@ -48,21 +50,32 @@ async function handler(
|
||||
teamToken,
|
||||
pageSize = 15
|
||||
} = req.body;
|
||||
|
||||
const limitedPageSize = Math.min(pageSize, 30);
|
||||
|
||||
await Promise.all([
|
||||
authChatCrud({
|
||||
try {
|
||||
await authDatasetCollection({
|
||||
req,
|
||||
authToken: true,
|
||||
appId,
|
||||
chatId,
|
||||
shareId,
|
||||
outLinkUid,
|
||||
teamId,
|
||||
teamToken
|
||||
}),
|
||||
authCollectionInChat({ appId, chatId, chatItemId, collectionId })
|
||||
]);
|
||||
authApiKey: true,
|
||||
collectionId: req.body.collectionId,
|
||||
per: ReadPermissionVal
|
||||
});
|
||||
} catch (error) {
|
||||
await Promise.all([
|
||||
authChatCrud({
|
||||
req,
|
||||
authToken: true,
|
||||
appId,
|
||||
chatId,
|
||||
shareId,
|
||||
outLinkUid,
|
||||
teamId,
|
||||
teamToken
|
||||
}),
|
||||
authCollectionInChat({ appId, chatId, chatItemId, collectionId })
|
||||
]);
|
||||
}
|
||||
|
||||
const baseMatch: BaseMatchType = {
|
||||
collectionId,
|
||||
|
||||
@ -71,9 +71,7 @@ async function handler(req: ApiRequestProps<GetQuoteDataProps>): Promise<GetQuot
|
||||
|
||||
export default NextAPI(handler);
|
||||
|
||||
export function processChatTimeFilter(list: DatasetDataSchemaType[], chatTime?: Date) {
|
||||
if (!chatTime) return list;
|
||||
|
||||
export function processChatTimeFilter(list: DatasetDataSchemaType[], chatTime: Date) {
|
||||
return list.map((item) => {
|
||||
if (!item.history) return item;
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ async function handler(req: ApiRequestProps<ExportCollectionBody, {}>, res: Next
|
||||
};
|
||||
|
||||
res.setHeader('Content-Type', 'text/csv; charset=utf-8;');
|
||||
res.setHeader('Content-Disposition', 'attachment; filename=usage.csv; ');
|
||||
res.setHeader('Content-Disposition', 'attachment; filename=data.csv; ');
|
||||
|
||||
const cursor = MongoDatasetData.find(where, 'q a', {
|
||||
...readFromSecondary,
|
||||
@ -54,10 +54,13 @@ async function handler(req: ApiRequestProps<ExportCollectionBody, {}>, res: Next
|
||||
readStream: cursor
|
||||
});
|
||||
|
||||
cursor.on('data', (doc) => {
|
||||
const res = doc.a ? `\n${doc.q}\n${doc.a}` : `\n${doc.q}`;
|
||||
write(`\uFEFFindex,content`);
|
||||
|
||||
write(res);
|
||||
cursor.on('data', (doc) => {
|
||||
const q = doc.q.replace(/"/g, '""') || '';
|
||||
const a = doc.a.replace(/"/g, '""') || '';
|
||||
|
||||
write(`\n"${q}","${a}"`);
|
||||
});
|
||||
|
||||
cursor.on('end', () => {
|
||||
|
||||
@ -168,66 +168,68 @@ const Chat = ({ myApps }: { myApps: AppListItemType[] }) => {
|
||||
<NextHead title={chatBoxData.app.name} icon={chatBoxData.app.avatar}></NextHead>
|
||||
{/* pc show myself apps */}
|
||||
{isPc && (
|
||||
<Box borderRight={theme.borders.base} w={'220px'} flexShrink={0}>
|
||||
<Box borderRight={theme.borders.base} flex={'0 0 220px'}>
|
||||
<SliderApps apps={myApps} activeAppId={appId} />
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<PageContainer
|
||||
isLoading={loading}
|
||||
flex={'1 0 0'}
|
||||
w={0}
|
||||
p={[0, '16px']}
|
||||
pr={quoteData ? '8px !important' : '16px'}
|
||||
position={'relative'}
|
||||
>
|
||||
<Flex h={'100%'} flexDirection={['column', 'row']}>
|
||||
{/* pc always show history. */}
|
||||
{RenderHistorySlider}
|
||||
{/* chat container */}
|
||||
<Flex
|
||||
position={'relative'}
|
||||
h={[0, '100%']}
|
||||
w={['100%', 0]}
|
||||
flex={'1 0 0'}
|
||||
flexDirection={'column'}
|
||||
>
|
||||
{/* header */}
|
||||
<ChatHeader
|
||||
totalRecordsCount={totalRecordsCount}
|
||||
apps={myApps}
|
||||
history={chatRecords}
|
||||
showHistory
|
||||
/>
|
||||
{(!quoteData || isPc) && (
|
||||
<PageContainer
|
||||
isLoading={loading}
|
||||
flex={'1 0 0'}
|
||||
w={0}
|
||||
p={[0, '16px']}
|
||||
position={'relative'}
|
||||
>
|
||||
<Flex h={'100%'} flexDirection={['column', 'row']}>
|
||||
{/* pc always show history. */}
|
||||
{RenderHistorySlider}
|
||||
{/* chat container */}
|
||||
<Flex
|
||||
position={'relative'}
|
||||
h={[0, '100%']}
|
||||
w={['100%', 0]}
|
||||
flex={'1 0 0'}
|
||||
flexDirection={'column'}
|
||||
>
|
||||
{/* header */}
|
||||
<ChatHeader
|
||||
totalRecordsCount={totalRecordsCount}
|
||||
apps={myApps}
|
||||
history={chatRecords}
|
||||
showHistory
|
||||
/>
|
||||
|
||||
{/* chat box */}
|
||||
<Box flex={'1 0 0'} bg={'white'}>
|
||||
{isPlugin ? (
|
||||
<CustomPluginRunBox
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
outLinkAuthData={outLinkAuthData}
|
||||
onNewChat={() => onChangeChatId(getNanoid())}
|
||||
onStartChat={onStartChat}
|
||||
/>
|
||||
) : (
|
||||
<ChatBox
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
outLinkAuthData={outLinkAuthData}
|
||||
showEmptyIntro
|
||||
feedbackType={'user'}
|
||||
onStartChat={onStartChat}
|
||||
chatType={'chat'}
|
||||
isReady={!loading}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
{/* chat box */}
|
||||
<Box flex={'1 0 0'} bg={'white'}>
|
||||
{isPlugin ? (
|
||||
<CustomPluginRunBox
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
outLinkAuthData={outLinkAuthData}
|
||||
onNewChat={() => onChangeChatId(getNanoid())}
|
||||
onStartChat={onStartChat}
|
||||
/>
|
||||
) : (
|
||||
<ChatBox
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
outLinkAuthData={outLinkAuthData}
|
||||
showEmptyIntro
|
||||
feedbackType={'user'}
|
||||
onStartChat={onStartChat}
|
||||
chatType={'chat'}
|
||||
isReady={!loading}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</PageContainer>
|
||||
</PageContainer>
|
||||
)}
|
||||
|
||||
{quoteData && (
|
||||
<PageContainer w={['full', '588px']} insertProps={{ bg: 'white' }}>
|
||||
<PageContainer flex={'1 0 0'} w={0} maxW={'560px'}>
|
||||
<ChatQuoteList
|
||||
chatTime={quoteData.chatTime}
|
||||
rawSearch={quoteData.rawSearch}
|
||||
|
||||
@ -239,73 +239,80 @@ const OutLink = (props: Props) => {
|
||||
}, [isOpenSlider, isPc, onCloseSlider, quoteData, showHistory, t]);
|
||||
|
||||
return (
|
||||
<Box h={'full'} display={quoteData ? 'flex' : ''}>
|
||||
<>
|
||||
<NextHead
|
||||
title={props.appName || data?.app?.name || 'AI'}
|
||||
desc={props.appIntro || data?.app?.intro}
|
||||
icon={props.appAvatar || data?.app?.avatar}
|
||||
/>
|
||||
<PageContainer
|
||||
isLoading={loading}
|
||||
{...(isEmbed
|
||||
? { p: '0 !important', insertProps: { borderRadius: '0', boxShadow: 'none' } }
|
||||
: { p: [0, 5] })}
|
||||
>
|
||||
<Flex h={'100%'} flexDirection={['column', 'row']}>
|
||||
{RenderHistoryList}
|
||||
|
||||
{/* chat container */}
|
||||
<Flex
|
||||
position={'relative'}
|
||||
h={[0, '100%']}
|
||||
w={['100%', 0]}
|
||||
<Flex h={'full'}>
|
||||
{(!quoteData || isPc) && (
|
||||
<PageContainer
|
||||
flex={'1 0 0'}
|
||||
flexDirection={'column'}
|
||||
w={0}
|
||||
isLoading={loading}
|
||||
{...(isEmbed
|
||||
? { p: '0 !important', insertProps: { borderRadius: '0', boxShadow: 'none' } }
|
||||
: { p: [0, 5] })}
|
||||
>
|
||||
{/* header */}
|
||||
{showHead === '1' ? (
|
||||
<ChatHeader
|
||||
history={chatRecords}
|
||||
totalRecordsCount={totalRecordsCount}
|
||||
showHistory={showHistory === '1'}
|
||||
/>
|
||||
) : null}
|
||||
{/* chat box */}
|
||||
<Box flex={1} bg={'white'}>
|
||||
{isPlugin ? (
|
||||
<CustomPluginRunBox
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
outLinkAuthData={outLinkAuthData}
|
||||
onNewChat={() => onChangeChatId(getNanoid())}
|
||||
onStartChat={startChat}
|
||||
/>
|
||||
) : (
|
||||
<ChatBox
|
||||
isReady={!loading}
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
outLinkAuthData={outLinkAuthData}
|
||||
feedbackType={'user'}
|
||||
onStartChat={startChat}
|
||||
chatType="share"
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</PageContainer>
|
||||
{quoteData && (
|
||||
<PageContainer w={['full', '800px']} py={5}>
|
||||
<ChatQuoteList
|
||||
chatTime={quoteData.chatTime}
|
||||
rawSearch={quoteData.rawSearch}
|
||||
metadata={quoteData.metadata}
|
||||
onClose={() => setQuoteData(undefined)}
|
||||
/>
|
||||
</PageContainer>
|
||||
)}
|
||||
</Box>
|
||||
<Flex h={'100%'} flexDirection={['column', 'row']}>
|
||||
{RenderHistoryList}
|
||||
|
||||
{/* chat container */}
|
||||
<Flex
|
||||
position={'relative'}
|
||||
h={[0, '100%']}
|
||||
w={['100%', 0]}
|
||||
flex={'1 0 0'}
|
||||
flexDirection={'column'}
|
||||
>
|
||||
{/* header */}
|
||||
{showHead === '1' ? (
|
||||
<ChatHeader
|
||||
history={chatRecords}
|
||||
totalRecordsCount={totalRecordsCount}
|
||||
showHistory={showHistory === '1'}
|
||||
/>
|
||||
) : null}
|
||||
{/* chat box */}
|
||||
<Box flex={1} bg={'white'}>
|
||||
{isPlugin ? (
|
||||
<CustomPluginRunBox
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
outLinkAuthData={outLinkAuthData}
|
||||
onNewChat={() => onChangeChatId(getNanoid())}
|
||||
onStartChat={startChat}
|
||||
/>
|
||||
) : (
|
||||
<ChatBox
|
||||
isReady={!loading}
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
outLinkAuthData={outLinkAuthData}
|
||||
feedbackType={'user'}
|
||||
onStartChat={startChat}
|
||||
chatType="share"
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</PageContainer>
|
||||
)}
|
||||
|
||||
{quoteData && (
|
||||
<PageContainer flex={'1 0 0'} w={0} maxW={'560px'}>
|
||||
<ChatQuoteList
|
||||
chatTime={quoteData.chatTime}
|
||||
rawSearch={quoteData.rawSearch}
|
||||
metadata={quoteData.metadata}
|
||||
onClose={() => setQuoteData(undefined)}
|
||||
/>
|
||||
</PageContainer>
|
||||
)}
|
||||
</Flex>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -191,52 +191,59 @@ const Chat = ({ myApps }: { myApps: AppListItemType[] }) => {
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<PageContainer isLoading={loading} flex={'1 0 0'} w={0} p={[0, '16px']} position={'relative'}>
|
||||
<Flex h={'100%'} flexDirection={['column', 'row']} bg={'white'}>
|
||||
{RenderHistoryList}
|
||||
{/* chat container */}
|
||||
<Flex
|
||||
position={'relative'}
|
||||
h={[0, '100%']}
|
||||
w={['100%', 0]}
|
||||
flex={'1 0 0'}
|
||||
flexDirection={'column'}
|
||||
>
|
||||
{/* header */}
|
||||
<ChatHeader
|
||||
totalRecordsCount={totalRecordsCount}
|
||||
apps={myApps}
|
||||
history={chatRecords}
|
||||
showHistory
|
||||
/>
|
||||
{/* chat box */}
|
||||
<Box flex={1}>
|
||||
{chatBoxData.app.type === AppTypeEnum.plugin ? (
|
||||
<CustomPluginRunBox
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
outLinkAuthData={outLinkAuthData}
|
||||
onNewChat={() => onChangeChatId(getNanoid())}
|
||||
onStartChat={startChat}
|
||||
/>
|
||||
) : (
|
||||
<ChatBox
|
||||
isReady={!loading}
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
outLinkAuthData={outLinkAuthData}
|
||||
feedbackType={'user'}
|
||||
onStartChat={startChat}
|
||||
chatType="team"
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
{(!quoteData || isPc) && (
|
||||
<PageContainer
|
||||
isLoading={loading}
|
||||
flex={'1 0 0'}
|
||||
w={0}
|
||||
p={[0, '16px']}
|
||||
position={'relative'}
|
||||
>
|
||||
<Flex h={'100%'} flexDirection={['column', 'row']} bg={'white'}>
|
||||
{RenderHistoryList}
|
||||
{/* chat container */}
|
||||
<Flex
|
||||
position={'relative'}
|
||||
h={[0, '100%']}
|
||||
w={['100%', 0]}
|
||||
flex={'1 0 0'}
|
||||
flexDirection={'column'}
|
||||
>
|
||||
{/* header */}
|
||||
<ChatHeader
|
||||
totalRecordsCount={totalRecordsCount}
|
||||
apps={myApps}
|
||||
history={chatRecords}
|
||||
showHistory
|
||||
/>
|
||||
{/* chat box */}
|
||||
<Box flex={1}>
|
||||
{chatBoxData.app.type === AppTypeEnum.plugin ? (
|
||||
<CustomPluginRunBox
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
outLinkAuthData={outLinkAuthData}
|
||||
onNewChat={() => onChangeChatId(getNanoid())}
|
||||
onStartChat={startChat}
|
||||
/>
|
||||
) : (
|
||||
<ChatBox
|
||||
isReady={!loading}
|
||||
appId={appId}
|
||||
chatId={chatId}
|
||||
outLinkAuthData={outLinkAuthData}
|
||||
feedbackType={'user'}
|
||||
onStartChat={startChat}
|
||||
chatType="team"
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</PageContainer>
|
||||
|
||||
</PageContainer>
|
||||
)}
|
||||
{quoteData && (
|
||||
<PageContainer w={['full', '800px']} py={5}>
|
||||
<PageContainer flex={'1 0 0'} w={0} maxW={'560px'}>
|
||||
<ChatQuoteList
|
||||
chatTime={quoteData.chatTime}
|
||||
rawSearch={quoteData.rawSearch}
|
||||
|
||||
@ -220,7 +220,11 @@ export async function updateData2Dataset({
|
||||
}
|
||||
}
|
||||
|
||||
// insert vector
|
||||
// 4. Update mongo updateTime(便于脏数据检查器识别)
|
||||
mongoData.updateTime = new Date();
|
||||
await mongoData.save();
|
||||
|
||||
// 5. insert vector
|
||||
const insertResult = await Promise.all(
|
||||
patchResult
|
||||
.filter((item) => item.type === 'create' || item.type === 'update')
|
||||
@ -245,15 +249,16 @@ export async function updateData2Dataset({
|
||||
.filter((item) => item.type !== 'delete')
|
||||
.map((item) => item.index) as DatasetDataIndexItemType[];
|
||||
|
||||
// 6. update mongo data
|
||||
await mongoSessionRun(async (session) => {
|
||||
// update mongo data
|
||||
// Update history
|
||||
mongoData.history =
|
||||
q !== mongoData.q || a !== mongoData.a
|
||||
? [
|
||||
{
|
||||
q: mongoData.q,
|
||||
a: mongoData.a,
|
||||
updateTime: mongoData.updateTime
|
||||
updateTime: new Date()
|
||||
},
|
||||
...(mongoData.history?.slice(0, 9) || [])
|
||||
]
|
||||
@ -283,10 +288,6 @@ export async function updateData2Dataset({
|
||||
}
|
||||
});
|
||||
|
||||
// Update mongo updateTime(便于脏数据检查器识别)
|
||||
mongoData.updateTime = new Date();
|
||||
await mongoData.save();
|
||||
|
||||
return {
|
||||
tokens
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user