mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-27 08:25:07 +00:00
perf: btn color (#423)
This commit is contained in:
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 256 KiB |
Binary file not shown.
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 970 KiB |
@@ -225,9 +225,9 @@ data: [{"moduleName":"KB Search","price":1.2000000000000002,"model":"Embedding-2
|
|||||||
此部分 API 需使用全局通用的 API Key。
|
此部分 API 需使用全局通用的 API Key。
|
||||||
{{% /alert %}}
|
{{% /alert %}}
|
||||||
|
|
||||||
| 如何获取知识库ID(kbId) | 如何获取文件ID(file_id) |
|
| 如何获取知识库ID(datasetId) | 如何获取文件ID(file_id) |
|
||||||
| --------------------- | --------------------- |
|
| --------------------- | --------------------- |
|
||||||
|  |  |
|
|  |  |
|
||||||
|
|
||||||
|
|
||||||
### 知识库添加数据
|
### 知识库添加数据
|
||||||
@@ -241,7 +241,7 @@ curl --location --request POST 'https://fastgpt.run/api/core/dataset/data/pushDa
|
|||||||
--header 'Authorization: Bearer apikey' \
|
--header 'Authorization: Bearer apikey' \
|
||||||
--header 'Content-Type: application/json' \
|
--header 'Content-Type: application/json' \
|
||||||
--data-raw '{
|
--data-raw '{
|
||||||
"kbId": "64663f451ba1676dbdef0499",
|
"collectionId": "64663f451ba1676dbdef0499",
|
||||||
"mode": "index",
|
"mode": "index",
|
||||||
"prompt": "qa 拆分引导词,index 模式下可以忽略",
|
"prompt": "qa 拆分引导词,index 模式下可以忽略",
|
||||||
"billId": "可选。如果有这个值,本次的数据会被聚合到一个订单中,这个值可以重复使用。可以参考 [创建训练订单] 获取该值。",
|
"billId": "可选。如果有这个值,本次的数据会被聚合到一个订单中,这个值可以重复使用。可以参考 [创建训练订单] 获取该值。",
|
||||||
@@ -268,7 +268,7 @@ curl --location --request POST 'https://fastgpt.run/api/core/dataset/data/pushDa
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"kbId": "知识库的ID,可以在知识库详情查看。",
|
"collectionId": "文件的ID,参考上面的第二张图",
|
||||||
"mode": "index | qa ", // index 模式: 直接将 q 转成向量存起来,a 直接入库。qa 模式: 只关注 data 里的 q,将 q 丢给大模型,让其根据 prompt 拆分成 qa 问答对。
|
"mode": "index | qa ", // index 模式: 直接将 q 转成向量存起来,a 直接入库。qa 模式: 只关注 data 里的 q,将 q 丢给大模型,让其根据 prompt 拆分成 qa 问答对。
|
||||||
"prompt": "拆分提示词,需严格按照模板,建议不要传入。",
|
"prompt": "拆分提示词,需严格按照模板,建议不要传入。",
|
||||||
"data": [
|
"data": [
|
||||||
@@ -351,7 +351,7 @@ curl --location --request POST 'https://fastgpt.run/api/core/dataset/searchTest'
|
|||||||
--header 'Authorization: Bearer apiKey' \
|
--header 'Authorization: Bearer apiKey' \
|
||||||
--header 'Content-Type: application/json' \
|
--header 'Content-Type: application/json' \
|
||||||
--data-raw '{
|
--data-raw '{
|
||||||
"kbId": "xxxxx",
|
"datasetId": "知识库的ID",
|
||||||
"text": "导演是谁"
|
"text": "导演是谁"
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
@@ -29,6 +29,10 @@ ALTER EXTENSION vector UPDATE;
|
|||||||
alter system set maintenance_work_mem = '2400MB';
|
alter system set maintenance_work_mem = '2400MB';
|
||||||
select pg_reload_conf();
|
select pg_reload_conf();
|
||||||
|
|
||||||
|
-- 重构数据库索引和排序
|
||||||
|
REINDEX DATABASE postgres;
|
||||||
|
ALTER DATABASE postgres REFRESH COLLATION VERSION;
|
||||||
|
|
||||||
-- 开始构建索引,该索引构建时间非常久,直接点击右上角的叉,退出 Terminal 即可
|
-- 开始构建索引,该索引构建时间非常久,直接点击右上角的叉,退出 Terminal 即可
|
||||||
CREATE INDEX CONCURRENTLY vector_index ON modeldata USING hnsw (vector vector_ip_ops) WITH (m = 16, ef_construction = 64);
|
CREATE INDEX CONCURRENTLY vector_index ON modeldata USING hnsw (vector vector_ip_ops) WITH (m = 16, ef_construction = 64);
|
||||||
-- 可以再次点击一键链接,进入 Terminal,输入下方命令,如果看到 "vector_index" hnsw (vector vector_ip_ops) WITH (m='16', ef_construction='64') 则代表构建完成(注意,后面没有 INVALID)
|
-- 可以再次点击一键链接,进入 Terminal,输入下方命令,如果看到 "vector_index" hnsw (vector vector_ip_ops) WITH (m='16', ef_construction='64') 则代表构建完成(注意,后面没有 INVALID)
|
||||||
|
@@ -32,4 +32,4 @@ curl --location --request POST 'https://{{host}}/api/admin/initv451' \
|
|||||||
|
|
||||||
1. 新增知识库文件夹管理
|
1. 新增知识库文件夹管理
|
||||||
2. 修复了 openai4.x sdk 无法兼容 oneapi 的智谱和阿里的接口。
|
2. 修复了 openai4.x sdk 无法兼容 oneapi 的智谱和阿里的接口。
|
||||||
|
3. 修复部分模块无法触发完成事件
|
@@ -14,9 +14,12 @@
|
|||||||
"UnKnow": "UnKnow",
|
"UnKnow": "UnKnow",
|
||||||
"Warning": "Warning",
|
"Warning": "Warning",
|
||||||
"app": {
|
"app": {
|
||||||
|
"AI Advanced Settings": "Advanced Settings",
|
||||||
"AI Settings": "AI Settings",
|
"AI Settings": "AI Settings",
|
||||||
"Advance App TestTip": "The current application is advanced editing mode \n. If you need to switch to [simple mode], please click the save button on the left",
|
"Advance App TestTip": "The current application is advanced editing mode \n. If you need to switch to [simple mode], please click the save button on the left",
|
||||||
"App Detail": "App Detail",
|
"App Detail": "App Detail",
|
||||||
|
"Basic Settings": "Basic Settings",
|
||||||
|
"Chat Debug": "Chat Debug",
|
||||||
"Chat Logs Tips": "Logs record the app's online, shared, and API(chatId is existing) conversations",
|
"Chat Logs Tips": "Logs record the app's online, shared, and API(chatId is existing) conversations",
|
||||||
"Chat logs": "Chat Logs",
|
"Chat logs": "Chat Logs",
|
||||||
"Confirm Del App Tip": "Confirm to delete the app and all its chats",
|
"Confirm Del App Tip": "Confirm to delete the app and all its chats",
|
||||||
@@ -38,6 +41,7 @@
|
|||||||
"Logs Title": "Title",
|
"Logs Title": "Title",
|
||||||
"Mark Count": "Mark Count",
|
"Mark Count": "Mark Count",
|
||||||
"My Apps": "My Apps",
|
"My Apps": "My Apps",
|
||||||
|
"Open AI Advanced Settings": "Advanced Settings",
|
||||||
"Output Field Settings": "Output Field Settings",
|
"Output Field Settings": "Output Field Settings",
|
||||||
"Paste Config": "Paste Config",
|
"Paste Config": "Paste Config",
|
||||||
"Variable Key Repeat Tip": "Variable Key Repeat",
|
"Variable Key Repeat Tip": "Variable Key Repeat",
|
||||||
@@ -106,6 +110,7 @@
|
|||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"Add": "Add",
|
"Add": "Add",
|
||||||
|
"Choose": "Choose",
|
||||||
"Close": "Clow",
|
"Close": "Clow",
|
||||||
"Collect": "Collect",
|
"Collect": "Collect",
|
||||||
"Confirm Move": "Move here",
|
"Confirm Move": "Move here",
|
||||||
@@ -131,6 +136,7 @@
|
|||||||
"Name is empty": "Name is empty",
|
"Name is empty": "Name is empty",
|
||||||
"Next Step": "Next",
|
"Next Step": "Next",
|
||||||
"Output": "Output",
|
"Output": "Output",
|
||||||
|
"Params": "Params",
|
||||||
"Password inconsistency": "Password inconsistency",
|
"Password inconsistency": "Password inconsistency",
|
||||||
"Rename": "Rename",
|
"Rename": "Rename",
|
||||||
"Rename Failed": "Rename Failed",
|
"Rename Failed": "Rename Failed",
|
||||||
@@ -151,10 +157,30 @@
|
|||||||
"folder": {
|
"folder": {
|
||||||
"Drag Tip": "Click and move",
|
"Drag Tip": "Click and move",
|
||||||
"Move Success": "Move Success",
|
"Move Success": "Move Success",
|
||||||
"No Folder": "No Folder",
|
"No Folder": "There's no subdirectory. Just put it here",
|
||||||
"Root Path": "Root Folder"
|
"Root Path": "Root Folder"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"core": {
|
||||||
|
"ai": {
|
||||||
|
"Model": "Model",
|
||||||
|
"Prompt": "Prompt"
|
||||||
|
},
|
||||||
|
"app": {
|
||||||
|
"Next Step Guide": "Next step guide"
|
||||||
|
},
|
||||||
|
"chat": {
|
||||||
|
"Restart": "Restart"
|
||||||
|
},
|
||||||
|
"dataset": {
|
||||||
|
"Choose Dataset": "Chookse Dataset",
|
||||||
|
"Dataset": "Dataset",
|
||||||
|
"Read Dataset": "Read Dataset",
|
||||||
|
"Search Top K": "Top K",
|
||||||
|
"Set Empty Result Tip": ",Response empty text",
|
||||||
|
"Similarity": "Similarity"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dataset": {
|
"dataset": {
|
||||||
"Chunk Length": "Chunk Length",
|
"Chunk Length": "Chunk Length",
|
||||||
"Confirm move the folder": "Confirm Move",
|
"Confirm move the folder": "Confirm Move",
|
||||||
@@ -189,6 +215,7 @@
|
|||||||
"Click to view folder": "To Folder",
|
"Click to view folder": "To Folder",
|
||||||
"Collection Embedding": "{{total}}Embedding",
|
"Collection Embedding": "{{total}}Embedding",
|
||||||
"Confirm to delete the folder": "Are you sure to delete this folder and all its contents?",
|
"Confirm to delete the folder": "Are you sure to delete this folder and all its contents?",
|
||||||
|
"Create And Import": "Create/Import",
|
||||||
"Create Training Data": "Training-{{filename}}",
|
"Create Training Data": "Training-{{filename}}",
|
||||||
"Create Virtual File Success": "Create Virtual File Success",
|
"Create Virtual File Success": "Create Virtual File Success",
|
||||||
"Data Amount": "Data Amount",
|
"Data Amount": "Data Amount",
|
||||||
@@ -208,7 +235,7 @@
|
|||||||
"deleteFolderTips": "Are you sure to delete this folder and all the knowledge bases it contains? Data cannot be recovered after deletion, please confirm!"
|
"deleteFolderTips": "Are you sure to delete this folder and all the knowledge bases it contains? Data cannot be recovered after deletion, please confirm!"
|
||||||
},
|
},
|
||||||
"file": {
|
"file": {
|
||||||
"Click to download CSV template": "Click to download CSV template",
|
"Click to download file template": "Download Template: {{name}}",
|
||||||
"Click to view file": "Click to view file",
|
"Click to view file": "Click to view file",
|
||||||
"Create File": "Create File",
|
"Create File": "Create File",
|
||||||
"Create file": "Create file",
|
"Create file": "Create file",
|
||||||
|
@@ -14,9 +14,12 @@
|
|||||||
"UnKnow": "未知",
|
"UnKnow": "未知",
|
||||||
"Warning": "提示",
|
"Warning": "提示",
|
||||||
"app": {
|
"app": {
|
||||||
"AI Settings": "AI 高级配置",
|
"AI Advanced Settings": "AI 高级配置",
|
||||||
|
"AI Settings": "AI 配置",
|
||||||
"Advance App TestTip": "当前应用为高级编排模式\n如需切换为【简易模式】请点击左侧保存按键",
|
"Advance App TestTip": "当前应用为高级编排模式\n如需切换为【简易模式】请点击左侧保存按键",
|
||||||
"App Detail": "应用详情",
|
"App Detail": "应用详情",
|
||||||
|
"Basic Settings": "基本信息",
|
||||||
|
"Chat Debug": "调试预览",
|
||||||
"Chat Logs Tips": "日志会记录该应用的在线、分享和 API(需填写 chatId) 对话记录",
|
"Chat Logs Tips": "日志会记录该应用的在线、分享和 API(需填写 chatId) 对话记录",
|
||||||
"Chat logs": "对话日志",
|
"Chat logs": "对话日志",
|
||||||
"Confirm Del App Tip": "确认删除该应用及其所有聊天记录?",
|
"Confirm Del App Tip": "确认删除该应用及其所有聊天记录?",
|
||||||
@@ -38,6 +41,7 @@
|
|||||||
"Logs Title": "标题",
|
"Logs Title": "标题",
|
||||||
"Mark Count": "标注答案数量",
|
"Mark Count": "标注答案数量",
|
||||||
"My Apps": "我的应用",
|
"My Apps": "我的应用",
|
||||||
|
"Open AI Advanced Settings": "高级配置",
|
||||||
"Output Field Settings": "输出字段编辑",
|
"Output Field Settings": "输出字段编辑",
|
||||||
"Paste Config": "粘贴配置",
|
"Paste Config": "粘贴配置",
|
||||||
"Variable Key Repeat Tip": "变量 key 重复",
|
"Variable Key Repeat Tip": "变量 key 重复",
|
||||||
@@ -106,6 +110,7 @@
|
|||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"Add": "添加",
|
"Add": "添加",
|
||||||
|
"Choose": "选择",
|
||||||
"Close": "关闭",
|
"Close": "关闭",
|
||||||
"Collect": "收藏",
|
"Collect": "收藏",
|
||||||
"Confirm Move": "移动到这",
|
"Confirm Move": "移动到这",
|
||||||
@@ -131,6 +136,7 @@
|
|||||||
"Name is empty": "名称不能为空",
|
"Name is empty": "名称不能为空",
|
||||||
"Next Step": "下一步",
|
"Next Step": "下一步",
|
||||||
"Output": "输出",
|
"Output": "输出",
|
||||||
|
"Params": "参数",
|
||||||
"Password inconsistency": "两次密码不一致",
|
"Password inconsistency": "两次密码不一致",
|
||||||
"Rename": "重命名",
|
"Rename": "重命名",
|
||||||
"Rename Failed": "重命名失败",
|
"Rename Failed": "重命名失败",
|
||||||
@@ -151,10 +157,30 @@
|
|||||||
"folder": {
|
"folder": {
|
||||||
"Drag Tip": "点我可拖动",
|
"Drag Tip": "点我可拖动",
|
||||||
"Move Success": "移动成功",
|
"Move Success": "移动成功",
|
||||||
"No Folder": "这个目录空空的~",
|
"No Folder": "没有子目录了,就放这里吧",
|
||||||
"Root Path": "根目录"
|
"Root Path": "根目录"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"core": {
|
||||||
|
"ai": {
|
||||||
|
"Model": "AI 模型",
|
||||||
|
"Prompt": "提示词"
|
||||||
|
},
|
||||||
|
"app": {
|
||||||
|
"Next Step Guide": "下一步指引"
|
||||||
|
},
|
||||||
|
"chat": {
|
||||||
|
"Restart": "重开对话"
|
||||||
|
},
|
||||||
|
"dataset": {
|
||||||
|
"Choose Dataset": "关联知识库",
|
||||||
|
"Dataset": "知识库",
|
||||||
|
"Read Dataset": "查看知识库详情",
|
||||||
|
"Search Top K": "单次搜索数量",
|
||||||
|
"Set Empty Result Tip": ",未搜索到内容时回复指定内容",
|
||||||
|
"Similarity": "相似度"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dataset": {
|
"dataset": {
|
||||||
"Chunk Length": "数据总量",
|
"Chunk Length": "数据总量",
|
||||||
"Confirm move the folder": "确认移动到该目录",
|
"Confirm move the folder": "确认移动到该目录",
|
||||||
@@ -189,6 +215,7 @@
|
|||||||
"Click to view folder": "进入目录",
|
"Click to view folder": "进入目录",
|
||||||
"Collection Embedding": "{{total}}组索引中",
|
"Collection Embedding": "{{total}}组索引中",
|
||||||
"Confirm to delete the folder": "确认删除该文件夹及里面所有内容?",
|
"Confirm to delete the folder": "确认删除该文件夹及里面所有内容?",
|
||||||
|
"Create And Import": "新建/导入",
|
||||||
"Create Training Data": "文件训练-{{filename}}",
|
"Create Training Data": "文件训练-{{filename}}",
|
||||||
"Create Virtual File Success": "创建虚拟文件成功",
|
"Create Virtual File Success": "创建虚拟文件成功",
|
||||||
"Data Amount": "数据总量",
|
"Data Amount": "数据总量",
|
||||||
@@ -208,7 +235,7 @@
|
|||||||
"deleteFolderTips": "确认删除该文件夹及其包含的所有知识库?删除后数据无法恢复,请确认!"
|
"deleteFolderTips": "确认删除该文件夹及其包含的所有知识库?删除后数据无法恢复,请确认!"
|
||||||
},
|
},
|
||||||
"file": {
|
"file": {
|
||||||
"Click to download CSV template": "点击下载 CSV 模板",
|
"Click to download file template": "点击下载模板:{{name}}",
|
||||||
"Click to view file": "点击查看原始文件",
|
"Click to view file": "点击查看原始文件",
|
||||||
"Create File": "创建新文件",
|
"Create File": "创建新文件",
|
||||||
"Create file": "创建文件",
|
"Create file": "创建文件",
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1698113328889" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2458" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M362.496 661.504c0 23.552 18.944 42.496 42.496 42.496s42.496-18.944 42.496-42.496c0-23.552-18.944-42.496-42.496-42.496s-42.496 18.944-42.496 42.496zM576 661.504c0 23.552 18.944 42.496 42.496 42.496 23.552 0 42.496-18.944 42.496-42.496 0-23.552-18.944-42.496-42.496-42.496-23.552-0.512-42.496 18.944-42.496 42.496z" p-id="2459"></path><path d="M874.496 618.496v-21.504c2.048-95.744-41.984-186.368-118.272-244.224L860.16 190.464c34.304 8.192 68.608-13.312 76.8-48.128 8.192-34.304-13.312-68.608-48.128-76.8s-68.608 13.312-76.8 48.128c-4.608 18.944 0 38.4 11.776 53.76l-102.912 162.304c-64-35.328-136.192-53.248-209.408-52.224-73.216-1.536-145.408 16.384-209.408 52.224L199.68 167.424c21.504-27.648 16.896-68.096-11.264-89.6-27.648-21.504-68.096-16.896-89.6 11.264-22.016 27.648-16.896 67.584 11.264 89.6 15.36 11.776 34.816 16.384 53.76 11.776L267.776 353.28c-76.288 57.856-120.32 148.48-118.272 244.224v21.504H42.496v256h106.496v85.504h725.504v-85.504h106.496v-256h-106.496zM149.504 832H85.504v-170.496h64v170.496z m512-42.496H362.496c-70.656 0-128-57.344-128-128s57.344-128 128-128h298.496c70.656 0 128 57.344 128 128 0.512 70.656-56.832 128-127.488 128z m276.992 42.496h-64v-170.496h64v170.496z" p-id="2460"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1698113264760" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="26082" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M981.333333 618.666667h-106.666666v-21.333334a298.666667 298.666667 0 0 0-118.186667-244.053333l103.893333-162.986667a64 64 0 1 0-36.053333-23.04l-103.04 162.133334A416.213333 416.213333 0 0 0 512 277.333333a416.213333 416.213333 0 0 0-209.28 52.053334l-103.04-162.133334a64 64 0 1 0-36.053333 23.04l103.893333 162.986667A298.666667 298.666667 0 0 0 149.333333 597.333333v21.333334H42.666667v256h106.666666v85.333333h725.333334v-85.333333h106.666666zM85.333333 832v-170.666667h64v170.666667z m746.666667 85.333333H192V597.333333c0-192 160.64-277.333333 320-277.333333s320 85.333333 320 277.333333v320z m106.666667-85.333333h-64v-170.666667h64z" p-id="26083"></path><path d="M405.333333 661.333333m-42.666666 0a42.666667 42.666667 0 1 0 85.333333 0 42.666667 42.666667 0 1 0-85.333333 0Z" p-id="26084"></path><path d="M618.666667 661.333333m-42.666667 0a42.666667 42.666667 0 1 0 85.333333 0 42.666667 42.666667 0 1 0-85.333333 0Z" p-id="26085"></path><path d="M661.333333 533.333333H362.666667a128 128 0 0 0 0 256h298.666666a128 128 0 0 0 0-256z m0 213.333334H362.666667a85.333333 85.333333 0 0 1 0-170.666667h298.666666a85.333333 85.333333 0 0 1 0 170.666667z" p-id="26086"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
@@ -89,7 +89,9 @@ const iconPaths = {
|
|||||||
moveLight: () => import('./icons/light/move.svg'),
|
moveLight: () => import('./icons/light/move.svg'),
|
||||||
questionGuide: () => import('./icons/app/questionGuide.svg'),
|
questionGuide: () => import('./icons/app/questionGuide.svg'),
|
||||||
loading: () => import('./icons/light/loading.svg'),
|
loading: () => import('./icons/light/loading.svg'),
|
||||||
pause: () => import('./icons/common/pause.svg')
|
pause: () => import('./icons/common/pause.svg'),
|
||||||
|
'core/app/aiLight': () => import('./icons/core/app/aiLight.svg'),
|
||||||
|
'core/app/aiFill': () => import('./icons/core/app/aiFill.svg')
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IconName = keyof typeof iconPaths;
|
export type IconName = keyof typeof iconPaths;
|
||||||
|
@@ -35,8 +35,8 @@ const Navbar = ({ unread }: { unread: number }) => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('navbar.Apps'),
|
label: t('navbar.Apps'),
|
||||||
icon: 'appLight',
|
icon: 'core/app/aiLight',
|
||||||
activeIcon: 'appFill',
|
activeIcon: 'core/app/aiFill',
|
||||||
link: `/app/list`,
|
link: `/app/list`,
|
||||||
activeLink: ['/app/list', '/app/detail']
|
activeLink: ['/app/list', '/app/detail']
|
||||||
},
|
},
|
||||||
|
@@ -21,7 +21,7 @@ const NavbarPhone = ({ unread }: { unread: number }) => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('navbar.Apps'),
|
label: t('navbar.Apps'),
|
||||||
icon: 'tabbarModel',
|
icon: 'core/app/aiLight',
|
||||||
link: `/app/list`,
|
link: `/app/list`,
|
||||||
activeLink: ['/app/list', '/app/detail'],
|
activeLink: ['/app/list', '/app/detail'],
|
||||||
unread: 0
|
unread: 0
|
||||||
|
@@ -22,7 +22,7 @@ const MyModal = ({
|
|||||||
title,
|
title,
|
||||||
children,
|
children,
|
||||||
isCentered,
|
isCentered,
|
||||||
w = '100%',
|
w = 'auto',
|
||||||
maxW = ['90vw', '600px'],
|
maxW = ['90vw', '600px'],
|
||||||
...props
|
...props
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
|
@@ -80,7 +80,7 @@ const DatasetSelectContainer = ({
|
|||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
{children}
|
<Box flex={'1 0 0'}>{children}</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</MyModal>
|
</MyModal>
|
||||||
);
|
);
|
||||||
|
@@ -850,7 +850,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
key: 'userChatInput'
|
key: 'userChatInput'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
moduleId: 'kbSearch',
|
moduleId: 'datasetSearch',
|
||||||
key: 'userChatInput'
|
key: 'userChatInput'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -898,7 +898,7 @@ export const appTemplates: (AppItemType & {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
moduleId: 'kbSearch',
|
moduleId: 'datasetSearch',
|
||||||
name: '知识库搜索',
|
name: '知识库搜索',
|
||||||
flowType: 'datasetSearchNode',
|
flowType: 'datasetSearchNode',
|
||||||
showStatus: true,
|
showStatus: true,
|
||||||
|
@@ -9,6 +9,5 @@ export enum ContextExtractEnum {
|
|||||||
|
|
||||||
export enum HttpPropsEnum {
|
export enum HttpPropsEnum {
|
||||||
url = 'url',
|
url = 'url',
|
||||||
failed = 'failed',
|
failed = 'failed'
|
||||||
finish = 'finish'
|
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import { authUser } from '@fastgpt/service/support/user/auth';
|
|||||||
import { App } from '@/service/models/app';
|
import { App } from '@/service/models/app';
|
||||||
import type { AppUpdateParams } from '@/types/app';
|
import type { AppUpdateParams } from '@/types/app';
|
||||||
import { authApp } from '@/service/utils/auth';
|
import { authApp } from '@/service/utils/auth';
|
||||||
|
import { SystemOutputEnum } from '@/constants/app';
|
||||||
|
|
||||||
/* 获取我的模型 */
|
/* 获取我的模型 */
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||||
@@ -40,7 +41,17 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
|||||||
'share.isShare': share.isShare,
|
'share.isShare': share.isShare,
|
||||||
'share.isShareDetail': share.isShareDetail
|
'share.isShareDetail': share.isShareDetail
|
||||||
}),
|
}),
|
||||||
...(modules && { modules })
|
...(modules && {
|
||||||
|
modules: modules.map((modules) => ({
|
||||||
|
...modules,
|
||||||
|
outputs: modules.outputs.sort((a, b) => {
|
||||||
|
// finish output always at last
|
||||||
|
if (a.key === SystemOutputEnum.finish) return 1;
|
||||||
|
if (b.key === SystemOutputEnum.finish) return -1;
|
||||||
|
return 0;
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -29,7 +29,7 @@ import { pushChatBill } from '@/service/common/bill/push';
|
|||||||
import { BillSourceEnum } from '@/constants/user';
|
import { BillSourceEnum } from '@/constants/user';
|
||||||
import { ChatHistoryItemResType } from '@/types/chat';
|
import { ChatHistoryItemResType } from '@/types/chat';
|
||||||
import type { UserModelSchema } from '@fastgpt/global/support/user/type';
|
import type { UserModelSchema } from '@fastgpt/global/support/user/type';
|
||||||
import { SystemInputEnum } from '@/constants/app';
|
import { SystemInputEnum, SystemOutputEnum } from '@/constants/app';
|
||||||
import { getSystemTime } from '@fastgpt/global/common/time/timezone';
|
import { getSystemTime } from '@fastgpt/global/common/time/timezone';
|
||||||
import { authOutLinkChat } from '@fastgpt/service/support/outLink/auth';
|
import { authOutLinkChat } from '@fastgpt/service/support/outLink/auth';
|
||||||
import { pushResult2Remote, updateOutLinkUsage } from '@fastgpt/service/support/outLink/tools';
|
import { pushResult2Remote, updateOutLinkUsage } from '@fastgpt/service/support/outLink/tools';
|
||||||
@@ -431,7 +431,7 @@ export async function dispatchModules({
|
|||||||
inputs: params
|
inputs: params
|
||||||
};
|
};
|
||||||
|
|
||||||
const dispatchRes = await (async () => {
|
const dispatchRes: Record<string, any> = await (async () => {
|
||||||
const callbackMap: Record<string, Function> = {
|
const callbackMap: Record<string, Function> = {
|
||||||
[FlowModuleTypeEnum.historyNode]: dispatchHistory,
|
[FlowModuleTypeEnum.historyNode]: dispatchHistory,
|
||||||
[FlowModuleTypeEnum.questionInput]: dispatchChatInput,
|
[FlowModuleTypeEnum.questionInput]: dispatchChatInput,
|
||||||
@@ -449,7 +449,10 @@ export async function dispatchModules({
|
|||||||
return {};
|
return {};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
return moduleOutput(module, dispatchRes);
|
return moduleOutput(module, {
|
||||||
|
[SystemOutputEnum.finish]: true,
|
||||||
|
...dispatchRes
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// start process width initInput
|
// start process width initInput
|
||||||
|
@@ -66,7 +66,7 @@ const AIChatSettingsModal = ({
|
|||||||
isOpen
|
isOpen
|
||||||
title={
|
title={
|
||||||
<Flex alignItems={'flex-end'}>
|
<Flex alignItems={'flex-end'}>
|
||||||
{t('app.AI Settings')}
|
{t('app.AI Advanced Settings')}
|
||||||
{feConfigs?.show_doc && (
|
{feConfigs?.show_doc && (
|
||||||
<Link
|
<Link
|
||||||
href={`${feConfigs.docUrl}/docs/use-cases/ai_settings/`}
|
href={`${feConfigs.docUrl}/docs/use-cases/ai_settings/`}
|
||||||
|
@@ -51,12 +51,10 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
|||||||
...item,
|
...item,
|
||||||
connected: item.connected ?? item.type !== FlowInputItemTypeEnum.target
|
connected: item.connected ?? item.type !== FlowInputItemTypeEnum.target
|
||||||
})),
|
})),
|
||||||
outputs: item.data.outputs
|
outputs: item.data.outputs.map((item) => ({
|
||||||
.map((item) => ({
|
|
||||||
...item,
|
...item,
|
||||||
targets: [] as FlowOutputTargetItemType[]
|
targets: [] as FlowOutputTargetItemType[]
|
||||||
}))
|
}))
|
||||||
.sort((a, b) => (a.key === SystemOutputEnum.finish ? 1 : -1)) // finish output always at last
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// update inputs and outputs
|
// update inputs and outputs
|
||||||
@@ -100,7 +98,7 @@ const RenderHeaderContainer = React.memo(function RenderHeaderContainer({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return updateAppDetail(app._id, {
|
return updateAppDetail(app._id, {
|
||||||
modules: modules,
|
modules,
|
||||||
type: AppTypeEnum.advanced
|
type: AppTypeEnum.advanced
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@@ -128,9 +128,15 @@ const RenderOutput = ({
|
|||||||
flowOutputList: FlowOutputItemType[];
|
flowOutputList: FlowOutputItemType[];
|
||||||
}) => {
|
}) => {
|
||||||
const sortOutput = useMemo(
|
const sortOutput = useMemo(
|
||||||
() => [...flowOutputList].sort((a, b) => (a.key === SystemOutputEnum.finish ? -1 : 1)),
|
() =>
|
||||||
|
[...flowOutputList].sort((a, b) => {
|
||||||
|
if (a.key === SystemOutputEnum.finish) return -1;
|
||||||
|
if (b.key === SystemOutputEnum.finish) return 1;
|
||||||
|
return 0;
|
||||||
|
}),
|
||||||
[flowOutputList]
|
[flowOutputList]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{sortOutput.map(
|
{sortOutput.map(
|
||||||
|
@@ -82,7 +82,8 @@ const Settings = ({ appId }: { appId: string }) => {
|
|||||||
const [refresh, setRefresh] = useState(false);
|
const [refresh, setRefresh] = useState(false);
|
||||||
|
|
||||||
const { openConfirm: openConfirmSave, ConfirmModal: ConfirmSaveModal } = useConfirm({
|
const { openConfirm: openConfirmSave, ConfirmModal: ConfirmSaveModal } = useConfirm({
|
||||||
content: t('app.Confirm Save App Tip')
|
content: t('app.Confirm Save App Tip'),
|
||||||
|
bg: appDetail.type === AppTypeEnum.basic ? '' : 'red.600'
|
||||||
});
|
});
|
||||||
const { openConfirm: openConfirmDel, ConfirmModal: ConfirmDelModal } = useConfirm({
|
const { openConfirm: openConfirmDel, ConfirmModal: ConfirmDelModal } = useConfirm({
|
||||||
content: t('app.Confirm Del App Tip')
|
content: t('app.Confirm Del App Tip')
|
||||||
@@ -211,7 +212,7 @@ const Settings = ({ appId }: { appId: string }) => {
|
|||||||
>
|
>
|
||||||
<Flex alignItems={'flex-end'}>
|
<Flex alignItems={'flex-end'}>
|
||||||
<Box fontSize={['md', 'xl']} fontWeight={'bold'}>
|
<Box fontSize={['md', 'xl']} fontWeight={'bold'}>
|
||||||
基础信息
|
{t('app.Basic Settings')}
|
||||||
</Box>
|
</Box>
|
||||||
<Box ml={1} color={'myGray.500'} fontSize={'sm'}>
|
<Box ml={1} color={'myGray.500'} fontSize={'sm'}>
|
||||||
(
|
(
|
||||||
@@ -310,6 +311,7 @@ const Settings = ({ appId }: { appId: string }) => {
|
|||||||
isLoading={isSaving}
|
isLoading={isSaving}
|
||||||
fontSize={'sm'}
|
fontSize={'sm'}
|
||||||
size={['sm', 'md']}
|
size={['sm', 'md']}
|
||||||
|
variant={appDetail.type === AppTypeEnum.basic ? 'primary' : 'base'}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (appDetail.type !== AppTypeEnum.basic) {
|
if (appDetail.type !== AppTypeEnum.basic) {
|
||||||
openConfirmSave(handleSubmit((data) => onSubmitSave(data)))();
|
openConfirmSave(handleSubmit((data) => onSubmitSave(data)))();
|
||||||
@@ -398,21 +400,21 @@ const Settings = ({ appId }: { appId: string }) => {
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* model */}
|
{/* ai */}
|
||||||
<Box mt={5} {...BoxStyles}>
|
<Box mt={5} {...BoxStyles}>
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<Avatar src={'/imgs/module/AI.png'} w={'18px'} />
|
<Avatar src={'/imgs/module/AI.png'} w={'18px'} />
|
||||||
<Box ml={2} flex={1}>
|
<Box ml={2} flex={1}>
|
||||||
AI 配置
|
{t('app.AI Settings')}
|
||||||
</Box>
|
</Box>
|
||||||
<Flex {...BoxBtnStyles} onClick={onOpenAIChatSetting}>
|
<Flex {...BoxBtnStyles} onClick={onOpenAIChatSetting}>
|
||||||
<MyIcon mr={1} name={'settingLight'} w={'14px'} />
|
<MyIcon mr={1} name={'settingLight'} w={'14px'} />
|
||||||
高级配置
|
{t('app.Open AI Advanced Settings')}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
<Flex alignItems={'center'} mt={5}>
|
<Flex alignItems={'center'} mt={5}>
|
||||||
<Box {...LabelStyles}>对话模型</Box>
|
<Box {...LabelStyles}>{t('core.ai.Model')}</Box>
|
||||||
<Box flex={'1 0 0'}>
|
<Box flex={'1 0 0'}>
|
||||||
<MySelect
|
<MySelect
|
||||||
width={'100%'}
|
width={'100%'}
|
||||||
@@ -432,7 +434,7 @@ const Settings = ({ appId }: { appId: string }) => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<Flex mt={10} alignItems={'flex-start'}>
|
<Flex mt={10} alignItems={'flex-start'}>
|
||||||
<Box {...LabelStyles}>
|
<Box {...LabelStyles}>
|
||||||
提示词
|
{t('core.ai.Prompt')}
|
||||||
<MyTooltip label={ChatModelSystemTip} forceShow>
|
<MyTooltip label={ChatModelSystemTip} forceShow>
|
||||||
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
|
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
|
||||||
</MyTooltip>
|
</MyTooltip>
|
||||||
@@ -451,24 +453,29 @@ const Settings = ({ appId }: { appId: string }) => {
|
|||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<Flex alignItems={'center'} flex={1}>
|
<Flex alignItems={'center'} flex={1}>
|
||||||
<Avatar src={'/imgs/module/db.png'} w={'18px'} />
|
<Avatar src={'/imgs/module/db.png'} w={'18px'} />
|
||||||
<Box ml={2}>知识库</Box>
|
<Box ml={2}>{t('core.dataset.Choose Dataset')}</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex alignItems={'center'} mr={3} {...BoxBtnStyles} onClick={onOpenKbSelect}>
|
<Flex alignItems={'center'} mr={3} {...BoxBtnStyles} onClick={onOpenKbSelect}>
|
||||||
<SmallAddIcon />
|
<SmallAddIcon />
|
||||||
选择
|
{t('common.Choose')}
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex alignItems={'center'} {...BoxBtnStyles} onClick={onOpenKbParams}>
|
<Flex alignItems={'center'} {...BoxBtnStyles} onClick={onOpenKbParams}>
|
||||||
<MyIcon name={'edit'} w={'14px'} mr={1} />
|
<MyIcon name={'edit'} w={'14px'} mr={1} />
|
||||||
参数
|
{t('common.Params')}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex mt={1} color={'myGray.600'} fontSize={['sm', 'md']}>
|
<Flex mt={1} color={'myGray.600'} fontSize={['sm', 'md']}>
|
||||||
相似度: {getValues('kb.searchSimilarity')}, 单次搜索数量: {getValues('kb.searchLimit')},
|
{t('core.dataset.Similarity')}: {getValues('kb.searchSimilarity')},{' '}
|
||||||
空搜索时拒绝回复: {getValues('kb.searchEmptyText') !== '' ? 'true' : 'false'}
|
{t('core.dataset.Search Top K')}: {getValues('kb.searchLimit')}
|
||||||
|
{getValues('kb.searchEmptyText') === '' ? '' : t('core.dataset.Set Empty Result Tip')}
|
||||||
</Flex>
|
</Flex>
|
||||||
<Grid templateColumns={['repeat(2,1fr)', 'repeat(3,1fr)']} my={2} gridGap={[2, 4]}>
|
<Grid
|
||||||
|
gridTemplateColumns={['repeat(2, minmax(0, 1fr))', 'repeat(3, minmax(0, 1fr))']}
|
||||||
|
my={2}
|
||||||
|
gridGap={[2, 4]}
|
||||||
|
>
|
||||||
{selectDatasets.map((item) => (
|
{selectDatasets.map((item) => (
|
||||||
<MyTooltip key={item._id} label={'查看知识库详情'}>
|
<MyTooltip key={item._id} label={t('core.dataset.Read Dataset')} overflow={'hidden'}>
|
||||||
<Flex
|
<Flex
|
||||||
alignItems={'center'}
|
alignItems={'center'}
|
||||||
p={2}
|
p={2}
|
||||||
@@ -499,7 +506,7 @@ const Settings = ({ appId }: { appId: string }) => {
|
|||||||
<Box mt={5} {...BoxStyles}>
|
<Box mt={5} {...BoxStyles}>
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<MyIcon name={'questionGuide'} mr={2} w={'16px'} />
|
<MyIcon name={'questionGuide'} mr={2} w={'16px'} />
|
||||||
<Box>下一步指引</Box>
|
<Box>{t('core.app.Next Step Guide')}</Box>
|
||||||
<MyTooltip label={questionGuideTip} forceShow>
|
<MyTooltip label={questionGuideTip} forceShow>
|
||||||
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
|
<QuestionOutlineIcon display={['none', 'inline']} ml={1} />
|
||||||
</MyTooltip>
|
</MyTooltip>
|
||||||
@@ -635,9 +642,9 @@ const ChatTest = ({ appId }: { appId: string }) => {
|
|||||||
<Flex position={'relative'} flexDirection={'column'} h={'100%'} py={4} overflowX={'auto'}>
|
<Flex position={'relative'} flexDirection={'column'} h={'100%'} py={4} overflowX={'auto'}>
|
||||||
<Flex px={[2, 5]}>
|
<Flex px={[2, 5]}>
|
||||||
<Box fontSize={['md', 'xl']} fontWeight={'bold'} flex={1}>
|
<Box fontSize={['md', 'xl']} fontWeight={'bold'} flex={1}>
|
||||||
调试预览
|
{t('app.Chat Debug')}
|
||||||
</Box>
|
</Box>
|
||||||
<MyTooltip label={'重置'}>
|
<MyTooltip label={t('core.chat.Restart')}>
|
||||||
<IconButton
|
<IconButton
|
||||||
className="chat"
|
className="chat"
|
||||||
size={'sm'}
|
size={'sm'}
|
||||||
|
@@ -74,13 +74,16 @@ export const DatasetSelectModal = ({
|
|||||||
tips={'仅能选择同一个索引模型的知识库'}
|
tips={'仅能选择同一个索引模型的知识库'}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
>
|
>
|
||||||
<ModalBody
|
<Flex h={'100%'} flexDirection={'column'} flex={'1 0 0'}>
|
||||||
flex={['1 0 0', '1 0 auto']}
|
<ModalBody flex={'1 0 0'} overflowY={'auto'} userSelect={'none'}>
|
||||||
maxH={'80vh'}
|
<Grid
|
||||||
overflowY={['auto', 'unset']}
|
gridTemplateColumns={[
|
||||||
userSelect={'none'}
|
'repeat(1, minmax(0, 1fr))',
|
||||||
|
'repeat(2, minmax(0, 1fr))',
|
||||||
|
'repeat(3, minmax(0, 1fr))'
|
||||||
|
]}
|
||||||
|
gridGap={3}
|
||||||
>
|
>
|
||||||
<Grid gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)', 'repeat(3,1fr)']} gridGap={3}>
|
|
||||||
{filterKbList.selected.map((item) =>
|
{filterKbList.selected.map((item) =>
|
||||||
(() => {
|
(() => {
|
||||||
return (
|
return (
|
||||||
@@ -93,7 +96,7 @@ export const DatasetSelectModal = ({
|
|||||||
>
|
>
|
||||||
<Flex alignItems={'center'} h={'38px'}>
|
<Flex alignItems={'center'} h={'38px'}>
|
||||||
<Avatar src={item.avatar} w={['24px', '28px']}></Avatar>
|
<Avatar src={item.avatar} w={['24px', '28px']}></Avatar>
|
||||||
<Box flex={'1 0 0'} mx={3}>
|
<Box flex={'1 0 0'} w={0} className="textEllipsis" mx={3}>
|
||||||
{item.name}
|
{item.name}
|
||||||
</Box>
|
</Box>
|
||||||
<MyIcon
|
<MyIcon
|
||||||
@@ -116,7 +119,14 @@ export const DatasetSelectModal = ({
|
|||||||
|
|
||||||
{filterKbList.selected.length > 0 && <Divider my={3} />}
|
{filterKbList.selected.length > 0 && <Divider my={3} />}
|
||||||
|
|
||||||
<Grid gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)', 'repeat(3,1fr)']} gridGap={3}>
|
<Grid
|
||||||
|
gridTemplateColumns={[
|
||||||
|
'repeat(1, minmax(0, 1fr))',
|
||||||
|
'repeat(2, minmax(0, 1fr))',
|
||||||
|
'repeat(3, minmax(0, 1fr))'
|
||||||
|
]}
|
||||||
|
gridGap={3}
|
||||||
|
>
|
||||||
{filterKbList.unSelected.map((item) =>
|
{filterKbList.unSelected.map((item) =>
|
||||||
(() => {
|
(() => {
|
||||||
return (
|
return (
|
||||||
@@ -159,6 +169,8 @@ export const DatasetSelectModal = ({
|
|||||||
<Flex alignItems={'center'} h={'38px'}>
|
<Flex alignItems={'center'} h={'38px'}>
|
||||||
<Avatar src={item.avatar} w={['24px', '28px']}></Avatar>
|
<Avatar src={item.avatar} w={['24px', '28px']}></Avatar>
|
||||||
<Box
|
<Box
|
||||||
|
flex={'1 0 0'}
|
||||||
|
w={0}
|
||||||
className="textEllipsis"
|
className="textEllipsis"
|
||||||
ml={3}
|
ml={3}
|
||||||
fontWeight={'bold'}
|
fontWeight={'bold'}
|
||||||
@@ -208,6 +220,7 @@ export const DatasetSelectModal = ({
|
|||||||
完成
|
完成
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
|
</Flex>
|
||||||
</DatasetSelectContainer>
|
</DatasetSelectContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -47,7 +47,6 @@ import { getCollectionIcon } from '@fastgpt/global/core/dataset/utils';
|
|||||||
import EditFolderModal, { useEditFolder } from '../../component/EditFolderModal';
|
import EditFolderModal, { useEditFolder } from '../../component/EditFolderModal';
|
||||||
import { TabEnum } from '..';
|
import { TabEnum } from '..';
|
||||||
import ParentPath from '@/components/common/ParentPaths';
|
import ParentPath from '@/components/common/ParentPaths';
|
||||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import { useDrag } from '@/web/common/hooks/useDrag';
|
import { useDrag } from '@/web/common/hooks/useDrag';
|
||||||
import SelectCollections from '@/web/core/dataset/components/SelectCollections';
|
import SelectCollections from '@/web/core/dataset/components/SelectCollections';
|
||||||
@@ -68,7 +67,6 @@ const CollectionCard = () => {
|
|||||||
const { isPc } = useSystemStore();
|
const { isPc } = useSystemStore();
|
||||||
const [searchText, setSearchText] = useState('');
|
const [searchText, setSearchText] = useState('');
|
||||||
const { setLoading } = useSystemStore();
|
const { setLoading } = useSystemStore();
|
||||||
const { datasetDetail, loadDatasetDetail } = useDatasetStore();
|
|
||||||
|
|
||||||
const { openConfirm, ConfirmModal } = useConfirm({
|
const { openConfirm, ConfirmModal } = useConfirm({
|
||||||
content: t('dataset.Confirm to delete the file')
|
content: t('dataset.Confirm to delete the file')
|
||||||
@@ -114,8 +112,7 @@ const CollectionCard = () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { moveDataId, setMoveDataId, dragStartId, setDragStartId, dragTargetId, setDragTargetId } =
|
const { dragStartId, setDragStartId, dragTargetId, setDragTargetId } = useDrag();
|
||||||
useDrag();
|
|
||||||
|
|
||||||
// change search
|
// change search
|
||||||
const debounceRefetch = useCallback(
|
const debounceRefetch = useCallback(
|
||||||
@@ -209,7 +206,6 @@ const CollectionCard = () => {
|
|||||||
getDatasetCollectionPathById(parentId)
|
getDatasetCollectionPathById(parentId)
|
||||||
);
|
);
|
||||||
|
|
||||||
useQuery(['loadDatasetDetail', datasetId], () => loadDatasetDetail(datasetId));
|
|
||||||
useQuery(
|
useQuery(
|
||||||
['refreshCollection'],
|
['refreshCollection'],
|
||||||
() => {
|
() => {
|
||||||
@@ -279,7 +275,7 @@ const CollectionCard = () => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
<MyMenu
|
<MyMenu
|
||||||
offset={[-10, 10]}
|
offset={[-40, 10]}
|
||||||
width={120}
|
width={120}
|
||||||
Button={
|
Button={
|
||||||
<MenuButton
|
<MenuButton
|
||||||
@@ -290,15 +286,17 @@ const CollectionCard = () => {
|
|||||||
>
|
>
|
||||||
<Flex
|
<Flex
|
||||||
alignItems={'center'}
|
alignItems={'center'}
|
||||||
border={theme.borders.base}
|
|
||||||
px={5}
|
px={5}
|
||||||
py={2}
|
py={2}
|
||||||
borderRadius={'md'}
|
borderRadius={'md'}
|
||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
|
bg={'myBlue.600'}
|
||||||
|
overflow={'hidden'}
|
||||||
|
color={'white'}
|
||||||
h={['28px', '35px']}
|
h={['28px', '35px']}
|
||||||
>
|
>
|
||||||
<AddIcon mr={2} />
|
<MyIcon name={'importLight'} mr={2} w={'14px'} />
|
||||||
<Box>{t('Create New')}</Box>
|
<Box>{t('dataset.collections.Create And Import')}</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
}
|
}
|
||||||
@@ -410,7 +408,7 @@ const CollectionCard = () => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Td maxW={['200px', '300px']} draggable>
|
<Td minW={'150px'} maxW={['200px', '300px']} draggable>
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<Image src={collection.icon} w={'16px'} mr={2} alt={''} />
|
<Image src={collection.icon} w={'16px'} mr={2} alt={''} />
|
||||||
<MyTooltip label={t('common.folder.Drag Tip')} shouldWrapChildren={false}>
|
<MyTooltip label={t('common.folder.Drag Tip')} shouldWrapChildren={false}>
|
||||||
|
@@ -100,7 +100,9 @@ const DataCard = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Flex className="textEllipsis" flex={'1 0 0'} mr={[3, 5]} alignItems={'center'}>
|
<Flex className="textEllipsis" flex={'1 0 0'} mr={[3, 5]} alignItems={'center'}>
|
||||||
<Image src={fileIcon || '/imgs/files/file.svg'} w={'16px'} mr={2} alt={''} />
|
<Image src={fileIcon || '/imgs/files/file.svg'} w={['16px', '18px']} mr={2} alt={''} />
|
||||||
|
|
||||||
|
<Box lineHeight={1.2}>
|
||||||
<RawSourceText
|
<RawSourceText
|
||||||
sourceName={collection?.name}
|
sourceName={collection?.name}
|
||||||
sourceId={collection?.metadata?.fileId || collection?.metadata?.rawLink}
|
sourceId={collection?.metadata?.fileId || collection?.metadata?.rawLink}
|
||||||
@@ -108,6 +110,13 @@ const DataCard = () => {
|
|||||||
color={'black'}
|
color={'black'}
|
||||||
textDecoration={'none'}
|
textDecoration={'none'}
|
||||||
/>
|
/>
|
||||||
|
<Box fontSize={'sm'} color={'myGray.500'}>
|
||||||
|
文件ID:{' '}
|
||||||
|
<Box as={'span'} userSelect={'all'}>
|
||||||
|
{collection?._id}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Box>
|
<Box>
|
||||||
<Button
|
<Button
|
||||||
|
@@ -4,6 +4,7 @@ import { useConfirm } from '@/web/common/hooks/useConfirm';
|
|||||||
import { useImportStore, SelectorContainer, PreviewFileOrChunk } from './Provider';
|
import { useImportStore, SelectorContainer, PreviewFileOrChunk } from './Provider';
|
||||||
|
|
||||||
const fileExtension = '.csv';
|
const fileExtension = '.csv';
|
||||||
|
const csvTemplate = `index,content\n"被索引的内容","对应的答案。CSV 中请注意内容不能包含双引号,双引号是列分割符号"\n"什么是 laf","laf 是一个云函数开发平台……",""\n"什么是 sealos","Sealos 是以 kubernetes 为内核的云操作系统发行版,可以……"`;
|
||||||
|
|
||||||
const CsvImport = () => {
|
const CsvImport = () => {
|
||||||
const { successChunks, totalChunks, isUnselectedFile, onclickUpload, uploading } =
|
const { successChunks, totalChunks, isUnselectedFile, onclickUpload, uploading } =
|
||||||
@@ -15,7 +16,15 @@ const CsvImport = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box display={['block', 'flex']} h={['auto', '100%']}>
|
<Box display={['block', 'flex']} h={['auto', '100%']}>
|
||||||
<SelectorContainer fileExtension={fileExtension} showUrlFetch={false}>
|
<SelectorContainer
|
||||||
|
fileExtension={fileExtension}
|
||||||
|
showUrlFetch={false}
|
||||||
|
fileTemplate={{
|
||||||
|
filename: 'csv 模板.csv',
|
||||||
|
value: csvTemplate,
|
||||||
|
type: 'text/csv'
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Flex mt={3}>
|
<Flex mt={3}>
|
||||||
<Button isDisabled={uploading} onClick={openConfirm(onclickUpload)}>
|
<Button isDisabled={uploading} onClick={openConfirm(onclickUpload)}>
|
||||||
{uploading ? <Box>{Math.round((successChunks / totalChunks) * 100)}%</Box> : '确认导入'}
|
{uploading ? <Box>{Math.round((successChunks / totalChunks) * 100)}%</Box> : '确认导入'}
|
||||||
|
@@ -13,7 +13,7 @@ import {
|
|||||||
readDocContent
|
readDocContent
|
||||||
} from '@/web/common/file/utils';
|
} from '@/web/common/file/utils';
|
||||||
import { Box, Flex, useDisclosure, type BoxProps } from '@chakra-ui/react';
|
import { Box, Flex, useDisclosure, type BoxProps } from '@chakra-ui/react';
|
||||||
import { DragEvent, useCallback, useState } from 'react';
|
import React, { DragEvent, useCallback, useState } from 'react';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
@@ -33,7 +33,6 @@ const UrlFetchModal = dynamic(() => import('./UrlFetchModal'));
|
|||||||
const CreateFileModal = dynamic(() => import('./CreateFileModal'));
|
const CreateFileModal = dynamic(() => import('./CreateFileModal'));
|
||||||
|
|
||||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12);
|
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12);
|
||||||
const csvTemplate = `index,content\n"被索引的内容","对应的答案。CSV 中请注意内容不能包含双引号,双引号是列分割符号"\n"什么是 laf","laf 是一个云函数开发平台……",""\n"什么是 sealos","Sealos 是以 kubernetes 为内核的云操作系统发行版,可以……"`;
|
|
||||||
|
|
||||||
export type FileItemType = {
|
export type FileItemType = {
|
||||||
id: string; // fileId / raw Link
|
id: string; // fileId / raw Link
|
||||||
@@ -46,12 +45,16 @@ export type FileItemType = {
|
|||||||
metadata: DatasetCollectionSchemaType['metadata'];
|
metadata: DatasetCollectionSchemaType['metadata'];
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Props extends BoxProps {
|
export interface Props extends BoxProps {
|
||||||
fileExtension: string;
|
fileExtension: string;
|
||||||
onPushFiles: (files: FileItemType[]) => void;
|
onPushFiles: (files: FileItemType[]) => void;
|
||||||
tipText?: string;
|
tipText?: string;
|
||||||
chunkLen?: number;
|
chunkLen?: number;
|
||||||
isCsv?: boolean;
|
fileTemplate?: {
|
||||||
|
type: string;
|
||||||
|
filename: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
showUrlFetch?: boolean;
|
showUrlFetch?: boolean;
|
||||||
showCreateFile?: boolean;
|
showCreateFile?: boolean;
|
||||||
}
|
}
|
||||||
@@ -61,7 +64,7 @@ const FileSelect = ({
|
|||||||
onPushFiles,
|
onPushFiles,
|
||||||
tipText,
|
tipText,
|
||||||
chunkLen = 500,
|
chunkLen = 500,
|
||||||
isCsv = false,
|
fileTemplate,
|
||||||
showUrlFetch = true,
|
showUrlFetch = true,
|
||||||
showCreateFile = true,
|
showCreateFile = true,
|
||||||
...props
|
...props
|
||||||
@@ -396,7 +399,7 @@ const FileSelect = ({
|
|||||||
{t(tipText)}
|
{t(tipText)}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
{isCsv && (
|
{!!fileTemplate && (
|
||||||
<Box
|
<Box
|
||||||
mt={1}
|
mt={1}
|
||||||
cursor={'pointer'}
|
cursor={'pointer'}
|
||||||
@@ -405,13 +408,13 @@ const FileSelect = ({
|
|||||||
fontSize={'12px'}
|
fontSize={'12px'}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
fileDownload({
|
fileDownload({
|
||||||
text: csvTemplate,
|
text: fileTemplate.value,
|
||||||
type: 'text/csv',
|
type: fileTemplate.type,
|
||||||
filename: 'template.csv'
|
filename: fileTemplate.filename
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{t('file.Click to download CSV template')}
|
{t('file.Click to download file template', { name: fileTemplate.filename })}
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
{selectingText !== undefined && (
|
{selectingText !== undefined && (
|
||||||
|
@@ -76,7 +76,7 @@ const ImportData = ({
|
|||||||
<Flex flexDirection={'column'} flex={'1 0 0'}>
|
<Flex flexDirection={'column'} flex={'1 0 0'}>
|
||||||
<Box pb={[5, 7]} px={[4, 8]} borderBottom={theme.borders.base}>
|
<Box pb={[5, 7]} px={[4, 8]} borderBottom={theme.borders.base}>
|
||||||
<MyRadio
|
<MyRadio
|
||||||
gridTemplateColumns={['repeat(1,1fr)', 'repeat(3, 350px)']}
|
gridTemplateColumns={['repeat(1,1fr)', 'repeat(3,1fr)']}
|
||||||
list={[
|
list={[
|
||||||
{
|
{
|
||||||
icon: 'indexImport',
|
icon: 'indexImport',
|
||||||
|
@@ -8,7 +8,7 @@ import React, {
|
|||||||
useMemo,
|
useMemo,
|
||||||
useEffect
|
useEffect
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import FileSelect, { FileItemType } from './FileSelect';
|
import FileSelect, { FileItemType, Props as FileSelectProps } from './FileSelect';
|
||||||
import { useRequest } from '@/web/common/hooks/useRequest';
|
import { useRequest } from '@/web/common/hooks/useRequest';
|
||||||
import { postDatasetCollection } from '@/web/core/dataset/api';
|
import { postDatasetCollection } from '@/web/core/dataset/api';
|
||||||
import { formatPrice } from '@fastgpt/global/common/bill/tools';
|
import { formatPrice } from '@fastgpt/global/common/bill/tools';
|
||||||
@@ -394,11 +394,13 @@ export const SelectorContainer = ({
|
|||||||
fileExtension,
|
fileExtension,
|
||||||
showUrlFetch,
|
showUrlFetch,
|
||||||
showCreateFile,
|
showCreateFile,
|
||||||
|
fileTemplate,
|
||||||
children
|
children
|
||||||
}: {
|
}: {
|
||||||
fileExtension: string;
|
fileExtension: string;
|
||||||
showUrlFetch?: boolean;
|
showUrlFetch?: boolean;
|
||||||
showCreateFile?: boolean;
|
showCreateFile?: boolean;
|
||||||
|
fileTemplate?: FileSelectProps['fileTemplate'];
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
const { files, setPreviewFile, isUnselectedFile, setFiles, chunkLen } = useImportStore();
|
const { files, setPreviewFile, isUnselectedFile, setFiles, chunkLen } = useImportStore();
|
||||||
@@ -422,6 +424,7 @@ export const SelectorContainer = ({
|
|||||||
chunkLen={chunkLen}
|
chunkLen={chunkLen}
|
||||||
showUrlFetch={showUrlFetch}
|
showUrlFetch={showUrlFetch}
|
||||||
showCreateFile={showCreateFile}
|
showCreateFile={showCreateFile}
|
||||||
|
fileTemplate={fileTemplate}
|
||||||
py={isUnselectedFile ? '100px' : 5}
|
py={isUnselectedFile ? '100px' : 5}
|
||||||
/>
|
/>
|
||||||
{!isUnselectedFile && (
|
{!isUnselectedFile && (
|
||||||
|
@@ -185,6 +185,7 @@ const Info = (
|
|||||||
</Box>
|
</Box>
|
||||||
<Input
|
<Input
|
||||||
flex={[1, '0 0 300px']}
|
flex={[1, '0 0 300px']}
|
||||||
|
maxLength={30}
|
||||||
{...register('name', {
|
{...register('name', {
|
||||||
required: '知识库名称不能为空'
|
required: '知识库名称不能为空'
|
||||||
})}
|
})}
|
||||||
|
@@ -99,6 +99,7 @@ const CreateModal = ({ onClose, parentId }: { onClose: () => void; parentId?: st
|
|||||||
flex={1}
|
flex={1}
|
||||||
autoFocus
|
autoFocus
|
||||||
bg={'myWhite.600'}
|
bg={'myWhite.600'}
|
||||||
|
maxLength={30}
|
||||||
{...register('name', {
|
{...register('name', {
|
||||||
required: '知识库名称不能为空~'
|
required: '知识库名称不能为空~'
|
||||||
})}
|
})}
|
||||||
|
@@ -363,7 +363,9 @@ const Kb = () => {
|
|||||||
/>
|
/>
|
||||||
<Flex alignItems={'center'} h={'38px'}>
|
<Flex alignItems={'center'} h={'38px'}>
|
||||||
<Avatar src={dataset.avatar} borderRadius={'lg'} w={'28px'} />
|
<Avatar src={dataset.avatar} borderRadius={'lg'} w={'28px'} />
|
||||||
<Box ml={3}>{dataset.name}</Box>
|
<Box mx={3} className="textEllipsis3">
|
||||||
|
{dataset.name}
|
||||||
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Box flex={'1 0 0'} overflow={'hidden'} pt={2}>
|
<Box flex={'1 0 0'} overflow={'hidden'} pt={2}>
|
||||||
<Flex>
|
<Flex>
|
||||||
|
@@ -38,6 +38,7 @@ export async function generateQA(): Promise<any> {
|
|||||||
datasetCollectionId: 1,
|
datasetCollectionId: 1,
|
||||||
q: 1,
|
q: 1,
|
||||||
model: 1,
|
model: 1,
|
||||||
|
prompt: 1,
|
||||||
billId: 1
|
billId: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -35,7 +35,6 @@ export type ChatResponse = {
|
|||||||
[TaskResponseKeyEnum.answerText]: string;
|
[TaskResponseKeyEnum.answerText]: string;
|
||||||
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType;
|
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType;
|
||||||
[TaskResponseKeyEnum.history]: ChatItemType[];
|
[TaskResponseKeyEnum.history]: ChatItemType[];
|
||||||
finish: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* request openai chat */
|
/* request openai chat */
|
||||||
@@ -193,8 +192,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
|||||||
quoteList: filterQuoteQA,
|
quoteList: filterQuoteQA,
|
||||||
historyPreview: getHistoryPreview(completeMessages)
|
historyPreview: getHistoryPreview(completeMessages)
|
||||||
},
|
},
|
||||||
[TaskResponseKeyEnum.history]: completeMessages,
|
[TaskResponseKeyEnum.history]: completeMessages
|
||||||
finish: true
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -6,7 +6,6 @@ export type AnswerProps = ModuleDispatchProps<{
|
|||||||
text: string;
|
text: string;
|
||||||
}>;
|
}>;
|
||||||
export type AnswerResponse = {
|
export type AnswerResponse = {
|
||||||
finish: boolean;
|
|
||||||
[TaskResponseKeyEnum.answerText]: string;
|
[TaskResponseKeyEnum.answerText]: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -31,7 +30,6 @@ export const dispatchAnswer = (props: Record<string, any>): AnswerResponse => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
finish: true,
|
|
||||||
[TaskResponseKeyEnum.answerText]: formatText
|
[TaskResponseKeyEnum.answerText]: formatText
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@@ -8,7 +8,6 @@ export type HttpRequestProps = ModuleDispatchProps<{
|
|||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}>;
|
}>;
|
||||||
export type HttpResponse = {
|
export type HttpResponse = {
|
||||||
[HttpPropsEnum.finish]: boolean;
|
|
||||||
[HttpPropsEnum.failed]?: boolean;
|
[HttpPropsEnum.failed]?: boolean;
|
||||||
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType;
|
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
@@ -33,7 +32,6 @@ export const dispatchHttpRequest = async (props: Record<string, any>): Promise<H
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[HttpPropsEnum.finish]: true,
|
|
||||||
[TaskResponseKeyEnum.responseData]: {
|
[TaskResponseKeyEnum.responseData]: {
|
||||||
moduleType: FlowModuleTypeEnum.httpRequest,
|
moduleType: FlowModuleTypeEnum.httpRequest,
|
||||||
moduleName,
|
moduleName,
|
||||||
@@ -45,7 +43,6 @@ export const dispatchHttpRequest = async (props: Record<string, any>): Promise<H
|
|||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
return {
|
||||||
[HttpPropsEnum.finish]: true,
|
|
||||||
[HttpPropsEnum.failed]: true,
|
[HttpPropsEnum.failed]: true,
|
||||||
[TaskResponseKeyEnum.responseData]: {
|
[TaskResponseKeyEnum.responseData]: {
|
||||||
moduleType: FlowModuleTypeEnum.httpRequest,
|
moduleType: FlowModuleTypeEnum.httpRequest,
|
||||||
|
@@ -13,7 +13,6 @@ type Props = ModuleDispatchProps<{
|
|||||||
app: SelectAppItemType;
|
app: SelectAppItemType;
|
||||||
}>;
|
}>;
|
||||||
type Response = {
|
type Response = {
|
||||||
finish: boolean;
|
|
||||||
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType[];
|
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType[];
|
||||||
[TaskResponseKeyEnum.answerText]: string;
|
[TaskResponseKeyEnum.answerText]: string;
|
||||||
[TaskResponseKeyEnum.history]: ChatItemType[];
|
[TaskResponseKeyEnum.history]: ChatItemType[];
|
||||||
@@ -77,7 +76,6 @@ export const dispatchAppRequest = async (props: Record<string, any>): Promise<Re
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
finish: true,
|
|
||||||
responseData,
|
responseData,
|
||||||
[TaskResponseKeyEnum.answerText]: answerText,
|
[TaskResponseKeyEnum.answerText]: answerText,
|
||||||
[TaskResponseKeyEnum.history]: completeMessages
|
[TaskResponseKeyEnum.history]: completeMessages
|
||||||
|
@@ -11,9 +11,13 @@ import {
|
|||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
|
|
||||||
export const useConfirm = (props: { title?: string | null; content?: string | null }) => {
|
export const useConfirm = (props: {
|
||||||
|
title?: string | null;
|
||||||
|
content?: string | null;
|
||||||
|
bg?: string;
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { title = t('Warning'), content } = props;
|
const { title = t('Warning'), content, bg } = props;
|
||||||
const [customContent, setCustomContent] = useState(content);
|
const [customContent, setCustomContent] = useState(content);
|
||||||
|
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
@@ -61,6 +65,7 @@ export const useConfirm = (props: { title?: string | null; content?: string | nu
|
|||||||
{t('Cancel')}
|
{t('Cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
{...(bg && { bg: `${bg} !important` })}
|
||||||
ml={4}
|
ml={4}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onClose();
|
onClose();
|
||||||
@@ -74,7 +79,7 @@ export const useConfirm = (props: { title?: string | null; content?: string | nu
|
|||||||
</AlertDialogOverlay>
|
</AlertDialogOverlay>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
),
|
),
|
||||||
[customContent, isOpen, onClose, t, title]
|
[bg, customContent, isOpen, onClose, t, title]
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@@ -50,7 +50,7 @@ export const useEditTitle = ({
|
|||||||
|
|
||||||
// eslint-disable-next-line react/display-name
|
// eslint-disable-next-line react/display-name
|
||||||
const EditModal = useCallback(
|
const EditModal = useCallback(
|
||||||
() => (
|
({ maxLength = 30 }: { maxLength?: number }) => (
|
||||||
<MyModal isOpen={isOpen} onClose={onClose} title={title}>
|
<MyModal isOpen={isOpen} onClose={onClose} title={title}>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
{!!tip && (
|
{!!tip && (
|
||||||
@@ -64,7 +64,7 @@ export const useEditTitle = ({
|
|||||||
defaultValue={defaultValue.current}
|
defaultValue={defaultValue.current}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
autoFocus
|
autoFocus
|
||||||
maxLength={20}
|
maxLength={maxLength}
|
||||||
/>
|
/>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
|
@@ -378,7 +378,7 @@ const kbTemplate = (formData: EditFormType): AppModuleItemType[] => [
|
|||||||
key: 'userChatInput'
|
key: 'userChatInput'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
moduleId: 'kbSearch',
|
moduleId: 'datasetSearch',
|
||||||
key: 'userChatInput'
|
key: 'userChatInput'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -501,7 +501,7 @@ const kbTemplate = (formData: EditFormType): AppModuleItemType[] => [
|
|||||||
x: 956.0838440206068,
|
x: 956.0838440206068,
|
||||||
y: 887.462827870246
|
y: 887.462827870246
|
||||||
},
|
},
|
||||||
moduleId: 'kbSearch'
|
moduleId: 'datasetSearch'
|
||||||
},
|
},
|
||||||
...(formData.kb.searchEmptyText
|
...(formData.kb.searchEmptyText
|
||||||
? [
|
? [
|
||||||
|
@@ -97,7 +97,14 @@ const SelectCollections = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MyModal isOpen onClose={onClose} maxW={['90vw', '900px']} h={['90vh', '80vh']} isCentered>
|
<MyModal
|
||||||
|
isOpen
|
||||||
|
onClose={onClose}
|
||||||
|
maxW={['90vw', '900px']}
|
||||||
|
w={'100%'}
|
||||||
|
h={['90vh', '80vh']}
|
||||||
|
isCentered
|
||||||
|
>
|
||||||
<Flex flexDirection={'column'} flex={'1 0 0'}>
|
<Flex flexDirection={'column'} flex={'1 0 0'}>
|
||||||
<Box flex={'1 0 0'} px={4} py={2}>
|
<Box flex={'1 0 0'} px={4} py={2}>
|
||||||
<Flex flexDirection={'column'} h={'100%'} position={'relative'}>
|
<Flex flexDirection={'column'} h={'100%'} position={'relative'}>
|
||||||
|
Reference in New Issue
Block a user