From c2abbb579f99a7f13cfd93b2d206f8dee75c36d0 Mon Sep 17 00:00:00 2001 From: Archer <545436317@qq.com> Date: Wed, 3 Jan 2024 23:51:12 +0800 Subject: [PATCH] perf: auto load icons (#688) * perf: icon * perf: icon * doc * perf: simple edit ui * doc * doc * doc * doc --- docSite/assets/imgs/sealos_price.png | Bin 0 -> 151919 bytes docSite/content/docs/commercial/intro.md | 14 +- .../content/docs/development/configuration.md | 28 +- docSite/content/docs/development/qa.md | 14 +- docSite/content/docs/development/sealos.md | 81 +- .../content/docs/development/upgrading/466.md | 7 +- .../content/docs/use-cases/datasetEngine.md | 8 +- docSite/content/docs/use-cases/onwechat.md | 2 +- docSite/content/docs/use-cases/openapi.md | 2 +- .../docs/workflow/examples/google_search.md | 2 +- .../docs/workflow/examples/lab_appointment.md | 10 +- .../workflow/modules/coreferenceResolution.md | 6 +- .../docs/workflow/modules/custom_feedback.md | 4 +- docSite/content/docs/workflow/modules/http.md | 2 +- package.json | 4 +- .../template/system/coreferenceResolution.ts | 2 +- .../web/components/common}/Icon/close.tsx | 4 +- .../web/components/common/Icon/constants.ts | 248 +++--- .../web/components/common}/Icon/delete.tsx | 2 +- .../components/common}/Icon/icons/chat.svg | 0 .../common}/Icon/icons/chatSend.svg | 0 .../common}/Icon/icons/closeSolid.svg | 0 .../common}/Icon/icons/collectionLight.svg | 0 .../common}/Icon/icons/collectionSolid.svg | 0 .../Icon/icons/common/addCircleLight.svg | 0 .../common/Icon/icons/common/backFill.svg | 0 .../common/Icon/icons/common/backLight.svg | 0 .../common/Icon/icons/common/clearLight.svg | 0 .../common/Icon/icons/common/closeLight.svg | 0 .../Icon/icons/common/confirm/commonTip.svg | 0 .../Icon/icons/common/confirm/deleteTip.svg | 0 .../common}/Icon/icons/common/courseLight.svg | 0 .../Icon/icons/common/customTitleLight.svg | 0 .../common}/Icon/icons/common/file/move.svg | 0 .../Icon/icons/common/fullScreenLight.svg | 0 .../common/Icon/icons/common/gitFill.svg | 0 .../common/Icon/icons/common/gitLight.svg | 0 .../common/Icon/icons/common/googleFill.svg | 0 .../common/Icon/icons/common/importLight.svg | 0 .../common}/Icon/icons/common/inviteLight.svg | 0 .../common}/Icon/icons/common/language/en.svg | 0 .../common}/Icon/icons/common/language/zh.svg | 0 .../common}/Icon/icons/common/loading.svg | 0 .../Icon/icons/common/navbar/pluginFill.svg | 0 .../Icon/icons/common/navbar/pluginLight.svg | 0 .../Icon/icons/common/overviewLight.svg | 0 .../common}/Icon/icons/common/playFill.svg | 0 .../common}/Icon/icons/common/playLight.svg | 0 .../Icon/icons/common/questionLight.svg | 4 + .../Icon/icons/common/refreshLight.svg | 0 .../common}/Icon/icons/common/retryLight.svg | 0 .../Icon/icons/common/rightArrowLight.svg | 0 .../Icon/icons/common/routePushLight.svg | 0 .../common}/Icon/icons/common/searchLight.svg | 0 .../common/Icon/icons/common/settingLight.svg | 0 .../common}/Icon/icons/common/text/t.svg | 0 .../common}/Icon/icons/common/tickFill.svg | 0 .../common}/Icon/icons/common/viewLight.svg | 0 .../common/Icon/icons/common/voiceLight.svg | 0 .../components/common}/Icon/icons/copy.svg | 0 .../common}/Icon/icons/core/app/aiFill.svg | 0 .../common}/Icon/icons/core/app/aiLight.svg | 0 .../Icon/icons/core/app/appApiLight.svg | 0 .../Icon/icons/core/app/customFeedback.svg | 0 .../Icon/icons/core/app/headphones.svg | 0 .../common}/Icon/icons/core/app/logsLight.svg | 0 .../common}/Icon/icons/core/app/markLight.svg | 0 .../Icon/icons/core/app/questionGuide.svg | 0 .../common}/Icon/icons/core/app/tts.svg | 0 .../common}/Icon/icons/core/app/ttsFill.svg | 0 .../Icon/icons/core/app/variable/input.svg | 0 .../Icon/icons/core/app/variable/select.svg | 0 .../Icon/icons/core/app/variable/textarea.svg | 0 .../common}/Icon/icons/core/chat/QGFill.svg | 0 .../common/Icon/icons/core/chat/chatFill.svg | 0 .../common/Icon/icons/core/chat/chatLight.svg | 0 .../Icon/icons/core/chat/chatModelTag.svg | 0 .../icons/core/chat/feedback/badLight.svg | 0 .../icons/core/chat/feedback/goodLight.svg | 0 .../Icon/icons/core/chat/fileSelect.svg | 0 .../Icon/icons/core/chat/quoteFill.svg | 0 .../Icon/icons/core/chat/quoteSign.svg | 0 .../Icon/icons/core/chat/recordFill.svg | 0 .../common}/Icon/icons/core/chat/sendFill.svg | 0 .../Icon/icons/core/chat/sendLight.svg | 0 .../Icon/icons/core/chat/setTopLight.svg | 0 .../common}/Icon/icons/core/chat/speaking.svg | 0 .../Icon/icons/core/chat/stopSpeech.svg | 0 .../Icon/icons/core/chat/stopSpeechFill.svg | 0 .../Icon/icons/core/dataset/commonDataset.svg | 0 .../Icon/icons/core/dataset/datasetFill.svg | 0 .../Icon/icons/core/dataset/datasetLight.svg | 0 .../Icon/icons/core/dataset/folderDataset.svg | 0 .../icons/core/dataset/fullTextRecall.svg | 0 .../Icon/icons/core/dataset/mixedRecall.svg | 0 .../Icon/icons/core/dataset/modeEmbedding.svg | 0 .../Icon/icons/core/dataset/rerank.svg | 0 .../icons/core/dataset/websiteDataset.svg | 0 .../Icon/icons/core/modules}/previewLight.svg | 0 .../Icon/icons/core}/modules/variable.svg | 0 .../Icon/icons/core}/modules/welcomeText.svg | 0 .../components/common}/Icon/icons/date.svg | 0 .../components/common}/Icon/icons/delete.svg | 0 .../components/common}/Icon/icons/edit.svg | 0 .../components/common}/Icon/icons/empty.svg | 0 .../components/common}/Icon/icons/export.svg | 0 .../common}/Icon/icons/file/csv.svg | 0 .../common}/Icon/icons/file/html.svg | 0 .../common}/Icon/icons/file/indexImport.svg | 0 .../common}/Icon/icons/file/manualImport.svg | 0 .../common}/Icon/icons/file/markdown.svg | 0 .../common}/Icon/icons/file/pdf.svg | 0 .../common}/Icon/icons/file/qaImport.svg | 0 .../common}/Icon/icons/file/uploadFile.svg | 0 .../components/common}/Icon/icons/history.svg | 0 .../components/common}/Icon/icons/inform.svg | 0 .../components/common}/Icon/icons/kbTest.svg | 0 .../components/common}/Icon/icons/menu.svg | 0 .../components/common}/Icon/icons/minus.svg | 0 .../components/common}/Icon/icons/more.svg | 0 .../web/components/common}/Icon/icons/out.svg | 0 .../common}/Icon/icons/phoneTabbar/me.svg | 0 .../common}/Icon/icons/phoneTabbar/more.svg | 0 .../components/common}/Icon/icons/save.svg | 0 .../components/common}/Icon/icons/stop.svg | 0 .../icons/support/account/loginoutLight.svg | 0 .../icons/support/account/promotionLight.svg | 0 .../icons/support/bill/billRecordLight.svg | 0 .../Icon/icons/support/outlink/apikeyFill.svg | 0 .../icons/support/outlink/apikeyLight.svg | 0 .../icons/support/outlink/iframeLight.svg | 0 .../Icon/icons/support/outlink}/share.svg | 0 .../Icon/icons/support/outlink/shareLight.svg | 6 + .../Icon/icons/support/pay/payRecordLight.svg | 0 .../Icon/icons/support/pay/priceLight.svg | 0 .../icons/support/permission/privateLight.svg | 0 .../icons/support/permission/publicLight.svg | 0 .../Icon/icons/support/team/memberLight.svg | 0 .../Icon/icons/support/user/informLight.svg | 0 .../Icon/icons/support/user/userFill.svg | 0 .../Icon/icons/support/user/userLight.svg | 0 .../components/common}/Icon/icons/text.svg | 0 .../components/common}/Icon/icons/user.svg | 0 .../web/components/common}/Icon/icons/wx.svg | 0 packages/web/components/common/Icon/index.tsx | 31 + packages/web/components/common/Icon/type.d.ts | 3 + packages/web/package.json | 19 +- packages/web/tsconfig.json | 7 +- pnpm-lock.yaml | 152 +--- projects/app/data/config.json | 36 +- projects/app/public/imgs/modal/shareFill.svg | 8 + projects/app/public/imgs/modal/shareLight.svg | 1 - projects/app/public/locales/en/common.json | 9 +- projects/app/public/locales/zh/common.json | 7 +- .../src/components/ChatBox/MessageInput.tsx | 5 +- .../ChatBox/SelectMarkCollection.tsx | 2 +- projects/app/src/components/ChatBox/index.tsx | 6 +- .../src/components/DateRangePicker/index.tsx | 2 +- .../app/src/components/EmptyTip/index.tsx | 2 +- .../src/components/Icon/icons/fill/app.svg | 1 - .../components/Icon/icons/fill/appStore.svg | 1 - .../src/components/Icon/icons/fill/play.svg | 8 - .../src/components/Icon/icons/fill/plus.svg | 8 - .../components/Icon/icons/light/appStore.svg | 1 - .../components/Icon/icons/phoneTabbar/app.svg | 1 - .../Icon/icons/phoneTabbar/chat.svg | 1 - .../Icon/icons/support/outlink/shareLight.svg | 1 - projects/app/src/components/Layout/navbar.tsx | 27 +- .../app/src/components/Layout/navbarPhone.tsx | 8 +- .../app/src/components/Markdown/CodeLight.tsx | 2 +- .../Markdown/chat/QuestionGuide.tsx | 2 +- .../Markdown/img/MermaidCodeBlock.tsx | 2 +- .../app/src/components/Markdown/index.tsx | 2 +- projects/app/src/components/MyModal/index.tsx | 2 +- projects/app/src/components/SideBar/index.tsx | 4 +- .../app/src/components/SideTabs/index.tsx | 5 +- .../src/components/common/MyRadio/index.tsx | 2 +- .../components/common/ParentPaths/index.tsx | 2 +- .../common/Textarea/PromptTextarea/index.tsx | 4 +- .../components/core/chat/Divider/index.tsx | 5 +- .../src/components/core/dataset/QuoteItem.tsx | 2 +- .../core/module/DatasetParamsModal.tsx | 2 +- .../core/module/DatasetSelectModal.tsx | 2 +- .../components/core/module/Flow/ChatTest.tsx | 4 +- .../Flow/components/modules/ButtonEdge.tsx | 2 +- .../Flow/components/modules/QGSwitch.tsx | 2 +- .../Flow/components/modules/TTSSelect.tsx | 2 +- .../Flow/components/modules/VariableEdit.tsx | 12 +- .../Flow/components/nodes/NodeCQNode.tsx | 2 +- .../components/nodes/NodeExtract/index.tsx | 4 +- .../Flow/components/nodes/NodePluginInput.tsx | 4 +- .../components/nodes/NodePluginOutput.tsx | 4 +- .../Flow/components/nodes/NodeUserGuide.tsx | 4 +- .../components/nodes/abandon/NodeVariable.tsx | 2 +- .../Flow/components/render/NodeCard.tsx | 4 +- .../components/render/RenderInput/Label.tsx | 4 +- .../RenderInput/templates/AiSetting.tsx | 4 +- .../templates/SelectDatasetParams.tsx | 4 +- .../components/render/RenderOutput/Label.tsx | 4 +- .../src/components/support/apikey/Table.tsx | 2 +- .../support/permission/IconText/index.tsx | 2 +- .../user/team/TeamManageModal/index.tsx | 2 +- .../pages/account/components/BillTable.tsx | 2 +- .../app/src/pages/account/components/Info.tsx | 2 +- .../pages/account/components/InformTable.tsx | 2 +- .../account/components/PayRecordTable.tsx | 2 +- .../pages/account/components/Promotion.tsx | 2 +- projects/app/src/pages/account/index.tsx | 8 +- .../app/detail/components/FlowEdit/Header.tsx | 8 +- .../src/pages/app/detail/components/Logs.tsx | 4 +- .../OutLink/SelectUsingWayModal.tsx | 2 +- .../app/detail/components/OutLink/Share.tsx | 4 +- .../app/detail/components/OutLink/index.tsx | 4 +- .../detail/components/SimpleEdit/AppCard.tsx | 148 ++++ .../components/SimpleEdit/CfrEditModal.tsx | 61 ++ .../detail/components/SimpleEdit/ChatTest.tsx | 133 +++ .../detail/components/SimpleEdit/EditForm.tsx | 546 ++++++++++++ .../detail/components/SimpleEdit/index.tsx | 817 +----------------- projects/app/src/pages/app/detail/index.tsx | 12 +- projects/app/src/pages/app/list/index.tsx | 4 +- .../src/pages/appStore/components/list.tsx | 2 +- .../src/pages/chat/components/ChatHeader.tsx | 2 +- .../chat/components/ChatHistorySlider.tsx | 17 +- .../src/pages/chat/components/SliderApps.tsx | 4 +- .../src/pages/chat/components/ToolMenu.tsx | 10 +- .../detail/components/CollectionCard.tsx | 4 +- .../dataset/detail/components/DataCard.tsx | 4 +- .../detail/components/Import/FileSelect.tsx | 4 +- .../detail/components/Import/ImportModal.tsx | 6 +- .../detail/components/Import/Provider.tsx | 4 +- .../detail/components/InputDataModal.tsx | 6 +- .../pages/dataset/detail/components/Test.tsx | 6 +- .../app/src/pages/dataset/detail/index.tsx | 8 +- .../dataset/list/component/MoveModal.tsx | 2 +- projects/app/src/pages/dataset/list/index.tsx | 2 +- .../src/pages/login/components/LoginForm.tsx | 6 +- projects/app/src/pages/plugin/edit/Header.tsx | 8 +- .../pages/plugin/list/component/EditModal.tsx | 2 +- projects/app/src/pages/plugin/list/index.tsx | 2 +- projects/app/src/pages/tools/index.tsx | 15 +- .../src/service/moduleDispatch/tools/cfr.ts | 4 +- .../dataset/components/SelectCollections.tsx | 2 +- scripts/icon/index.js | 105 +++ scripts/icon/init.js | 42 + scripts/icon/package-lock.json | 613 +++++++++++++ scripts/icon/package.json | 15 + 246 files changed, 2184 insertions(+), 1375 deletions(-) create mode 100644 docSite/assets/imgs/sealos_price.png rename {projects/app/src/components => packages/web/components/common}/Icon/close.tsx (78%) rename projects/app/src/components/Icon/index.tsx => packages/web/components/common/Icon/constants.ts (64%) rename {projects/app/src/components => packages/web/components/common}/Icon/delete.tsx (91%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/chat.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/chatSend.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/closeSolid.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/collectionLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/collectionSolid.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/addCircleLight.svg (100%) rename projects/app/src/components/Icon/icons/fill/back.svg => packages/web/components/common/Icon/icons/common/backFill.svg (100%) rename projects/app/src/components/Icon/icons/back.svg => packages/web/components/common/Icon/icons/common/backLight.svg (100%) rename projects/app/src/components/Icon/icons/light/clear.svg => packages/web/components/common/Icon/icons/common/clearLight.svg (100%) rename projects/app/src/components/Icon/icons/light/close.svg => packages/web/components/common/Icon/icons/common/closeLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/confirm/commonTip.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/confirm/deleteTip.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/courseLight.svg (100%) rename projects/app/src/components/Icon/icons/light/customTitle.svg => packages/web/components/common/Icon/icons/common/customTitleLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/file/move.svg (100%) rename projects/app/src/components/Icon/icons/light/fullScreen.svg => packages/web/components/common/Icon/icons/common/fullScreenLight.svg (100%) rename projects/app/src/components/Icon/icons/fill/git.svg => packages/web/components/common/Icon/icons/common/gitFill.svg (100%) rename projects/app/src/components/Icon/icons/git.svg => packages/web/components/common/Icon/icons/common/gitLight.svg (100%) rename projects/app/src/components/Icon/icons/fill/google.svg => packages/web/components/common/Icon/icons/common/googleFill.svg (100%) rename projects/app/src/components/Icon/icons/light/import.svg => packages/web/components/common/Icon/icons/common/importLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/inviteLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/language/en.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/language/zh.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/loading.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/navbar/pluginFill.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/navbar/pluginLight.svg (100%) rename projects/app/src/components/Icon/icons/light/overview.svg => packages/web/components/common/Icon/icons/common/overviewLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/playFill.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/playLight.svg (100%) create mode 100644 packages/web/components/common/Icon/icons/common/questionLight.svg rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/refreshLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/retryLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/rightArrowLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/routePushLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/searchLight.svg (100%) rename projects/app/src/components/Icon/icons/light/setting.svg => packages/web/components/common/Icon/icons/common/settingLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/text/t.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/tickFill.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/common/viewLight.svg (100%) rename projects/app/src/components/Icon/icons/voice.svg => packages/web/components/common/Icon/icons/common/voiceLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/copy.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/app/aiFill.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/app/aiLight.svg (100%) rename projects/app/src/components/Icon/icons/light/appApi.svg => packages/web/components/common/Icon/icons/core/app/appApiLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/app/customFeedback.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/app/headphones.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/app/logsLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/app/markLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/app/questionGuide.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/app/tts.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/app/ttsFill.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/app/variable/input.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/app/variable/select.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/app/variable/textarea.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/QGFill.svg (100%) rename projects/app/src/components/Icon/icons/fill/chat.svg => packages/web/components/common/Icon/icons/core/chat/chatFill.svg (100%) rename projects/app/src/components/Icon/icons/light/chat.svg => packages/web/components/common/Icon/icons/core/chat/chatLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/chatModelTag.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/feedback/badLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/feedback/goodLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/fileSelect.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/quoteFill.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/quoteSign.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/recordFill.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/sendFill.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/sendLight.svg (100%) rename projects/app/src/components/Icon/icons/light/setTop.svg => packages/web/components/common/Icon/icons/core/chat/setTopLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/speaking.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/stopSpeech.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/chat/stopSpeechFill.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/dataset/commonDataset.svg (100%) rename projects/app/src/components/Icon/icons/fill/db.svg => packages/web/components/common/Icon/icons/core/dataset/datasetFill.svg (100%) rename projects/app/src/components/Icon/icons/light/db.svg => packages/web/components/common/Icon/icons/core/dataset/datasetLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/dataset/folderDataset.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/dataset/fullTextRecall.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/dataset/mixedRecall.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/dataset/modeEmbedding.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/dataset/rerank.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/core/dataset/websiteDataset.svg (100%) rename {projects/app/src/components/Icon/icons/core/module => packages/web/components/common/Icon/icons/core/modules}/previewLight.svg (100%) rename {projects/app/src/components/Icon/icons => packages/web/components/common/Icon/icons/core}/modules/variable.svg (100%) rename {projects/app/src/components/Icon/icons => packages/web/components/common/Icon/icons/core}/modules/welcomeText.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/date.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/delete.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/edit.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/empty.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/export.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/file/csv.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/file/html.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/file/indexImport.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/file/manualImport.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/file/markdown.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/file/pdf.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/file/qaImport.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/file/uploadFile.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/history.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/inform.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/kbTest.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/menu.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/minus.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/more.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/out.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/phoneTabbar/me.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/phoneTabbar/more.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/save.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/stop.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/support/account/loginoutLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/support/account/promotionLight.svg (100%) rename projects/app/src/components/Icon/icons/light/billRecord.svg => packages/web/components/common/Icon/icons/support/bill/billRecordLight.svg (100%) rename projects/app/src/components/Icon/icons/fill/apikey.svg => packages/web/components/common/Icon/icons/support/outlink/apikeyFill.svg (100%) rename projects/app/src/components/Icon/icons/apikey.svg => packages/web/components/common/Icon/icons/support/outlink/apikeyLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/support/outlink/iframeLight.svg (100%) rename {projects/app/src/components/Icon/icons/light => packages/web/components/common/Icon/icons/support/outlink}/share.svg (100%) create mode 100644 packages/web/components/common/Icon/icons/support/outlink/shareLight.svg rename {projects/app/src/components => packages/web/components/common}/Icon/icons/support/pay/payRecordLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/support/pay/priceLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/support/permission/privateLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/support/permission/publicLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/support/team/memberLight.svg (100%) rename projects/app/src/components/Icon/icons/light/inform.svg => packages/web/components/common/Icon/icons/support/user/informLight.svg (100%) rename projects/app/src/components/Icon/icons/fill/me.svg => packages/web/components/common/Icon/icons/support/user/userFill.svg (100%) rename projects/app/src/components/Icon/icons/light/me.svg => packages/web/components/common/Icon/icons/support/user/userLight.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/text.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/user.svg (100%) rename {projects/app/src/components => packages/web/components/common}/Icon/icons/wx.svg (100%) create mode 100644 packages/web/components/common/Icon/index.tsx create mode 100644 packages/web/components/common/Icon/type.d.ts create mode 100644 projects/app/public/imgs/modal/shareFill.svg delete mode 100644 projects/app/public/imgs/modal/shareLight.svg delete mode 100644 projects/app/src/components/Icon/icons/fill/app.svg delete mode 100644 projects/app/src/components/Icon/icons/fill/appStore.svg delete mode 100644 projects/app/src/components/Icon/icons/fill/play.svg delete mode 100644 projects/app/src/components/Icon/icons/fill/plus.svg delete mode 100644 projects/app/src/components/Icon/icons/light/appStore.svg delete mode 100644 projects/app/src/components/Icon/icons/phoneTabbar/app.svg delete mode 100644 projects/app/src/components/Icon/icons/phoneTabbar/chat.svg delete mode 100644 projects/app/src/components/Icon/icons/support/outlink/shareLight.svg create mode 100644 projects/app/src/pages/app/detail/components/SimpleEdit/AppCard.tsx create mode 100644 projects/app/src/pages/app/detail/components/SimpleEdit/CfrEditModal.tsx create mode 100644 projects/app/src/pages/app/detail/components/SimpleEdit/ChatTest.tsx create mode 100644 projects/app/src/pages/app/detail/components/SimpleEdit/EditForm.tsx create mode 100644 scripts/icon/index.js create mode 100644 scripts/icon/init.js create mode 100644 scripts/icon/package-lock.json create mode 100644 scripts/icon/package.json diff --git a/docSite/assets/imgs/sealos_price.png b/docSite/assets/imgs/sealos_price.png new file mode 100644 index 0000000000000000000000000000000000000000..370849a8ca860cbe0dc4d3cf5550581b8ba70b3b GIT binary patch literal 151919 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. 免运维服务&数据库。
3. 赠送 10000 元 Sealos 云资源额度。 | 半天 | 3000元起/月(3个月起)

30000元起/年 | | 自有服务器-单机版 | 1. 6个版本的升级服务。 | 14天内 | 60000元/套(不限时长) | | 自有服务器-Sealos版 | 1. 6个版本的升级服务。 | 14天内 | 150000元/套(不限时长)| - {{< /table >}} +{{% alert icon="🤖 " context="success" %}} +6个版本的升级服务不是指只能用 6 个版本,而是指依赖 FastGPT 团队提供的升级服务。大部分时候,建议自行升级,也不麻烦。 +{{% /alert %}} + ## 技术支持 @@ -84,4 +87,11 @@ FastGPT 商业版软件根据不同的部署方式,分为 4 类收费模式。 2. 二次开发如何操作? - 可自行修改开源版代码进行二次开发,不支持修改商业版镜像。 \ No newline at end of file + 可自行修改开源版代码进行二次开发,不支持修改商业版镜像。 + + +## Sealos 费用 + +Sealos 云服务属于按量计费,下面是它的价格表: + +![](/imgs/sealos_price.png) diff --git a/docSite/content/docs/development/configuration.md b/docSite/content/docs/development/configuration.md index fb720249179..beff5a682d1 100644 --- a/docSite/content/docs/development/configuration.md +++ b/docSite/content/docs/development/configuration.md @@ -178,7 +178,8 @@ weight: 708 { "model": "gpt-3.5-turbo-1106", "name": "GPT35-1106", - "price": 0, // 除以 100000 后等于1个token的价格 + "inputPrice": 0, // 输入价格。 xx元/1k tokens + "outputPrice": 0, // 输出价格。 xx元/1k tokens "maxContext": 16000, // 最大上下文长度 "maxResponse": 4000, // 最大回复长度 "quoteMaxToken": 2000, // 最大引用内容长度 @@ -192,7 +193,8 @@ weight: 708 "name": "GPT35-16k", "maxContext": 16000, "maxResponse": 16000, - "price": 0, + "inputPrice": 0, + "outputPrice": 0, "quoteMaxToken": 8000, "maxTemperature": 1.2, "censor": false, @@ -204,7 +206,8 @@ weight: 708 "name": "GPT4-8k", "maxContext": 8000, "maxResponse": 8000, - "price": 0, + "inputPrice": 0, + "outputPrice": 0, "quoteMaxToken": 4000, "maxTemperature": 1.2, "censor": false, @@ -216,7 +219,8 @@ weight: 708 "name": "GPT4-Vision", "maxContext": 128000, "maxResponse": 4000, - "price": 0, + "inputPrice": 0, + "outputPrice": 0, "quoteMaxToken": 100000, "maxTemperature": 1.2, "censor": false, @@ -239,7 +243,8 @@ weight: 708 "name": "GPT35-1106", "maxContext": 16000, "maxResponse": 4000, - "price": 0, + "inputPrice": 0, + "outputPrice": 0, "toolChoice": true, // 是否支持openai的 toolChoice, 不支持的模型需要设置为 false,会走提示词生成 "functionPrompt": "" }, @@ -248,7 +253,7 @@ weight: 708 "name": "GPT4-8k", "maxContext": 8000, "maxResponse": 8000, - "price": 0, + "inputPrice": 0, "toolChoice": true, "functionPrompt": "" } @@ -259,7 +264,7 @@ weight: 708 "name": "GPT35-1106", "maxContext": 16000, "maxResponse": 4000, - "price": 0, + "outputPrice": 0, "toolChoice": true, "functionPrompt": "" } @@ -270,14 +275,15 @@ weight: 708 "name": "GPT35-1106", "maxContext": 1600, "maxResponse": 4000, - "price": 0 + "inputPrice": 0, + "outputPrice": 0, } ], "vectorModels": [ // 向量模型 { "model": "text-embedding-ada-002", "name": "Embedding-2", - "price": 0.2, + "inputPrice": 0, "defaultToken": 700, "maxToken": 3000 } @@ -287,7 +293,7 @@ weight: 708 { "model": "tts-1", "name": "OpenAI TTS1", - "price": 0, + "inputPrice": 0, "baseUrl": "", "key": "", "voices": [ @@ -303,7 +309,7 @@ weight: 708 "whisperModel": { "model": "whisper-1", "name": "Whisper1", - "price": 0 + "inputPrice": 0 } } ``` diff --git a/docSite/content/docs/development/qa.md b/docSite/content/docs/development/qa.md index b5178ab984c..5be3a5818b6 100644 --- a/docSite/content/docs/development/qa.md +++ b/docSite/content/docs/development/qa.md @@ -35,12 +35,16 @@ OneAPI 中没有配置该模型渠道。 ### 如何更新? -执行下面命令会自动拉取最新镜像,一般情况下不需要执行额外操作。 +1. 查看[更新文档](/docs/development/upgrading/intro/),确认要升级的版本,避免跨版本升级。 +2. 修改镜像 tag 到指定版本 +3. 执行下面命令会自动拉取镜像: -```bash -docker-compose pull -docker-compose up -d -``` + ```bash + docker-compose pull + docker-compose up -d + ``` + +4. 执行初始化脚本(如果有) ### 如何自定义配置文件? diff --git a/docSite/content/docs/development/sealos.md b/docSite/content/docs/development/sealos.md index 18ed6d70cc6..7b4d11c8113 100644 --- a/docSite/content/docs/development/sealos.md +++ b/docSite/content/docs/development/sealos.md @@ -59,14 +59,17 @@ FastGPT 商业版共包含了3个应用(fastgpt, fastgpt-plus, fastgpt-admin 例如,目前是4.5 版本,要升级到4.5.1,就先把镜像版本改成v4.5.1,执行一下升级脚本,等待完成后再继续升级。如果目标版本不需要执行初始化,则可以跳过。 升级步骤: -1. 打开sealos的应用管理 -2. 有3个应用 fastgpt , fastgpt-plugin 和 fastgpt-admin -3. 点击对应应用右边3个点,变更。或者点详情后右上角的变更。 -4. 修改镜像名栏 + +1. 查看[更新文档](/docs/development/upgrading/intro/),确认要升级的版本,避免跨版本升级。 +2. 打开 sealos 的应用管理 +3. 有2个应用 fastgpt , fastgpt-pro +4. 点击对应应用右边3个点,变更。或者点详情后右上角的变更。 +5. 修改镜像的版本号 + ![](/imgs/onsealos2.png) -5. 点击变更/重启,会自动拉取最新镜像进行更新 -6. 执行对应版本的初始化脚本 +6. 点击变更/重启,会自动拉取最新镜像进行更新 +7. 执行对应版本的初始化脚本(如果有) ### 如何获取 FastGPT 访问链接 @@ -88,34 +91,6 @@ FastGPT 商业版共包含了3个应用(fastgpt, fastgpt-plus, fastgpt-admin [配置文件参考](https://doc.fastgpt.in/docs/development/configuration/) -FeConfig 参考下面(目前未做可视化) -``` -"FeConfig": { - "show_emptyChat": false, // 是否展示聊天时空白的内容 - "show_register": true, // 展示注册按键 - "show_appStore": false, // 应用市场(暂时不可用) - "show_contact": false, // 联系方式(目前不可配置,直接false) - "show_git": false, // 展示 github - "show_doc": false, // 展示文档 - "show_pay": true, // 展示支付 - "show_openai_account": false, // 用户可自定义 openai key - "show_promotion": false, // 邀请好友机制 - "docUrl": "https://doc.fastgpt.in", // 文档基本地址 - "systemTitle": "FastGPT", // 系统的 title - "googleClientVerKey": "", // 谷歌 v3 校验前端凭证 - "isPlus": true, // 直接设置 true - "oauth": { // oauth登录 - "github": "", - "google": "" - }, - "limit": { - "exportLimitMinutes": 0 // 导出间隔限制 - }, - "scripts": [ - ] - } -``` - ### 修改站点名称以及 favicon 修改应用的环境变量,增加 @@ -134,6 +109,7 @@ SYSTEM_FAVICON 可以是一个网络地址 新增一个挂载文件,文件名为:/app/projects/app/public/icon/logo.svg ,值为 svg 对应的值。 ![](/imgs/onsealos7.png) + ![](/imgs/onsealos8.png) ### 管理后台 @@ -148,45 +124,8 @@ SYSTEM_FAVICON 可以是一个网络地址 "license": "", "system": { "title": "" // 系统名称 - }, - "censor": { - "BAIDU_TEXT_CENSOR_CLIENTID": "", // 百度文本安全校验 - "BAIDU_TEXT_CENSOR_CLIENTSECRET": "" // 百度文本安全校验 - }, - "auth": { - "googleServiceVerKey": "", // 谷歌 v3 校验 - "github": { // github oauth - "clientId": "", - "secret": "" - }, - "google": { // google oauth - "clientId": "", - "secret": "" - }, - "email": { // 注册邮箱配置 - "service": "qq", - "user": "", - "pass": "" - }, - "phone": { // 阿里短信配置 - "SNED_PHONE_ACCESSKEYID": "", - "SNED_PHONE_ACCESSSECRET": "", - "SNED_PHONE_SIGNNAME": "", - "SNED_PHONE_TEMPLATE": "" - } - }, - "pay": { // 微信支付配置 - "wx": { - "WX_APPID": "", - "WX_MCHID": "", - "WX_V3_CODE": "", - "WX_NOTIFY_URL": "", - "WX_SERIAL_NO": "", - "WX_PRIVATE_KEY": "" - } } } - ``` ### One API 使用 diff --git a/docSite/content/docs/development/upgrading/466.md b/docSite/content/docs/development/upgrading/466.md index 89aac365d0c..671a7e86d22 100644 --- a/docSite/content/docs/development/upgrading/466.md +++ b/docSite/content/docs/development/upgrading/466.md @@ -1,5 +1,5 @@ --- -title: 'V4.6.6-alpha(需要改配置文件)' +title: 'V4.6.6(需要改配置文件)' description: 'FastGPT V4.6.6' icon: 'upgrade' draft: false @@ -7,8 +7,6 @@ toc: true weight: 830 --- -**版本仍在开发中……** - ## 配置文件变更 为了减少代码重复度,我们对配置文件做了一些修改:[点击查看最新的配置文件](/docs/development/configuration/) @@ -18,4 +16,5 @@ weight: 830 1. 新增 - 搜索方式:分离向量语义检索,全文检索和重排,通过 RRF 进行排序合并。 2. 优化 - 问题分类提示词,id引导。测试国产商用 api 模型(百度阿里智谱讯飞)使用 Prompt 模式均可分类。 3. UI 优化,未来将逐步替换新的UI设计。 -4. 查看 [FastGPT 2024 RoadMap](https://github.com/labring/FastGPT?tab=readme-ov-file#-%E5%9C%A8%E7%BA%BF%E4%BD%BF%E7%94%A8) \ No newline at end of file +4. 优化代码:Icon 抽离和自动化获取。 +5. 查看 [FastGPT 2024 RoadMap](https://github.com/labring/FastGPT?tab=readme-ov-file#-%E5%9C%A8%E7%BA%BF%E4%BD%BF%E7%94%A8) \ No newline at end of file diff --git a/docSite/content/docs/use-cases/datasetEngine.md b/docSite/content/docs/use-cases/datasetEngine.md index 19fa4adddd0..959dec472ba 100644 --- a/docSite/content/docs/use-cases/datasetEngine.md +++ b/docSite/content/docs/use-cases/datasetEngine.md @@ -49,7 +49,7 @@ FastGPT 采用了 `PostgresSQL` 的 `PG Vector` 插件作为向量检索器, | 库 | 集合 | 数据 | | --- | --- | --- | -| ![](/imgs/datasetEngine1.png) | ![](/imgs/datasetEngine2.png) | ![](/imgs/datasetEngine3.png) | +| ![](/imgs/datasetEngine1.jpg) | ![](/imgs/datasetEngine2.jpg) | ![](/imgs/datasetEngine3.jpg) | ### 导入数据方案1 - 直接分段导入 @@ -57,7 +57,7 @@ FastGPT 采用了 `PostgresSQL` 的 `PG Vector` 插件作为向量检索器, | 交互 | 结果 | | --- | --- | -| ![](/imgs/datasetEngine4.png) | ![](/imgs/datasetEngine5.png) | +| ![](/imgs/datasetEngine4.jpg) | ![](/imgs/datasetEngine5.jpg) | ### 导入数据方案2 - QA导入 @@ -66,7 +66,7 @@ FastGPT 采用了 `PostgresSQL` 的 `PG Vector` 插件作为向量检索器, | 交互 | 结果 | | --- | --- | -| ![](/imgs/datasetEngine6.png) | ![](/imgs/datasetEngine7.png) | +| ![](/imgs/datasetEngine6.jpg) | ![](/imgs/datasetEngine7.jpg) | ### 导入数据方案3 - 手动录入 @@ -74,7 +74,7 @@ FastGPT 采用了 `PostgresSQL` 的 `PG Vector` 插件作为向量检索器, | | | | | --- | --- | --- | -| ![](/imgs/datasetEngine8.png) | ![](/imgs/datasetEngine9.png) | ![](/imgs/datasetEngine10.png) | +| ![](/imgs/datasetEngine8.jpg) | ![](/imgs/datasetEngine9.jpg) | ![](/imgs/datasetEngine10.jpg) | ### 导入数据方案4 - CSV录入 diff --git a/docSite/content/docs/use-cases/onwechat.md b/docSite/content/docs/use-cases/onwechat.md index 408f0f484ff..6d45ae25f0c 100644 --- a/docSite/content/docs/use-cases/onwechat.md +++ b/docSite/content/docs/use-cases/onwechat.md @@ -21,7 +21,7 @@ weight: 504 密钥需要自己保管好,一旦关闭就无法再复制密钥,只能创建新密钥再复制。 {{% /alert %}} -![](/imgs/fastgpt-api.png) +![](/imgs/fastgpt-api.jpg) ## 3. 创建 docker-compose.yml 文件 diff --git a/docSite/content/docs/use-cases/openapi.md b/docSite/content/docs/use-cases/openapi.md index 76b4bef804b..9dec264bbe6 100644 --- a/docSite/content/docs/use-cases/openapi.md +++ b/docSite/content/docs/use-cases/openapi.md @@ -15,7 +15,7 @@ weight: 505 密钥需要自己保管好,一旦关闭就无法再复制密钥,只能创建新密钥再复制。 {{% /alert %}} -![](/imgs/fastgpt-api.png) +![](/imgs/fastgpt-api.jpg) {{% alert icon="🍅" context="success" %}} Tips: 安全起见,你可以设置一个额度或者过期时间,放置 key 被滥用。 diff --git a/docSite/content/docs/workflow/examples/google_search.md b/docSite/content/docs/workflow/examples/google_search.md index 9568872fde7..6700b7cb143 100644 --- a/docSite/content/docs/workflow/examples/google_search.md +++ b/docSite/content/docs/workflow/examples/google_search.md @@ -9,7 +9,7 @@ weight: 402 | | | | --------------------- | --------------------- | -| ![](/imgs/google_search_1.png) | ![](/imgs/google_search_2.png) | +| ![](/imgs/google_search_1.jpg) | ![](/imgs/google_search_2.jpg) | 如上图,利用 HTTP 模块,你可以外接一个搜索引擎作为AI回复的参考资料。这里以调用 Google Search API 为例。注意:本文主要是为了介绍 HTTP 模型,具体的搜索效果需要依赖提示词和搜索引擎,尤其是【搜索引擎】,简单的搜索引擎无法获取更详细的内容,这部分可能需要更多的调试。 diff --git a/docSite/content/docs/workflow/examples/lab_appointment.md b/docSite/content/docs/workflow/examples/lab_appointment.md index 2ada07a319d..f7baeafbf55 100644 --- a/docSite/content/docs/workflow/examples/lab_appointment.md +++ b/docSite/content/docs/workflow/examples/lab_appointment.md @@ -9,8 +9,8 @@ weight: 403 | | | | --------------------- | --------------------- | -| ![](/imgs/demo-appointment1.png) | ![](/imgs/demo-appointment2.png) | -| ![](/imgs/demo-appointment3.png) | ![](/imgs/demo-appointment4.png) | +| ![](/imgs/demo-appointment1.jpg) | ![](/imgs/demo-appointment2.jpg) | +| ![](/imgs/demo-appointment3.jpg) | ![](/imgs/demo-appointment4.jpg) | @@ -26,7 +26,7 @@ weight: 403 ## 2. 问题分类 -![](/imgs/demo-appointment5.png) +![](/imgs/demo-appointment5.jpg) 如上图,用户问题作为对话的起点,流入【问题分类模块】,根据用户问题的内容,判断用户是询问实验室相关问题、预约实验室或其他问题。如果用户询问的是非实验问题,会直接拒绝回复内容。再根据问题是属于询问实验室相关/预约类问题,执行不同的流程。 @@ -43,7 +43,7 @@ weight: 403 | | | | | --------------------- | --------------------- |--------------------- | -| ![](/imgs/demo-appointment6.png) | ![](/imgs/demo-appointment7.png) | ![](/imgs/demo-appointment8.png) | +| ![](/imgs/demo-appointment6.jpg) | ![](/imgs/demo-appointment7.jpg) | ![](/imgs/demo-appointment8.jpg) | 内容提取是 LLM 带来的十分重要的能力,可以从自然语言中提取出结构化的数据,从而方便进行逻辑处理。 @@ -57,7 +57,7 @@ weight: 403 HTTP 模块允许你调用任意 GET/POST 类型的 HTTP 接口,从而实现一些复杂的业务逻辑。这里我们调用了一个预约实验室的接口,传入的是信息提取模块的结果和预约行为。 -![](/imgs/demo-appointment9.png) +![](/imgs/demo-appointment9.jpg) 具体的入参结构可以参考[HTTP模块](/docs/workflow/modules/http/),实在不行在接口里多打印 Debug。 diff --git a/docSite/content/docs/workflow/modules/coreferenceResolution.md b/docSite/content/docs/workflow/modules/coreferenceResolution.md index 5fe3ae801df..f0e9d6be28f 100644 --- a/docSite/content/docs/workflow/modules/coreferenceResolution.md +++ b/docSite/content/docs/workflow/modules/coreferenceResolution.md @@ -13,7 +13,7 @@ weight: 364 - 有外部输入 - 触发执行 -![](/imgs/coreferenceResolution1.png) +![](/imgs/coreferenceResolution1.jpg) ## 背景 @@ -21,11 +21,11 @@ weight: 364 在搜索的过程中,尤其是连续对话的搜索,我们通常会发现后续的问题难以搜索到合适的内容,其中一个原因是知识库搜索只会使用“当前”的问题去执行。看下面的例子: -![](/imgs/coreferenceResolution2.png) +![](/imgs/coreferenceResolution2.jpg) 用户在提问“第二点是什么”的时候,只会去知识库里查找“第二点是什么”,压根查不到内容。实际上需要查询的是“QA结构是什么”。因此我们需要引入一个【问题补全】模块,来对用户当前的问题进行补全,从而使得知识库搜索能够搜索到合适的内容。使用补全后效果如下: -![](/imgs/coreferenceResolution3.png) +![](/imgs/coreferenceResolution3.jpg) ## 功能 diff --git a/docSite/content/docs/workflow/modules/custom_feedback.md b/docSite/content/docs/workflow/modules/custom_feedback.md index e43d09577b8..c6733e95b63 100644 --- a/docSite/content/docs/workflow/modules/custom_feedback.md +++ b/docSite/content/docs/workflow/modules/custom_feedback.md @@ -18,8 +18,8 @@ weight: 354 | | | | --------------------- | --------------------- | -| ![](/imgs/customfeedback1.png) | ![](/imgs/customfeedback2.png) | -| ![](/imgs/customfeedback3.png) | ![](/imgs/customfeedback4.png) | +| ![](/imgs/customfeedback1.jpg) | ![](/imgs/customfeedback2.jpg) | +| ![](/imgs/customfeedback3.jpg) | ![](/imgs/customfeedback4.jpg) | ## 介绍 diff --git a/docSite/content/docs/workflow/modules/http.md b/docSite/content/docs/workflow/modules/http.md index 7ad57927b70..b2d627f2494 100644 --- a/docSite/content/docs/workflow/modules/http.md +++ b/docSite/content/docs/workflow/modules/http.md @@ -15,7 +15,7 @@ weight: 355 - 触发执行 - 核中核模块 -![](/imgs/http1.png) +![](/imgs/http1.jpg) ## 介绍 diff --git a/package.json b/package.json index 614c70596a2..617e266bc53 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,9 @@ "format-code": "prettier --config \"./.prettierrc.js\" --write \"./**/src/**/*.{ts,tsx,scss}\"", "format-doc": "zhlint --dir ./docSite *.md --fix", "gen:theme-typings": "chakra-cli tokens projects/app/src/web/styles/theme.ts --out node_modules/.pnpm/node_modules/@chakra-ui/styled-system/dist/theming.types.d.ts", - "postinstall": "sh ./scripts/postinstall.sh" + "postinstall": "sh ./scripts/postinstall.sh", + "initIcon": "node ./scripts/icon/init.js", + "previewIcon": "node ./scripts/icon/index.js" }, "devDependencies": { "@chakra-ui/cli": "^2.4.1", diff --git a/packages/global/core/module/template/system/coreferenceResolution.ts b/packages/global/core/module/template/system/coreferenceResolution.ts index 651d38b869c..1fe6e942415 100644 --- a/packages/global/core/module/template/system/coreferenceResolution.ts +++ b/packages/global/core/module/template/system/coreferenceResolution.ts @@ -42,7 +42,7 @@ export const AiCFR: FlowModuleTemplateType = { label: 'core.module.input.label.cfr background', max: 300, valueType: ModuleIOValueTypeEnum.string, - description: 'core.module.input.description.cfr background', + description: 'core.app.edit.cfr background tip', placeholder: 'core.module.input.placeholder.cfr background', showTargetInApp: true, showTargetInPlugin: true diff --git a/projects/app/src/components/Icon/close.tsx b/packages/web/components/common/Icon/close.tsx similarity index 78% rename from projects/app/src/components/Icon/close.tsx rename to packages/web/components/common/Icon/close.tsx index cb8e4eef82f..2c6f7f0f398 100644 --- a/projects/app/src/components/Icon/close.tsx +++ b/packages/web/components/common/Icon/close.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Flex, type FlexProps } from '@chakra-ui/react'; -import MyIcon from '@/components/Icon'; +import MyIcon from './index'; const CloseIcon = (props: FlexProps) => { return ( @@ -14,7 +14,7 @@ const CloseIcon = (props: FlexProps) => { _hover={{ bg: 'myGray.200' }} {...props} > - + ); }; diff --git a/projects/app/src/components/Icon/index.tsx b/packages/web/components/common/Icon/constants.ts similarity index 64% rename from projects/app/src/components/Icon/index.tsx rename to packages/web/components/common/Icon/constants.ts index ae342d3fe53..01ce497ae6b 100644 --- a/projects/app/src/components/Icon/index.tsx +++ b/packages/web/components/common/Icon/constants.ts @@ -1,159 +1,129 @@ -import React, { useEffect, useState } from 'react'; -import type { IconProps } from '@chakra-ui/react'; -import { Icon } from '@chakra-ui/react'; +// @ts-nocheck -const iconPaths = { - copy: () => import('./icons/copy.svg'), - delete: () => import('./icons/delete.svg'), - stop: () => import('./icons/stop.svg'), +export const iconPaths = { + chat: () => import('./icons/chat.svg'), + chatSend: () => import('./icons/chatSend.svg'), + closeSolid: () => import('./icons/closeSolid.svg'), collectionLight: () => import('./icons/collectionLight.svg'), collectionSolid: () => import('./icons/collectionSolid.svg'), - empty: () => import('./icons/empty.svg'), - back: () => import('./icons/back.svg'), - backFill: () => import('./icons/fill/back.svg'), - more: () => import('./icons/more.svg'), - tabbarChat: () => import('./icons/phoneTabbar/chat.svg'), - tabbarModel: () => import('./icons/phoneTabbar/app.svg'), - tabbarMore: () => import('./icons/phoneTabbar/more.svg'), - tabbarMe: () => import('./icons/phoneTabbar/me.svg'), - closeSolid: () => import('./icons/closeSolid.svg'), - wx: () => import('./icons/wx.svg'), - out: () => import('./icons/out.svg'), - git: () => import('./icons/git.svg'), - gitFill: () => import('./icons/fill/git.svg'), - googleFill: () => import('./icons/fill/google.svg'), - menu: () => import('./icons/menu.svg'), - edit: () => import('./icons/edit.svg'), - inform: () => import('./icons/inform.svg'), - export: () => import('./icons/export.svg'), - text: () => import('./icons/text.svg'), - history: () => import('./icons/history.svg'), - kbTest: () => import('./icons/kbTest.svg'), - date: () => import('./icons/date.svg'), - apikey: () => import('./icons/apikey.svg'), - apikeyFill: () => import('./icons/fill/apikey.svg'), - save: () => import('./icons/save.svg'), - minus: () => import('./icons/minus.svg'), - chat: () => import('./icons/light/chat.svg'), - chatFill: () => import('./icons/fill/chat.svg'), - clear: () => import('./icons/light/clear.svg'), - apiLight: () => import('./icons/light/appApi.svg'), - overviewLight: () => import('./icons/light/overview.svg'), - settingLight: () => import('./icons/light/setting.svg'), - shareLight: () => import('./icons/light/share.svg'), - dbLight: () => import('./icons/light/db.svg'), - dbFill: () => import('./icons/fill/db.svg'), - appStoreLight: () => import('./icons/light/appStore.svg'), - appStoreFill: () => import('./icons/fill/appStore.svg'), - meLight: () => import('./icons/light/me.svg'), - meFill: () => import('./icons/fill/me.svg'), - welcomeText: () => import('./icons/modules/welcomeText.svg'), - variable: () => import('./icons/modules/variable.svg'), - setTop: () => import('./icons/light/setTop.svg'), - fullScreenLight: () => import('./icons/light/fullScreen.svg'), - voice: () => import('./icons/voice.svg'), - html: () => import('./icons/file/html.svg'), - pdf: () => import('./icons/file/pdf.svg'), - markdown: () => import('./icons/file/markdown.svg'), - importLight: () => import('./icons/light/import.svg'), - manualImport: () => import('./icons/file/manualImport.svg'), - indexImport: () => import('./icons/file/indexImport.svg'), - csvImport: () => import('./icons/file/csv.svg'), - qaImport: () => import('./icons/file/qaImport.svg'), - uploadFile: () => import('./icons/file/uploadFile.svg'), - closeLight: () => import('./icons/light/close.svg'), - customTitle: () => import('./icons/light/customTitle.svg'), - billRecordLight: () => import('./icons/light/billRecord.svg'), - informLight: () => import('./icons/light/inform.svg'), - 'support/pay/payRecordLight': () => import('./icons/support/pay/payRecordLight.svg'), - 'support/account/loginoutLight': () => import('./icons/support/account/loginoutLight.svg'), - 'core/chat/chatModelTag': () => import('./icons/core/chat/chatModelTag.svg'), + 'common/addCircleLight': () => import('./icons/common/addCircleLight.svg'), + 'common/backFill': () => import('./icons/common/backFill.svg'), + 'common/backLight': () => import('./icons/common/backLight.svg'), + 'common/clearLight': () => import('./icons/common/clearLight.svg'), + 'common/closeLight': () => import('./icons/common/closeLight.svg'), + 'common/confirm/commonTip': () => import('./icons/common/confirm/commonTip.svg'), + 'common/confirm/deleteTip': () => import('./icons/common/confirm/deleteTip.svg'), + 'common/courseLight': () => import('./icons/common/courseLight.svg'), + 'common/customTitleLight': () => import('./icons/common/customTitleLight.svg'), + 'common/file/move': () => import('./icons/common/file/move.svg'), + 'common/fullScreenLight': () => import('./icons/common/fullScreenLight.svg'), + 'common/gitFill': () => import('./icons/common/gitFill.svg'), + 'common/gitLight': () => import('./icons/common/gitLight.svg'), + 'common/googleFill': () => import('./icons/common/googleFill.svg'), + 'common/importLight': () => import('./icons/common/importLight.svg'), + 'common/inviteLight': () => import('./icons/common/inviteLight.svg'), 'common/language/en': () => import('./icons/common/language/en.svg'), 'common/language/zh': () => import('./icons/common/language/zh.svg'), - 'support/outlink/shareLight': () => import('./icons/support/outlink/shareLight.svg'), - 'support/outlink/iframeLight': () => import('./icons/support/outlink/iframeLight.svg'), - 'common/addCircleLight': () => import('./icons/common/addCircleLight.svg'), + 'common/loading': () => import('./icons/common/loading.svg'), + 'common/navbar/pluginFill': () => import('./icons/common/navbar/pluginFill.svg'), + 'common/navbar/pluginLight': () => import('./icons/common/navbar/pluginLight.svg'), + 'common/overviewLight': () => import('./icons/common/overviewLight.svg'), 'common/playFill': () => import('./icons/common/playFill.svg'), - 'common/courseLight': () => import('./icons/common/courseLight.svg'), - 'support/account/promotionLight': () => import('./icons/support/account/promotionLight.svg'), - 'core/app/logsLight': () => import('./icons/core/app/logsLight.svg'), - 'core/chat/feedback/badLight': () => import('./icons/core/chat/feedback/badLight.svg'), - 'core/chat/feedback/goodLight': () => import('./icons/core/chat/feedback/goodLight.svg'), - 'core/app/markLight': () => import('./icons/core/app/markLight.svg'), + 'common/playLight': () => import('./icons/common/playLight.svg'), + 'common/questionLight': () => import('./icons/common/questionLight.svg'), + 'common/refreshLight': () => import('./icons/common/refreshLight.svg'), 'common/retryLight': () => import('./icons/common/retryLight.svg'), 'common/rightArrowLight': () => import('./icons/common/rightArrowLight.svg'), + 'common/routePushLight': () => import('./icons/common/routePushLight.svg'), 'common/searchLight': () => import('./icons/common/searchLight.svg'), - 'common/file/move': () => import('./icons/common/file/move.svg'), - 'core/app/questionGuide': () => import('./icons/core/app/questionGuide.svg'), - 'common/loading': () => import('./icons/common/loading.svg'), - 'core/app/aiLight': () => import('./icons/core/app/aiLight.svg'), - 'core/app/aiFill': () => import('./icons/core/app/aiFill.svg'), + 'common/settingLight': () => import('./icons/common/settingLight.svg'), 'common/text/t': () => import('./icons/common/text/t.svg'), - 'common/navbar/pluginLight': () => import('./icons/common/navbar/pluginLight.svg'), - 'common/navbar/pluginFill': () => import('./icons/common/navbar/pluginFill.svg'), - 'common/refreshLight': () => import('./icons/common/refreshLight.svg'), - 'core/module/previewLight': () => import('./icons/core/module/previewLight.svg'), - 'core/chat/quoteFill': () => import('./icons/core/chat/quoteFill.svg'), - 'core/chat/QGFill': () => import('./icons/core/chat/QGFill.svg'), 'common/tickFill': () => import('./icons/common/tickFill.svg'), - 'common/inviteLight': () => import('./icons/common/inviteLight.svg'), - 'support/team/memberLight': () => import('./icons/support/team/memberLight.svg'), - 'support/permission/privateLight': () => import('./icons/support/permission/privateLight.svg'), - 'support/permission/publicLight': () => import('./icons/support/permission/publicLight.svg'), - 'core/app/ttsFill': () => import('./icons/core/app/ttsFill.svg'), - 'core/app/tts': () => import('./icons/core/app/tts.svg'), + 'common/viewLight': () => import('./icons/common/viewLight.svg'), + 'common/voiceLight': () => import('./icons/common/voiceLight.svg'), + copy: () => import('./icons/copy.svg'), + 'core/app/aiFill': () => import('./icons/core/app/aiFill.svg'), + 'core/app/aiLight': () => import('./icons/core/app/aiLight.svg'), + 'core/app/appApiLight': () => import('./icons/core/app/appApiLight.svg'), + 'core/app/customFeedback': () => import('./icons/core/app/customFeedback.svg'), 'core/app/headphones': () => import('./icons/core/app/headphones.svg'), - 'common/playLight': () => import('./icons/common/playLight.svg'), + 'core/app/logsLight': () => import('./icons/core/app/logsLight.svg'), + 'core/app/markLight': () => import('./icons/core/app/markLight.svg'), + 'core/app/questionGuide': () => import('./icons/core/app/questionGuide.svg'), + 'core/app/tts': () => import('./icons/core/app/tts.svg'), + 'core/app/ttsFill': () => import('./icons/core/app/ttsFill.svg'), + 'core/app/variable/input': () => import('./icons/core/app/variable/input.svg'), + 'core/app/variable/select': () => import('./icons/core/app/variable/select.svg'), + 'core/app/variable/textarea': () => import('./icons/core/app/variable/textarea.svg'), + 'core/chat/QGFill': () => import('./icons/core/chat/QGFill.svg'), + 'core/chat/chatFill': () => import('./icons/core/chat/chatFill.svg'), + 'core/chat/chatLight': () => import('./icons/core/chat/chatLight.svg'), + 'core/chat/chatModelTag': () => import('./icons/core/chat/chatModelTag.svg'), + 'core/chat/feedback/badLight': () => import('./icons/core/chat/feedback/badLight.svg'), + 'core/chat/feedback/goodLight': () => import('./icons/core/chat/feedback/goodLight.svg'), + 'core/chat/fileSelect': () => import('./icons/core/chat/fileSelect.svg'), + 'core/chat/quoteFill': () => import('./icons/core/chat/quoteFill.svg'), 'core/chat/quoteSign': () => import('./icons/core/chat/quoteSign.svg'), - 'core/chat/sendLight': () => import('./icons/core/chat/sendLight.svg'), - 'core/chat/sendFill': () => import('./icons/core/chat/sendFill.svg'), 'core/chat/recordFill': () => import('./icons/core/chat/recordFill.svg'), - 'core/chat/stopSpeechFill': () => import('./icons/core/chat/stopSpeechFill.svg'), - 'core/chat/stopSpeech': () => import('./icons/core/chat/stopSpeech.svg'), + 'core/chat/sendFill': () => import('./icons/core/chat/sendFill.svg'), + 'core/chat/sendLight': () => import('./icons/core/chat/sendLight.svg'), + 'core/chat/setTopLight': () => import('./icons/core/chat/setTopLight.svg'), 'core/chat/speaking': () => import('./icons/core/chat/speaking.svg'), - 'core/chat/fileSelect': () => import('./icons/core/chat/fileSelect.svg'), - 'core/dataset/modeEmbedding': () => import('./icons/core/dataset/modeEmbedding.svg'), + 'core/chat/stopSpeech': () => import('./icons/core/chat/stopSpeech.svg'), + 'core/chat/stopSpeechFill': () => import('./icons/core/chat/stopSpeechFill.svg'), + 'core/dataset/commonDataset': () => import('./icons/core/dataset/commonDataset.svg'), + 'core/dataset/datasetFill': () => import('./icons/core/dataset/datasetFill.svg'), + 'core/dataset/datasetLight': () => import('./icons/core/dataset/datasetLight.svg'), + 'core/dataset/folderDataset': () => import('./icons/core/dataset/folderDataset.svg'), 'core/dataset/fullTextRecall': () => import('./icons/core/dataset/fullTextRecall.svg'), 'core/dataset/mixedRecall': () => import('./icons/core/dataset/mixedRecall.svg'), - 'core/app/variable/input': () => import('./icons/core/app/variable/input.svg'), - 'core/app/variable/textarea': () => import('./icons/core/app/variable/textarea.svg'), - 'core/app/variable/select': () => import('./icons/core/app/variable/select.svg'), + 'core/dataset/modeEmbedding': () => import('./icons/core/dataset/modeEmbedding.svg'), + 'core/dataset/rerank': () => import('./icons/core/dataset/rerank.svg'), 'core/dataset/websiteDataset': () => import('./icons/core/dataset/websiteDataset.svg'), - 'core/dataset/commonDataset': () => import('./icons/core/dataset/commonDataset.svg'), - 'core/dataset/folderDataset': () => import('./icons/core/dataset/folderDataset.svg'), - 'common/confirm/deleteTip': () => import('./icons/common/confirm/deleteTip.svg'), - 'common/confirm/commonTip': () => import('./icons/common/confirm/commonTip.svg'), - 'common/routePushLight': () => import('./icons/common/routePushLight.svg'), - 'common/viewLight': () => import('./icons/common/viewLight.svg'), - 'core/app/customFeedback': () => import('./icons/core/app/customFeedback.svg'), + 'core/modules/previewLight': () => import('./icons/core/modules/previewLight.svg'), + 'core/modules/variable': () => import('./icons/core/modules/variable.svg'), + 'core/modules/welcomeText': () => import('./icons/core/modules/welcomeText.svg'), + date: () => import('./icons/date.svg'), + delete: () => import('./icons/delete.svg'), + edit: () => import('./icons/edit.svg'), + empty: () => import('./icons/empty.svg'), + export: () => import('./icons/export.svg'), + 'file/csv': () => import('./icons/file/csv.svg'), + 'file/html': () => import('./icons/file/html.svg'), + 'file/indexImport': () => import('./icons/file/indexImport.svg'), + 'file/manualImport': () => import('./icons/file/manualImport.svg'), + 'file/markdown': () => import('./icons/file/markdown.svg'), + 'file/pdf': () => import('./icons/file/pdf.svg'), + 'file/qaImport': () => import('./icons/file/qaImport.svg'), + 'file/uploadFile': () => import('./icons/file/uploadFile.svg'), + history: () => import('./icons/history.svg'), + inform: () => import('./icons/inform.svg'), + kbTest: () => import('./icons/kbTest.svg'), + menu: () => import('./icons/menu.svg'), + minus: () => import('./icons/minus.svg'), + more: () => import('./icons/more.svg'), + out: () => import('./icons/out.svg'), + 'phoneTabbar/me': () => import('./icons/phoneTabbar/me.svg'), + 'phoneTabbar/more': () => import('./icons/phoneTabbar/more.svg'), + save: () => import('./icons/save.svg'), + stop: () => import('./icons/stop.svg'), + 'support/account/loginoutLight': () => import('./icons/support/account/loginoutLight.svg'), + 'support/account/promotionLight': () => import('./icons/support/account/promotionLight.svg'), + 'support/bill/billRecordLight': () => import('./icons/support/bill/billRecordLight.svg'), + 'support/outlink/apikeyFill': () => import('./icons/support/outlink/apikeyFill.svg'), + 'support/outlink/apikeyLight': () => import('./icons/support/outlink/apikeyLight.svg'), + 'support/outlink/iframeLight': () => import('./icons/support/outlink/iframeLight.svg'), + 'support/outlink/share': () => import('./icons/support/outlink/share.svg'), + 'support/outlink/shareLight': () => import('./icons/support/outlink/shareLight.svg'), + 'support/pay/payRecordLight': () => import('./icons/support/pay/payRecordLight.svg'), 'support/pay/priceLight': () => import('./icons/support/pay/priceLight.svg'), - 'core/dataset/rerank': () => import('./icons/core/dataset/rerank.svg') -}; - -export type IconName = keyof typeof iconPaths; - -const MyIcon = ({ name, w = 'auto', h = 'auto', ...props }: { name: IconName } & IconProps) => { - const [IconComponent, setIconComponent] = useState(null); - - useEffect(() => { - iconPaths[name]?.() - .then((icon) => { - setIconComponent({ as: icon.default }); - }) - .catch((error) => console.log(error)); - }, [name]); - - return !!name && !!iconPaths[name] ? ( - - ) : null; + 'support/permission/privateLight': () => import('./icons/support/permission/privateLight.svg'), + 'support/permission/publicLight': () => import('./icons/support/permission/publicLight.svg'), + 'support/team/memberLight': () => import('./icons/support/team/memberLight.svg'), + 'support/user/informLight': () => import('./icons/support/user/informLight.svg'), + 'support/user/userFill': () => import('./icons/support/user/userFill.svg'), + 'support/user/userLight': () => import('./icons/support/user/userLight.svg'), + text: () => import('./icons/text.svg'), + user: () => import('./icons/user.svg'), + wx: () => import('./icons/wx.svg') }; - -export default MyIcon; diff --git a/projects/app/src/components/Icon/delete.tsx b/packages/web/components/common/Icon/delete.tsx similarity index 91% rename from projects/app/src/components/Icon/delete.tsx rename to packages/web/components/common/Icon/delete.tsx index 236934c91a8..1e52ae802fc 100644 --- a/projects/app/src/components/Icon/delete.tsx +++ b/packages/web/components/common/Icon/delete.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import MyIcon from '@/components/Icon'; +import MyIcon from './index'; import { IconProps } from '@chakra-ui/react'; const DeleteIcon = (props: IconProps) => { diff --git a/projects/app/src/components/Icon/icons/chat.svg b/packages/web/components/common/Icon/icons/chat.svg similarity index 100% rename from projects/app/src/components/Icon/icons/chat.svg rename to packages/web/components/common/Icon/icons/chat.svg diff --git a/projects/app/src/components/Icon/icons/chatSend.svg b/packages/web/components/common/Icon/icons/chatSend.svg similarity index 100% rename from projects/app/src/components/Icon/icons/chatSend.svg rename to packages/web/components/common/Icon/icons/chatSend.svg diff --git a/projects/app/src/components/Icon/icons/closeSolid.svg b/packages/web/components/common/Icon/icons/closeSolid.svg similarity index 100% rename from projects/app/src/components/Icon/icons/closeSolid.svg rename to packages/web/components/common/Icon/icons/closeSolid.svg diff --git a/projects/app/src/components/Icon/icons/collectionLight.svg b/packages/web/components/common/Icon/icons/collectionLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/collectionLight.svg rename to packages/web/components/common/Icon/icons/collectionLight.svg diff --git a/projects/app/src/components/Icon/icons/collectionSolid.svg b/packages/web/components/common/Icon/icons/collectionSolid.svg similarity index 100% rename from projects/app/src/components/Icon/icons/collectionSolid.svg rename to packages/web/components/common/Icon/icons/collectionSolid.svg diff --git a/projects/app/src/components/Icon/icons/common/addCircleLight.svg b/packages/web/components/common/Icon/icons/common/addCircleLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/addCircleLight.svg rename to packages/web/components/common/Icon/icons/common/addCircleLight.svg diff --git a/projects/app/src/components/Icon/icons/fill/back.svg b/packages/web/components/common/Icon/icons/common/backFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/fill/back.svg rename to packages/web/components/common/Icon/icons/common/backFill.svg diff --git a/projects/app/src/components/Icon/icons/back.svg b/packages/web/components/common/Icon/icons/common/backLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/back.svg rename to packages/web/components/common/Icon/icons/common/backLight.svg diff --git a/projects/app/src/components/Icon/icons/light/clear.svg b/packages/web/components/common/Icon/icons/common/clearLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/clear.svg rename to packages/web/components/common/Icon/icons/common/clearLight.svg diff --git a/projects/app/src/components/Icon/icons/light/close.svg b/packages/web/components/common/Icon/icons/common/closeLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/close.svg rename to packages/web/components/common/Icon/icons/common/closeLight.svg diff --git a/projects/app/src/components/Icon/icons/common/confirm/commonTip.svg b/packages/web/components/common/Icon/icons/common/confirm/commonTip.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/confirm/commonTip.svg rename to packages/web/components/common/Icon/icons/common/confirm/commonTip.svg diff --git a/projects/app/src/components/Icon/icons/common/confirm/deleteTip.svg b/packages/web/components/common/Icon/icons/common/confirm/deleteTip.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/confirm/deleteTip.svg rename to packages/web/components/common/Icon/icons/common/confirm/deleteTip.svg diff --git a/projects/app/src/components/Icon/icons/common/courseLight.svg b/packages/web/components/common/Icon/icons/common/courseLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/courseLight.svg rename to packages/web/components/common/Icon/icons/common/courseLight.svg diff --git a/projects/app/src/components/Icon/icons/light/customTitle.svg b/packages/web/components/common/Icon/icons/common/customTitleLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/customTitle.svg rename to packages/web/components/common/Icon/icons/common/customTitleLight.svg diff --git a/projects/app/src/components/Icon/icons/common/file/move.svg b/packages/web/components/common/Icon/icons/common/file/move.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/file/move.svg rename to packages/web/components/common/Icon/icons/common/file/move.svg diff --git a/projects/app/src/components/Icon/icons/light/fullScreen.svg b/packages/web/components/common/Icon/icons/common/fullScreenLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/fullScreen.svg rename to packages/web/components/common/Icon/icons/common/fullScreenLight.svg diff --git a/projects/app/src/components/Icon/icons/fill/git.svg b/packages/web/components/common/Icon/icons/common/gitFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/fill/git.svg rename to packages/web/components/common/Icon/icons/common/gitFill.svg diff --git a/projects/app/src/components/Icon/icons/git.svg b/packages/web/components/common/Icon/icons/common/gitLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/git.svg rename to packages/web/components/common/Icon/icons/common/gitLight.svg diff --git a/projects/app/src/components/Icon/icons/fill/google.svg b/packages/web/components/common/Icon/icons/common/googleFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/fill/google.svg rename to packages/web/components/common/Icon/icons/common/googleFill.svg diff --git a/projects/app/src/components/Icon/icons/light/import.svg b/packages/web/components/common/Icon/icons/common/importLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/import.svg rename to packages/web/components/common/Icon/icons/common/importLight.svg diff --git a/projects/app/src/components/Icon/icons/common/inviteLight.svg b/packages/web/components/common/Icon/icons/common/inviteLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/inviteLight.svg rename to packages/web/components/common/Icon/icons/common/inviteLight.svg diff --git a/projects/app/src/components/Icon/icons/common/language/en.svg b/packages/web/components/common/Icon/icons/common/language/en.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/language/en.svg rename to packages/web/components/common/Icon/icons/common/language/en.svg diff --git a/projects/app/src/components/Icon/icons/common/language/zh.svg b/packages/web/components/common/Icon/icons/common/language/zh.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/language/zh.svg rename to packages/web/components/common/Icon/icons/common/language/zh.svg diff --git a/projects/app/src/components/Icon/icons/common/loading.svg b/packages/web/components/common/Icon/icons/common/loading.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/loading.svg rename to packages/web/components/common/Icon/icons/common/loading.svg diff --git a/projects/app/src/components/Icon/icons/common/navbar/pluginFill.svg b/packages/web/components/common/Icon/icons/common/navbar/pluginFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/navbar/pluginFill.svg rename to packages/web/components/common/Icon/icons/common/navbar/pluginFill.svg diff --git a/projects/app/src/components/Icon/icons/common/navbar/pluginLight.svg b/packages/web/components/common/Icon/icons/common/navbar/pluginLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/navbar/pluginLight.svg rename to packages/web/components/common/Icon/icons/common/navbar/pluginLight.svg diff --git a/projects/app/src/components/Icon/icons/light/overview.svg b/packages/web/components/common/Icon/icons/common/overviewLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/overview.svg rename to packages/web/components/common/Icon/icons/common/overviewLight.svg diff --git a/projects/app/src/components/Icon/icons/common/playFill.svg b/packages/web/components/common/Icon/icons/common/playFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/playFill.svg rename to packages/web/components/common/Icon/icons/common/playFill.svg diff --git a/projects/app/src/components/Icon/icons/common/playLight.svg b/packages/web/components/common/Icon/icons/common/playLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/playLight.svg rename to packages/web/components/common/Icon/icons/common/playLight.svg diff --git a/packages/web/components/common/Icon/icons/common/questionLight.svg b/packages/web/components/common/Icon/icons/common/questionLight.svg new file mode 100644 index 00000000000..f6fc6095eba --- /dev/null +++ b/packages/web/components/common/Icon/icons/common/questionLight.svg @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/projects/app/src/components/Icon/icons/common/refreshLight.svg b/packages/web/components/common/Icon/icons/common/refreshLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/refreshLight.svg rename to packages/web/components/common/Icon/icons/common/refreshLight.svg diff --git a/projects/app/src/components/Icon/icons/common/retryLight.svg b/packages/web/components/common/Icon/icons/common/retryLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/retryLight.svg rename to packages/web/components/common/Icon/icons/common/retryLight.svg diff --git a/projects/app/src/components/Icon/icons/common/rightArrowLight.svg b/packages/web/components/common/Icon/icons/common/rightArrowLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/rightArrowLight.svg rename to packages/web/components/common/Icon/icons/common/rightArrowLight.svg diff --git a/projects/app/src/components/Icon/icons/common/routePushLight.svg b/packages/web/components/common/Icon/icons/common/routePushLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/routePushLight.svg rename to packages/web/components/common/Icon/icons/common/routePushLight.svg diff --git a/projects/app/src/components/Icon/icons/common/searchLight.svg b/packages/web/components/common/Icon/icons/common/searchLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/searchLight.svg rename to packages/web/components/common/Icon/icons/common/searchLight.svg diff --git a/projects/app/src/components/Icon/icons/light/setting.svg b/packages/web/components/common/Icon/icons/common/settingLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/setting.svg rename to packages/web/components/common/Icon/icons/common/settingLight.svg diff --git a/projects/app/src/components/Icon/icons/common/text/t.svg b/packages/web/components/common/Icon/icons/common/text/t.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/text/t.svg rename to packages/web/components/common/Icon/icons/common/text/t.svg diff --git a/projects/app/src/components/Icon/icons/common/tickFill.svg b/packages/web/components/common/Icon/icons/common/tickFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/tickFill.svg rename to packages/web/components/common/Icon/icons/common/tickFill.svg diff --git a/projects/app/src/components/Icon/icons/common/viewLight.svg b/packages/web/components/common/Icon/icons/common/viewLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/common/viewLight.svg rename to packages/web/components/common/Icon/icons/common/viewLight.svg diff --git a/projects/app/src/components/Icon/icons/voice.svg b/packages/web/components/common/Icon/icons/common/voiceLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/voice.svg rename to packages/web/components/common/Icon/icons/common/voiceLight.svg diff --git a/projects/app/src/components/Icon/icons/copy.svg b/packages/web/components/common/Icon/icons/copy.svg similarity index 100% rename from projects/app/src/components/Icon/icons/copy.svg rename to packages/web/components/common/Icon/icons/copy.svg diff --git a/projects/app/src/components/Icon/icons/core/app/aiFill.svg b/packages/web/components/common/Icon/icons/core/app/aiFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/app/aiFill.svg rename to packages/web/components/common/Icon/icons/core/app/aiFill.svg diff --git a/projects/app/src/components/Icon/icons/core/app/aiLight.svg b/packages/web/components/common/Icon/icons/core/app/aiLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/app/aiLight.svg rename to packages/web/components/common/Icon/icons/core/app/aiLight.svg diff --git a/projects/app/src/components/Icon/icons/light/appApi.svg b/packages/web/components/common/Icon/icons/core/app/appApiLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/appApi.svg rename to packages/web/components/common/Icon/icons/core/app/appApiLight.svg diff --git a/projects/app/src/components/Icon/icons/core/app/customFeedback.svg b/packages/web/components/common/Icon/icons/core/app/customFeedback.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/app/customFeedback.svg rename to packages/web/components/common/Icon/icons/core/app/customFeedback.svg diff --git a/projects/app/src/components/Icon/icons/core/app/headphones.svg b/packages/web/components/common/Icon/icons/core/app/headphones.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/app/headphones.svg rename to packages/web/components/common/Icon/icons/core/app/headphones.svg diff --git a/projects/app/src/components/Icon/icons/core/app/logsLight.svg b/packages/web/components/common/Icon/icons/core/app/logsLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/app/logsLight.svg rename to packages/web/components/common/Icon/icons/core/app/logsLight.svg diff --git a/projects/app/src/components/Icon/icons/core/app/markLight.svg b/packages/web/components/common/Icon/icons/core/app/markLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/app/markLight.svg rename to packages/web/components/common/Icon/icons/core/app/markLight.svg diff --git a/projects/app/src/components/Icon/icons/core/app/questionGuide.svg b/packages/web/components/common/Icon/icons/core/app/questionGuide.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/app/questionGuide.svg rename to packages/web/components/common/Icon/icons/core/app/questionGuide.svg diff --git a/projects/app/src/components/Icon/icons/core/app/tts.svg b/packages/web/components/common/Icon/icons/core/app/tts.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/app/tts.svg rename to packages/web/components/common/Icon/icons/core/app/tts.svg diff --git a/projects/app/src/components/Icon/icons/core/app/ttsFill.svg b/packages/web/components/common/Icon/icons/core/app/ttsFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/app/ttsFill.svg rename to packages/web/components/common/Icon/icons/core/app/ttsFill.svg diff --git a/projects/app/src/components/Icon/icons/core/app/variable/input.svg b/packages/web/components/common/Icon/icons/core/app/variable/input.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/app/variable/input.svg rename to packages/web/components/common/Icon/icons/core/app/variable/input.svg diff --git a/projects/app/src/components/Icon/icons/core/app/variable/select.svg b/packages/web/components/common/Icon/icons/core/app/variable/select.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/app/variable/select.svg rename to packages/web/components/common/Icon/icons/core/app/variable/select.svg diff --git a/projects/app/src/components/Icon/icons/core/app/variable/textarea.svg b/packages/web/components/common/Icon/icons/core/app/variable/textarea.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/app/variable/textarea.svg rename to packages/web/components/common/Icon/icons/core/app/variable/textarea.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/QGFill.svg b/packages/web/components/common/Icon/icons/core/chat/QGFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/QGFill.svg rename to packages/web/components/common/Icon/icons/core/chat/QGFill.svg diff --git a/projects/app/src/components/Icon/icons/fill/chat.svg b/packages/web/components/common/Icon/icons/core/chat/chatFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/fill/chat.svg rename to packages/web/components/common/Icon/icons/core/chat/chatFill.svg diff --git a/projects/app/src/components/Icon/icons/light/chat.svg b/packages/web/components/common/Icon/icons/core/chat/chatLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/chat.svg rename to packages/web/components/common/Icon/icons/core/chat/chatLight.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/chatModelTag.svg b/packages/web/components/common/Icon/icons/core/chat/chatModelTag.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/chatModelTag.svg rename to packages/web/components/common/Icon/icons/core/chat/chatModelTag.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/feedback/badLight.svg b/packages/web/components/common/Icon/icons/core/chat/feedback/badLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/feedback/badLight.svg rename to packages/web/components/common/Icon/icons/core/chat/feedback/badLight.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/feedback/goodLight.svg b/packages/web/components/common/Icon/icons/core/chat/feedback/goodLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/feedback/goodLight.svg rename to packages/web/components/common/Icon/icons/core/chat/feedback/goodLight.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/fileSelect.svg b/packages/web/components/common/Icon/icons/core/chat/fileSelect.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/fileSelect.svg rename to packages/web/components/common/Icon/icons/core/chat/fileSelect.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/quoteFill.svg b/packages/web/components/common/Icon/icons/core/chat/quoteFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/quoteFill.svg rename to packages/web/components/common/Icon/icons/core/chat/quoteFill.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/quoteSign.svg b/packages/web/components/common/Icon/icons/core/chat/quoteSign.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/quoteSign.svg rename to packages/web/components/common/Icon/icons/core/chat/quoteSign.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/recordFill.svg b/packages/web/components/common/Icon/icons/core/chat/recordFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/recordFill.svg rename to packages/web/components/common/Icon/icons/core/chat/recordFill.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/sendFill.svg b/packages/web/components/common/Icon/icons/core/chat/sendFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/sendFill.svg rename to packages/web/components/common/Icon/icons/core/chat/sendFill.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/sendLight.svg b/packages/web/components/common/Icon/icons/core/chat/sendLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/sendLight.svg rename to packages/web/components/common/Icon/icons/core/chat/sendLight.svg diff --git a/projects/app/src/components/Icon/icons/light/setTop.svg b/packages/web/components/common/Icon/icons/core/chat/setTopLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/setTop.svg rename to packages/web/components/common/Icon/icons/core/chat/setTopLight.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/speaking.svg b/packages/web/components/common/Icon/icons/core/chat/speaking.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/speaking.svg rename to packages/web/components/common/Icon/icons/core/chat/speaking.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/stopSpeech.svg b/packages/web/components/common/Icon/icons/core/chat/stopSpeech.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/stopSpeech.svg rename to packages/web/components/common/Icon/icons/core/chat/stopSpeech.svg diff --git a/projects/app/src/components/Icon/icons/core/chat/stopSpeechFill.svg b/packages/web/components/common/Icon/icons/core/chat/stopSpeechFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/chat/stopSpeechFill.svg rename to packages/web/components/common/Icon/icons/core/chat/stopSpeechFill.svg diff --git a/projects/app/src/components/Icon/icons/core/dataset/commonDataset.svg b/packages/web/components/common/Icon/icons/core/dataset/commonDataset.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/dataset/commonDataset.svg rename to packages/web/components/common/Icon/icons/core/dataset/commonDataset.svg diff --git a/projects/app/src/components/Icon/icons/fill/db.svg b/packages/web/components/common/Icon/icons/core/dataset/datasetFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/fill/db.svg rename to packages/web/components/common/Icon/icons/core/dataset/datasetFill.svg diff --git a/projects/app/src/components/Icon/icons/light/db.svg b/packages/web/components/common/Icon/icons/core/dataset/datasetLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/db.svg rename to packages/web/components/common/Icon/icons/core/dataset/datasetLight.svg diff --git a/projects/app/src/components/Icon/icons/core/dataset/folderDataset.svg b/packages/web/components/common/Icon/icons/core/dataset/folderDataset.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/dataset/folderDataset.svg rename to packages/web/components/common/Icon/icons/core/dataset/folderDataset.svg diff --git a/projects/app/src/components/Icon/icons/core/dataset/fullTextRecall.svg b/packages/web/components/common/Icon/icons/core/dataset/fullTextRecall.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/dataset/fullTextRecall.svg rename to packages/web/components/common/Icon/icons/core/dataset/fullTextRecall.svg diff --git a/projects/app/src/components/Icon/icons/core/dataset/mixedRecall.svg b/packages/web/components/common/Icon/icons/core/dataset/mixedRecall.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/dataset/mixedRecall.svg rename to packages/web/components/common/Icon/icons/core/dataset/mixedRecall.svg diff --git a/projects/app/src/components/Icon/icons/core/dataset/modeEmbedding.svg b/packages/web/components/common/Icon/icons/core/dataset/modeEmbedding.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/dataset/modeEmbedding.svg rename to packages/web/components/common/Icon/icons/core/dataset/modeEmbedding.svg diff --git a/projects/app/src/components/Icon/icons/core/dataset/rerank.svg b/packages/web/components/common/Icon/icons/core/dataset/rerank.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/dataset/rerank.svg rename to packages/web/components/common/Icon/icons/core/dataset/rerank.svg diff --git a/projects/app/src/components/Icon/icons/core/dataset/websiteDataset.svg b/packages/web/components/common/Icon/icons/core/dataset/websiteDataset.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/dataset/websiteDataset.svg rename to packages/web/components/common/Icon/icons/core/dataset/websiteDataset.svg diff --git a/projects/app/src/components/Icon/icons/core/module/previewLight.svg b/packages/web/components/common/Icon/icons/core/modules/previewLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/core/module/previewLight.svg rename to packages/web/components/common/Icon/icons/core/modules/previewLight.svg diff --git a/projects/app/src/components/Icon/icons/modules/variable.svg b/packages/web/components/common/Icon/icons/core/modules/variable.svg similarity index 100% rename from projects/app/src/components/Icon/icons/modules/variable.svg rename to packages/web/components/common/Icon/icons/core/modules/variable.svg diff --git a/projects/app/src/components/Icon/icons/modules/welcomeText.svg b/packages/web/components/common/Icon/icons/core/modules/welcomeText.svg similarity index 100% rename from projects/app/src/components/Icon/icons/modules/welcomeText.svg rename to packages/web/components/common/Icon/icons/core/modules/welcomeText.svg diff --git a/projects/app/src/components/Icon/icons/date.svg b/packages/web/components/common/Icon/icons/date.svg similarity index 100% rename from projects/app/src/components/Icon/icons/date.svg rename to packages/web/components/common/Icon/icons/date.svg diff --git a/projects/app/src/components/Icon/icons/delete.svg b/packages/web/components/common/Icon/icons/delete.svg similarity index 100% rename from projects/app/src/components/Icon/icons/delete.svg rename to packages/web/components/common/Icon/icons/delete.svg diff --git a/projects/app/src/components/Icon/icons/edit.svg b/packages/web/components/common/Icon/icons/edit.svg similarity index 100% rename from projects/app/src/components/Icon/icons/edit.svg rename to packages/web/components/common/Icon/icons/edit.svg diff --git a/projects/app/src/components/Icon/icons/empty.svg b/packages/web/components/common/Icon/icons/empty.svg similarity index 100% rename from projects/app/src/components/Icon/icons/empty.svg rename to packages/web/components/common/Icon/icons/empty.svg diff --git a/projects/app/src/components/Icon/icons/export.svg b/packages/web/components/common/Icon/icons/export.svg similarity index 100% rename from projects/app/src/components/Icon/icons/export.svg rename to packages/web/components/common/Icon/icons/export.svg diff --git a/projects/app/src/components/Icon/icons/file/csv.svg b/packages/web/components/common/Icon/icons/file/csv.svg similarity index 100% rename from projects/app/src/components/Icon/icons/file/csv.svg rename to packages/web/components/common/Icon/icons/file/csv.svg diff --git a/projects/app/src/components/Icon/icons/file/html.svg b/packages/web/components/common/Icon/icons/file/html.svg similarity index 100% rename from projects/app/src/components/Icon/icons/file/html.svg rename to packages/web/components/common/Icon/icons/file/html.svg diff --git a/projects/app/src/components/Icon/icons/file/indexImport.svg b/packages/web/components/common/Icon/icons/file/indexImport.svg similarity index 100% rename from projects/app/src/components/Icon/icons/file/indexImport.svg rename to packages/web/components/common/Icon/icons/file/indexImport.svg diff --git a/projects/app/src/components/Icon/icons/file/manualImport.svg b/packages/web/components/common/Icon/icons/file/manualImport.svg similarity index 100% rename from projects/app/src/components/Icon/icons/file/manualImport.svg rename to packages/web/components/common/Icon/icons/file/manualImport.svg diff --git a/projects/app/src/components/Icon/icons/file/markdown.svg b/packages/web/components/common/Icon/icons/file/markdown.svg similarity index 100% rename from projects/app/src/components/Icon/icons/file/markdown.svg rename to packages/web/components/common/Icon/icons/file/markdown.svg diff --git a/projects/app/src/components/Icon/icons/file/pdf.svg b/packages/web/components/common/Icon/icons/file/pdf.svg similarity index 100% rename from projects/app/src/components/Icon/icons/file/pdf.svg rename to packages/web/components/common/Icon/icons/file/pdf.svg diff --git a/projects/app/src/components/Icon/icons/file/qaImport.svg b/packages/web/components/common/Icon/icons/file/qaImport.svg similarity index 100% rename from projects/app/src/components/Icon/icons/file/qaImport.svg rename to packages/web/components/common/Icon/icons/file/qaImport.svg diff --git a/projects/app/src/components/Icon/icons/file/uploadFile.svg b/packages/web/components/common/Icon/icons/file/uploadFile.svg similarity index 100% rename from projects/app/src/components/Icon/icons/file/uploadFile.svg rename to packages/web/components/common/Icon/icons/file/uploadFile.svg diff --git a/projects/app/src/components/Icon/icons/history.svg b/packages/web/components/common/Icon/icons/history.svg similarity index 100% rename from projects/app/src/components/Icon/icons/history.svg rename to packages/web/components/common/Icon/icons/history.svg diff --git a/projects/app/src/components/Icon/icons/inform.svg b/packages/web/components/common/Icon/icons/inform.svg similarity index 100% rename from projects/app/src/components/Icon/icons/inform.svg rename to packages/web/components/common/Icon/icons/inform.svg diff --git a/projects/app/src/components/Icon/icons/kbTest.svg b/packages/web/components/common/Icon/icons/kbTest.svg similarity index 100% rename from projects/app/src/components/Icon/icons/kbTest.svg rename to packages/web/components/common/Icon/icons/kbTest.svg diff --git a/projects/app/src/components/Icon/icons/menu.svg b/packages/web/components/common/Icon/icons/menu.svg similarity index 100% rename from projects/app/src/components/Icon/icons/menu.svg rename to packages/web/components/common/Icon/icons/menu.svg diff --git a/projects/app/src/components/Icon/icons/minus.svg b/packages/web/components/common/Icon/icons/minus.svg similarity index 100% rename from projects/app/src/components/Icon/icons/minus.svg rename to packages/web/components/common/Icon/icons/minus.svg diff --git a/projects/app/src/components/Icon/icons/more.svg b/packages/web/components/common/Icon/icons/more.svg similarity index 100% rename from projects/app/src/components/Icon/icons/more.svg rename to packages/web/components/common/Icon/icons/more.svg diff --git a/projects/app/src/components/Icon/icons/out.svg b/packages/web/components/common/Icon/icons/out.svg similarity index 100% rename from projects/app/src/components/Icon/icons/out.svg rename to packages/web/components/common/Icon/icons/out.svg diff --git a/projects/app/src/components/Icon/icons/phoneTabbar/me.svg b/packages/web/components/common/Icon/icons/phoneTabbar/me.svg similarity index 100% rename from projects/app/src/components/Icon/icons/phoneTabbar/me.svg rename to packages/web/components/common/Icon/icons/phoneTabbar/me.svg diff --git a/projects/app/src/components/Icon/icons/phoneTabbar/more.svg b/packages/web/components/common/Icon/icons/phoneTabbar/more.svg similarity index 100% rename from projects/app/src/components/Icon/icons/phoneTabbar/more.svg rename to packages/web/components/common/Icon/icons/phoneTabbar/more.svg diff --git a/projects/app/src/components/Icon/icons/save.svg b/packages/web/components/common/Icon/icons/save.svg similarity index 100% rename from projects/app/src/components/Icon/icons/save.svg rename to packages/web/components/common/Icon/icons/save.svg diff --git a/projects/app/src/components/Icon/icons/stop.svg b/packages/web/components/common/Icon/icons/stop.svg similarity index 100% rename from projects/app/src/components/Icon/icons/stop.svg rename to packages/web/components/common/Icon/icons/stop.svg diff --git a/projects/app/src/components/Icon/icons/support/account/loginoutLight.svg b/packages/web/components/common/Icon/icons/support/account/loginoutLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/support/account/loginoutLight.svg rename to packages/web/components/common/Icon/icons/support/account/loginoutLight.svg diff --git a/projects/app/src/components/Icon/icons/support/account/promotionLight.svg b/packages/web/components/common/Icon/icons/support/account/promotionLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/support/account/promotionLight.svg rename to packages/web/components/common/Icon/icons/support/account/promotionLight.svg diff --git a/projects/app/src/components/Icon/icons/light/billRecord.svg b/packages/web/components/common/Icon/icons/support/bill/billRecordLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/billRecord.svg rename to packages/web/components/common/Icon/icons/support/bill/billRecordLight.svg diff --git a/projects/app/src/components/Icon/icons/fill/apikey.svg b/packages/web/components/common/Icon/icons/support/outlink/apikeyFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/fill/apikey.svg rename to packages/web/components/common/Icon/icons/support/outlink/apikeyFill.svg diff --git a/projects/app/src/components/Icon/icons/apikey.svg b/packages/web/components/common/Icon/icons/support/outlink/apikeyLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/apikey.svg rename to packages/web/components/common/Icon/icons/support/outlink/apikeyLight.svg diff --git a/projects/app/src/components/Icon/icons/support/outlink/iframeLight.svg b/packages/web/components/common/Icon/icons/support/outlink/iframeLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/support/outlink/iframeLight.svg rename to packages/web/components/common/Icon/icons/support/outlink/iframeLight.svg diff --git a/projects/app/src/components/Icon/icons/light/share.svg b/packages/web/components/common/Icon/icons/support/outlink/share.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/share.svg rename to packages/web/components/common/Icon/icons/support/outlink/share.svg diff --git a/packages/web/components/common/Icon/icons/support/outlink/shareLight.svg b/packages/web/components/common/Icon/icons/support/outlink/shareLight.svg new file mode 100644 index 00000000000..4ab65220151 --- /dev/null +++ b/packages/web/components/common/Icon/icons/support/outlink/shareLight.svg @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/projects/app/src/components/Icon/icons/support/pay/payRecordLight.svg b/packages/web/components/common/Icon/icons/support/pay/payRecordLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/support/pay/payRecordLight.svg rename to packages/web/components/common/Icon/icons/support/pay/payRecordLight.svg diff --git a/projects/app/src/components/Icon/icons/support/pay/priceLight.svg b/packages/web/components/common/Icon/icons/support/pay/priceLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/support/pay/priceLight.svg rename to packages/web/components/common/Icon/icons/support/pay/priceLight.svg diff --git a/projects/app/src/components/Icon/icons/support/permission/privateLight.svg b/packages/web/components/common/Icon/icons/support/permission/privateLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/support/permission/privateLight.svg rename to packages/web/components/common/Icon/icons/support/permission/privateLight.svg diff --git a/projects/app/src/components/Icon/icons/support/permission/publicLight.svg b/packages/web/components/common/Icon/icons/support/permission/publicLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/support/permission/publicLight.svg rename to packages/web/components/common/Icon/icons/support/permission/publicLight.svg diff --git a/projects/app/src/components/Icon/icons/support/team/memberLight.svg b/packages/web/components/common/Icon/icons/support/team/memberLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/support/team/memberLight.svg rename to packages/web/components/common/Icon/icons/support/team/memberLight.svg diff --git a/projects/app/src/components/Icon/icons/light/inform.svg b/packages/web/components/common/Icon/icons/support/user/informLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/inform.svg rename to packages/web/components/common/Icon/icons/support/user/informLight.svg diff --git a/projects/app/src/components/Icon/icons/fill/me.svg b/packages/web/components/common/Icon/icons/support/user/userFill.svg similarity index 100% rename from projects/app/src/components/Icon/icons/fill/me.svg rename to packages/web/components/common/Icon/icons/support/user/userFill.svg diff --git a/projects/app/src/components/Icon/icons/light/me.svg b/packages/web/components/common/Icon/icons/support/user/userLight.svg similarity index 100% rename from projects/app/src/components/Icon/icons/light/me.svg rename to packages/web/components/common/Icon/icons/support/user/userLight.svg diff --git a/projects/app/src/components/Icon/icons/text.svg b/packages/web/components/common/Icon/icons/text.svg similarity index 100% rename from projects/app/src/components/Icon/icons/text.svg rename to packages/web/components/common/Icon/icons/text.svg diff --git a/projects/app/src/components/Icon/icons/user.svg b/packages/web/components/common/Icon/icons/user.svg similarity index 100% rename from projects/app/src/components/Icon/icons/user.svg rename to packages/web/components/common/Icon/icons/user.svg diff --git a/projects/app/src/components/Icon/icons/wx.svg b/packages/web/components/common/Icon/icons/wx.svg similarity index 100% rename from projects/app/src/components/Icon/icons/wx.svg rename to packages/web/components/common/Icon/icons/wx.svg diff --git a/packages/web/components/common/Icon/index.tsx b/packages/web/components/common/Icon/index.tsx new file mode 100644 index 00000000000..ff5dd3299b9 --- /dev/null +++ b/packages/web/components/common/Icon/index.tsx @@ -0,0 +1,31 @@ +import React, { useEffect, useState } from 'react'; +import type { IconProps } from '@chakra-ui/react'; +import { Icon } from '@chakra-ui/react'; +import { iconPaths } from './constants'; +import type { IconNameType } from './type.d'; + +const MyIcon = ({ name, w = 'auto', h = 'auto', ...props }: { name: IconNameType } & IconProps) => { + const [IconComponent, setIconComponent] = useState(null); + + useEffect(() => { + iconPaths[name]?.() + .then((icon) => { + setIconComponent({ as: icon.default }); + }) + .catch((error) => console.log(error)); + }, [name]); + + return !!name && !!iconPaths[name] ? ( + + ) : null; +}; + +export default MyIcon; diff --git a/packages/web/components/common/Icon/type.d.ts b/packages/web/components/common/Icon/type.d.ts new file mode 100644 index 00000000000..91ac9091da0 --- /dev/null +++ b/packages/web/components/common/Icon/type.d.ts @@ -0,0 +1,3 @@ +import { iconPaths } from './constants'; + +export type IconNameType = keyof typeof iconPaths; diff --git a/packages/web/package.json b/packages/web/package.json index 9aae252ce1b..d7bc1cd51cf 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -4,9 +4,24 @@ "dependencies": { "@fastgpt/global": "workspace:*", "joplin-turndown-plugin-gfm": "^1.0.12", - "turndown": "^7.1.2" + "turndown": "^7.1.2", + "@chakra-ui/anatomy": "^2.2.1", + "@chakra-ui/icons": "^2.1.1", + "@chakra-ui/next-js": "^2.1.5", + "@chakra-ui/react": "^2.8.1", + "@chakra-ui/styled-system": "^2.9.1", + "@chakra-ui/system": "^2.6.1", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "react": "18.2.0", + "react-dom": "18.2.0", + "i18next": "^22.5.1", + "next-i18next": "^13.3.0", + "react-i18next": "^12.3.1" }, "devDependencies": { - "@types/turndown": "^5.0.4" + "@types/turndown": "^5.0.4", + "@types/react": "18.2.0", + "@types/react-dom": "18.2.0" } } diff --git a/packages/web/tsconfig.json b/packages/web/tsconfig.json index 13c4daa3bed..d57aec33fb5 100644 --- a/packages/web/tsconfig.json +++ b/packages/web/tsconfig.json @@ -14,8 +14,11 @@ "isolatedModules": true, "jsx": "preserve", "incremental": true, - "baseUrl": "." + "baseUrl": ".", + "paths": { + "@/*": ["./*"] + } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts", "../**/*.d.ts"], - "exclude": ["node_modules"] + "exclude": ["node_modules","./components/common/Icon/constants.ts"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0bc845e98b8..5b0e1917f1c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -136,16 +136,61 @@ importers: packages/web: dependencies: + '@chakra-ui/anatomy': + specifier: ^2.2.1 + version: registry.npmmirror.com/@chakra-ui/anatomy@2.2.1 + '@chakra-ui/icons': + specifier: ^2.1.1 + version: registry.npmmirror.com/@chakra-ui/icons@2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0) + '@chakra-ui/next-js': + specifier: ^2.1.5 + version: registry.npmmirror.com/@chakra-ui/next-js@2.1.5(@chakra-ui/react@2.8.1)(@emotion/react@11.11.1)(next@13.5.2)(react@18.2.0) + '@chakra-ui/react': + specifier: ^2.8.1 + version: registry.npmmirror.com/@chakra-ui/react@2.8.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.0)(framer-motion@9.0.6)(react-dom@18.2.0)(react@18.2.0) + '@chakra-ui/styled-system': + specifier: ^2.9.1 + version: registry.npmmirror.com/@chakra-ui/styled-system@2.9.1 + '@chakra-ui/system': + specifier: ^2.6.1 + version: registry.npmmirror.com/@chakra-ui/system@2.6.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0) + '@emotion/react': + specifier: ^11.11.1 + version: registry.npmmirror.com/@emotion/react@11.11.1(@types/react@18.2.0)(react@18.2.0) + '@emotion/styled': + specifier: ^11.11.0 + version: registry.npmmirror.com/@emotion/styled@11.11.0(@emotion/react@11.11.1)(@types/react@18.2.0)(react@18.2.0) '@fastgpt/global': specifier: workspace:* version: link:../global + i18next: + specifier: ^22.5.1 + version: registry.npmmirror.com/i18next@22.5.1 joplin-turndown-plugin-gfm: specifier: ^1.0.12 version: registry.npmmirror.com/joplin-turndown-plugin-gfm@1.0.12 + next-i18next: + specifier: ^13.3.0 + version: registry.npmmirror.com/next-i18next@13.3.0(i18next@22.5.1)(next@13.5.2)(react-i18next@12.3.1)(react@18.2.0) + react: + specifier: 18.2.0 + version: registry.npmmirror.com/react@18.2.0 + react-dom: + specifier: 18.2.0 + version: registry.npmmirror.com/react-dom@18.2.0(react@18.2.0) + react-i18next: + specifier: ^12.3.1 + version: registry.npmmirror.com/react-i18next@12.3.1(i18next@22.5.1)(react-dom@18.2.0)(react@18.2.0) turndown: specifier: ^7.1.2 version: registry.npmmirror.com/turndown@7.1.2 devDependencies: + '@types/react': + specifier: 18.2.0 + version: registry.npmmirror.com/@types/react@18.2.0 + '@types/react-dom': + specifier: 18.2.0 + version: registry.npmmirror.com/@types/react-dom@18.2.0 '@types/turndown': specifier: ^5.0.4 version: registry.npmmirror.com/@types/turndown@5.0.4 @@ -346,112 +391,6 @@ importers: specifier: 4.9.5 version: registry.npmmirror.com/typescript@4.9.5 - projects/home: - dependencies: - '@chakra-ui/anatomy': - specifier: ^2.2.1 - version: registry.npmmirror.com/@chakra-ui/anatomy@2.2.1 - '@chakra-ui/icons': - specifier: ^2.1.1 - version: registry.npmmirror.com/@chakra-ui/icons@2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0) - '@chakra-ui/next-js': - specifier: ^2.1.5 - version: registry.npmmirror.com/@chakra-ui/next-js@2.1.5(@chakra-ui/react@2.8.1)(@emotion/react@11.11.1)(next@13.5.2)(react@18.2.0) - '@chakra-ui/react': - specifier: ^2.8.1 - version: registry.npmmirror.com/@chakra-ui/react@2.8.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.0)(framer-motion@9.0.6)(react-dom@18.2.0)(react@18.2.0) - '@chakra-ui/styled-system': - specifier: ^2.9.1 - version: registry.npmmirror.com/@chakra-ui/styled-system@2.9.1 - '@chakra-ui/system': - specifier: ^2.6.1 - version: registry.npmmirror.com/@chakra-ui/system@2.6.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0) - '@emotion/react': - specifier: ^11.11.1 - version: registry.npmmirror.com/@emotion/react@11.11.1(@types/react@18.2.0)(react@18.2.0) - '@emotion/styled': - specifier: ^11.11.0 - version: registry.npmmirror.com/@emotion/styled@11.11.0(@emotion/react@11.11.1)(@types/react@18.2.0)(react@18.2.0) - axios: - specifier: ^1.5.1 - version: registry.npmmirror.com/axios@1.5.1 - framer-motion: - specifier: ^9.0.6 - version: registry.npmmirror.com/framer-motion@9.0.6(react-dom@18.2.0)(react@18.2.0) - hyperdown: - specifier: ^2.4.29 - version: registry.npmmirror.com/hyperdown@2.4.29 - i18next: - specifier: ^22.5.1 - version: registry.npmmirror.com/i18next@22.5.1 - next: - specifier: 13.5.2 - version: registry.npmmirror.com/next@13.5.2(@babel/core@7.23.6)(react-dom@18.2.0)(react@18.2.0)(sass@1.58.3) - next-i18next: - specifier: ^13.3.0 - version: registry.npmmirror.com/next-i18next@13.3.0(i18next@22.5.1)(next@13.5.2)(react-i18next@12.3.1)(react@18.2.0) - nprogress: - specifier: ^0.2.0 - version: registry.npmmirror.com/nprogress@0.2.0 - react: - specifier: 18.2.0 - version: registry.npmmirror.com/react@18.2.0 - react-dom: - specifier: 18.2.0 - version: registry.npmmirror.com/react-dom@18.2.0(react@18.2.0) - react-i18next: - specifier: ^12.3.1 - version: registry.npmmirror.com/react-i18next@12.3.1(i18next@22.5.1)(react-dom@18.2.0)(react@18.2.0) - react-markdown: - specifier: ^8.0.7 - version: registry.npmmirror.com/react-markdown@8.0.7(@types/react@18.2.0)(react@18.2.0) - remark-breaks: - specifier: ^3.0.3 - version: registry.npmmirror.com/remark-breaks@3.0.3 - remark-gfm: - specifier: ^3.0.1 - version: registry.npmmirror.com/remark-gfm@3.0.1 - request-ip: - specifier: ^3.3.0 - version: registry.npmmirror.com/request-ip@3.3.0 - sass: - specifier: ^1.58.3 - version: registry.npmmirror.com/sass@1.58.3 - devDependencies: - '@svgr/webpack': - specifier: ^6.5.1 - version: registry.npmmirror.com/@svgr/webpack@6.5.1 - '@types/lodash': - specifier: ^4.14.191 - version: registry.npmmirror.com/@types/lodash@4.14.191 - '@types/node': - specifier: ^20.8.5 - version: registry.npmmirror.com/@types/node@20.8.5 - '@types/nprogress': - specifier: ^0.2.0 - version: registry.npmmirror.com/@types/nprogress@0.2.0 - '@types/react': - specifier: 18.2.0 - version: registry.npmmirror.com/@types/react@18.2.0 - '@types/react-dom': - specifier: 18.2.0 - version: registry.npmmirror.com/@types/react-dom@18.2.0 - '@types/react-syntax-highlighter': - specifier: ^15.5.6 - version: registry.npmmirror.com/@types/react-syntax-highlighter@15.5.6 - '@types/request-ip': - specifier: ^0.0.37 - version: registry.npmmirror.com/@types/request-ip@0.0.37 - eslint: - specifier: 8.34.0 - version: registry.npmmirror.com/eslint@8.34.0 - eslint-config-next: - specifier: 13.1.6 - version: registry.npmmirror.com/eslint-config-next@13.1.6(eslint@8.34.0)(typescript@4.9.5) - typescript: - specifier: 4.9.5 - version: registry.npmmirror.com/typescript@4.9.5 - packages: registry.npmmirror.com/@aashutoshrathi/word-wrap@1.2.6: @@ -5148,6 +5087,7 @@ packages: resolution: {integrity: sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/nprogress/-/nprogress-0.2.0.tgz} name: '@types/nprogress' version: 0.2.0 + dev: false registry.npmmirror.com/@types/papaparse@5.3.7: resolution: {integrity: sha512-f2HKmlnPdCvS0WI33WtCs5GD7X1cxzzS/aduaxSu3I7TbhWlENjSPs6z5TaB9K0J+BH1jbmqTaM+ja5puis4wg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@types/papaparse/-/papaparse-5.3.7.tgz} diff --git a/projects/app/data/config.json b/projects/app/data/config.json index 2ee834c26f8..1c21762528f 100644 --- a/projects/app/data/config.json +++ b/projects/app/data/config.json @@ -9,7 +9,8 @@ { "model": "gpt-3.5-turbo", "name": "GPT35", - "price": 0, + "inputPrice": 0, + "outputPrice": 0, "maxContext": 4000, "maxResponse": 4000, "quoteMaxToken": 2000, @@ -23,7 +24,8 @@ "name": "GPT35-16k", "maxContext": 16000, "maxResponse": 16000, - "price": 0, + "inputPrice": 0, + "outputPrice": 0, "quoteMaxToken": 8000, "maxTemperature": 1.2, "censor": false, @@ -35,7 +37,8 @@ "name": "GPT4-8k", "maxContext": 8000, "maxResponse": 8000, - "price": 0, + "inputPrice": 0, + "outputPrice": 0, "quoteMaxToken": 4000, "maxTemperature": 1.2, "censor": false, @@ -47,7 +50,8 @@ "name": "GPT4-Vision", "maxContext": 128000, "maxResponse": 4000, - "price": 0, + "inputPrice": 0, + "outputPrice": 0, "quoteMaxToken": 100000, "maxTemperature": 1.2, "censor": false, @@ -61,7 +65,8 @@ "name": "GPT35-16k", "maxContext": 16000, "maxResponse": 16000, - "price": 0 + "inputPrice": 0, + "outputPrice": 0 } ], "cqModels": [ @@ -70,7 +75,8 @@ "name": "GPT35", "maxContext": 4000, "maxResponse": 4000, - "price": 0, + "inputPrice": 0, + "outputPrice": 0, "toolChoice": true, "functionPrompt": "" }, @@ -79,7 +85,8 @@ "name": "GPT4-8k", "maxContext": 8000, "maxResponse": 8000, - "price": 0, + "inputPrice": 0, + "outputPrice": 0, "toolChoice": true, "functionPrompt": "" } @@ -90,7 +97,8 @@ "name": "GPT35-1106", "maxContext": 16000, "maxResponse": 4000, - "price": 0, + "inputPrice": 0, + "outputPrice": 0, "toolChoice": true, "functionPrompt": "" } @@ -101,14 +109,16 @@ "name": "GPT35-1106", "maxContext": 1600, "maxResponse": 4000, - "price": 0 + "inputPrice": 0, + "outputPrice": 0 } ], "vectorModels": [ { "model": "text-embedding-ada-002", "name": "Embedding-2", - "price": 0.2, + "inputPrice": 0, + "outputPrice": 0, "defaultToken": 700, "maxToken": 3000, "weight": 100 @@ -119,7 +129,8 @@ { "model": "tts-1", "name": "OpenAI TTS1", - "price": 0, + "inputPrice": 0, + "outputPrice": 0, "voices": [ { "label": "Alloy", "value": "alloy", "bufferId": "openai-Alloy" }, { "label": "Echo", "value": "echo", "bufferId": "openai-Echo" }, @@ -133,6 +144,7 @@ "whisperModel": { "model": "whisper-1", "name": "Whisper1", - "price": 0 + "inputPrice": 0, + "outputPrice": 0 } } diff --git a/projects/app/public/imgs/modal/shareFill.svg b/projects/app/public/imgs/modal/shareFill.svg new file mode 100644 index 00000000000..8f000c73482 --- /dev/null +++ b/projects/app/public/imgs/modal/shareFill.svg @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/projects/app/public/imgs/modal/shareLight.svg b/projects/app/public/imgs/modal/shareLight.svg deleted file mode 100644 index 04b18a98589..00000000000 --- a/projects/app/public/imgs/modal/shareLight.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/projects/app/public/locales/en/common.json b/projects/app/public/locales/en/common.json index 45346ea6596..e75b2f10325 100644 --- a/projects/app/public/locales/en/common.json +++ b/projects/app/public/locales/en/common.json @@ -133,7 +133,9 @@ "Name is empty": "Name is empty", "New Create": "Create", "Next Step": "Next", + "Not open": "Close", "OK": "OK", + "Opened": "Opened", "Output": "Output", "Params": "Params", "Password inconsistency": "Password inconsistency", @@ -244,12 +246,13 @@ "create app": "Create App", "edit": { "Confirm Save App Tip": "The application may be in advanced orchestration mode, and the advanced orchestration configuration will be overwritten after saving, please confirm!", + "Open cfr": "Open Cfr", "Out Ad Edit": "You are about to exit the Advanced orchestration page, please confirm", "Prompt Editor": "Prompt Editor", "Save and out": "Save out", "UnSave": "UnSave", - "cfr background prompt": "Question completion - Chat background description", - "cfr background tip": "Describing the scope of the current conversation makes it easier for AI to complete first or vague questions, thereby enhancing the knowledge base's ability to continue conversations. \nIf is empty, the problem completion function is not used." + "cfr background prompt": "Chat background description", + "cfr background tip": "Describing the scope of the current conversation makes it easier for AI to complete first or vague questions, thereby enhancing the knowledge base's ability to continue conversations.\nIf the value is empty, the problem completion function is not used for the \"first problem\".\nIf the value is none, the problem completion function is not used." }, "feedback": { "Custom feedback": "Custom feedback", @@ -637,7 +640,7 @@ "TFSwitch": "", "TFSwitch intro": "", "UnKnow Module": "UnKnow Module", - "cfr": "", + "cfr": "Coreference resolution", "cfr intro": "Refine the current issue based on history, making it more conducive to knowledge base search, while improving continuous conversation capabilities.", "textEditor": "Text Editor", "textEditor intro": "Output of fixed or incoming text after edit" diff --git a/projects/app/public/locales/zh/common.json b/projects/app/public/locales/zh/common.json index a77c40120dd..a4826e3be6e 100644 --- a/projects/app/public/locales/zh/common.json +++ b/projects/app/public/locales/zh/common.json @@ -133,7 +133,9 @@ "Name is empty": "名称不能为空", "New Create": "新建", "Next Step": "下一步", + "Not open": "未开启", "OK": "好的", + "Opened": "已开启", "Output": "输出", "Params": "参数", "Password inconsistency": "两次密码不一致", @@ -244,12 +246,13 @@ "create app": "创建属于你的 AI 应用", "edit": { "Confirm Save App Tip": "该应用可能为高级编排模式,保存后将会覆盖高级编排配置,请确认!", + "Open cfr": "开启自动补全", "Out Ad Edit": "您即将退出高级编排页面,请确认", "Prompt Editor": "提示词编辑", "Save and out": "保存并退出", "UnSave": "不保存", - "cfr background prompt": "问题补全 - 对话背景描述", - "cfr background tip": "描述当前对话的范围,便于AI补全首次问题或模糊的问题,从而增强知识库连续对话的能力。\n为空时,表示不使用问题补全功能。" + "cfr background prompt": "对话背景描述", + "cfr background tip": "描述当前对话的范围,便于AI补全首次问题或模糊的问题,从而增强知识库连续对话的能力。\n值为空时,表示【首个问题】不使用问题补全功能。\n值为 none 时,表示不使用问题补全功能。" }, "feedback": { "Custom feedback": "自定义反馈", diff --git a/projects/app/src/components/ChatBox/MessageInput.tsx b/projects/app/src/components/ChatBox/MessageInput.tsx index b252939e161..35115679009 100644 --- a/projects/app/src/components/ChatBox/MessageInput.tsx +++ b/projects/app/src/components/ChatBox/MessageInput.tsx @@ -4,8 +4,7 @@ import { Box, Flex, Image, Spinner, Textarea } from '@chakra-ui/react'; import React, { useRef, useEffect, useCallback, useState } from 'react'; import { useTranslation } from 'next-i18next'; import MyTooltip from '../MyTooltip'; -import MyIcon from '../Icon'; -import styles from './index.module.scss'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import { useRouter } from 'next/router'; import { useSelectFile } from '@/web/common/file/hooks/useSelectFile'; import { compressImgFileAndUpload } from '@/web/common/file/controller'; @@ -137,7 +136,7 @@ const MessageInput = ({ rawFile: file, type: FileTypeEnum.file, name: file.name, - icon: 'pdf' + icon: 'file/pdf' }); } }) diff --git a/projects/app/src/components/ChatBox/SelectMarkCollection.tsx b/projects/app/src/components/ChatBox/SelectMarkCollection.tsx index 39f8f5024c5..db67d9b7b9f 100644 --- a/projects/app/src/components/ChatBox/SelectMarkCollection.tsx +++ b/projects/app/src/components/ChatBox/SelectMarkCollection.tsx @@ -2,7 +2,7 @@ import React, { useMemo, useState } from 'react'; import { ModalBody, useTheme, ModalFooter, Button, Box, Card, Flex, Grid } from '@chakra-ui/react'; import { useTranslation } from 'next-i18next'; import Avatar from '../Avatar'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constant'; import DatasetSelectModal, { useDatasetSelect } from '@/components/core/dataset/SelectModal'; import dynamic from 'next/dynamic'; diff --git a/projects/app/src/components/ChatBox/index.tsx b/projects/app/src/components/ChatBox/index.tsx index 323e0014722..ef09f57249d 100644 --- a/projects/app/src/components/ChatBox/index.tsx +++ b/projects/app/src/components/ChatBox/index.tsx @@ -51,7 +51,7 @@ import { } from '@/web/core/chat/api'; import type { AdminMarkType } from './SelectMarkCollection'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import Avatar from '@/components/Avatar'; import Markdown, { CodeClassName } from '@/components/Markdown'; import MySelect from '@/components/Select'; @@ -629,7 +629,7 @@ const ChatBox = ( ))} {!variableIsFinish && ( + + {appDetail.isOwner && ( + + )} + + + + + + {settingAppInfo && ( + setSettingAppInfo(undefined)} /> + )} + + ); +}; + +export default React.memo(AppCard); diff --git a/projects/app/src/pages/app/detail/components/SimpleEdit/CfrEditModal.tsx b/projects/app/src/pages/app/detail/components/SimpleEdit/CfrEditModal.tsx new file mode 100644 index 00000000000..ff62e02342a --- /dev/null +++ b/projects/app/src/pages/app/detail/components/SimpleEdit/CfrEditModal.tsx @@ -0,0 +1,61 @@ +import React, { useMemo, useState } from 'react'; + +import MyModal from '@/components/MyModal'; +import { useTranslation } from 'next-i18next'; +import { Button, ModalBody, ModalFooter } from '@chakra-ui/react'; +import PromptTextarea from '@/components/common/Textarea/PromptTextarea'; +import MyTooltip from '@/components/MyTooltip'; +import { QuestionOutlineIcon } from '@chakra-ui/icons'; + +const CfrEditModal = ({ + defaultValue = '', + onClose, + onFinish +}: { + defaultValue?: string; + onClose: () => void; + onFinish: (value: string) => void; +}) => { + const { t } = useTranslation(); + const [value, setValue] = useState(defaultValue); + + return ( + + + {t('core.app.edit.cfr background prompt')} + + + + { + setValue(e.target.value || ''); + }} + /> + + + + + + ); +}; + +export default React.memo(CfrEditModal); diff --git a/projects/app/src/pages/app/detail/components/SimpleEdit/ChatTest.tsx b/projects/app/src/pages/app/detail/components/SimpleEdit/ChatTest.tsx new file mode 100644 index 00000000000..5e49bcd156c --- /dev/null +++ b/projects/app/src/pages/app/detail/components/SimpleEdit/ChatTest.tsx @@ -0,0 +1,133 @@ +import { useAppStore } from '@/web/core/app/store/useAppStore'; +import { useUserStore } from '@/web/support/user/useUserStore'; +import { Box, Flex, IconButton } from '@chakra-ui/react'; +import { useTranslation } from 'next-i18next'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import ChatBox, { type ComponentRef, type StartChatFnProps } from '@/components/ChatBox'; +import { ModuleItemType } from '@fastgpt/global/core/module/type'; +import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants'; +import { streamFetch } from '@/web/common/api/fetch'; +import MyTooltip from '@/components/MyTooltip'; +import MyIcon from '@fastgpt/web/components/common/Icon'; +import { getGuideModule } from '@fastgpt/global/core/module/utils'; +import { checkChatSupportSelectFileByModules } from '@/web/core/chat/utils'; +import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; + +const ChatTest = ({ appId }: { appId: string }) => { + const { t } = useTranslation(); + const { userInfo } = useUserStore(); + const { appDetail } = useAppStore(); + const ChatBoxRef = useRef(null); + const [modules, setModules] = useState([]); + + const startChat = useCallback( + async ({ chatList, controller, generatingMessage, variables }: StartChatFnProps) => { + let historyMaxLen = 0; + + modules.forEach((module) => { + module.inputs.forEach((input) => { + if ( + (input.key === ModuleInputKeyEnum.history || + input.key === ModuleInputKeyEnum.historyMaxAmount) && + typeof input.value === 'number' + ) { + historyMaxLen = Math.max(historyMaxLen, input.value); + } + }); + }); + const history = chatList.slice(-historyMaxLen - 2, -2); + + // 流请求,获取数据 + const { responseText, responseData } = await streamFetch({ + url: '/api/core/chat/chatTest', + data: { + history, + prompt: chatList[chatList.length - 2].value, + modules, + variables, + appId, + appName: `调试-${appDetail.name}` + }, + onMessage: generatingMessage, + abortSignal: controller + }); + + return { responseText, responseData }; + }, + [modules, appId, appDetail.name] + ); + + const resetChatBox = useCallback(() => { + ChatBoxRef.current?.resetHistory([]); + ChatBoxRef.current?.resetVariables(); + }, []); + + useEffect(() => { + resetChatBox(); + setModules(appDetail.modules); + }, [appDetail, resetChatBox]); + + return ( + + + + {t('app.Chat Debug')} + + + } + variant={'whiteDanger'} + borderRadius={'md'} + aria-label={'delete'} + onClick={(e) => { + e.stopPropagation(); + resetChatBox(); + }} + /> + + + + {}} + /> + + {appDetail.type !== AppTypeEnum.simple && ( + + {t('app.Advance App TestTip')} + + )} + + ); +}; + +export default React.memo(ChatTest); diff --git a/projects/app/src/pages/app/detail/components/SimpleEdit/EditForm.tsx b/projects/app/src/pages/app/detail/components/SimpleEdit/EditForm.tsx new file mode 100644 index 00000000000..cf4eadbe6eb --- /dev/null +++ b/projects/app/src/pages/app/detail/components/SimpleEdit/EditForm.tsx @@ -0,0 +1,546 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { + Box, + Flex, + Grid, + BoxProps, + useTheme, + useDisclosure, + Button, + Image +} from '@chakra-ui/react'; +import { useQuery } from '@tanstack/react-query'; +import { QuestionOutlineIcon, SmallAddIcon } from '@chakra-ui/icons'; +import { useForm, useFieldArray } from 'react-hook-form'; +import { useSystemStore } from '@/web/common/system/useSystemStore'; +import { appModules2Form, getDefaultAppForm } from '@fastgpt/global/core/app/utils'; +import type { AppSimpleEditFormType } from '@fastgpt/global/core/app/type.d'; +import { chatModelList, simpleModeTemplates } from '@/web/common/system/staticData'; +import { chatNodeSystemPromptTip, welcomeTextTip } from '@fastgpt/global/core/module/template/tip'; +import { useRequest } from '@/web/common/hooks/useRequest'; +import { useConfirm } from '@/web/common/hooks/useConfirm'; +import { useRouter } from 'next/router'; +import { useTranslation } from 'next-i18next'; +import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; +import { useDatasetStore } from '@/web/core/dataset/store/dataset'; +import { useAppStore } from '@/web/core/app/store/useAppStore'; + +import { postForm2Modules } from '@/web/core/app/utils'; + +import dynamic from 'next/dynamic'; +import MySelect from '@/components/Select'; +import MyTooltip from '@/components/MyTooltip'; +import Avatar from '@/components/Avatar'; +import MyIcon from '@fastgpt/web/components/common/Icon'; +import { SimpleModeTemplate_FastGPT_Universal } from '@/global/core/app/constants'; +import VariableEdit from '@/components/core/module/Flow/components/modules/VariableEdit'; +import PromptTextarea from '@/components/common/Textarea/PromptTextarea/index'; +import { DatasetSearchModeMap } from '@fastgpt/global/core/dataset/constant'; +import SelectAiModel from '@/components/Select/SelectAiModel'; + +const DatasetSelectModal = dynamic(() => import('@/components/core/module/DatasetSelectModal')); +const DatasetParamsModal = dynamic(() => import('@/components/core/module/DatasetParamsModal')); +const AIChatSettingsModal = dynamic(() => import('@/components/core/module/AIChatSettingsModal')); +const TTSSelect = dynamic( + () => import('@/components/core/module/Flow/components/modules/TTSSelect') +); +const QGSwitch = dynamic(() => import('@/components/core/module/Flow/components/modules/QGSwitch')); +const CfrEditModal = dynamic(() => import('./CfrEditModal')); + +const EditForm = ({ + divRef, + isSticky +}: { + divRef: React.RefObject; + isSticky: boolean; +}) => { + const theme = useTheme(); + const router = useRouter(); + const { t } = useTranslation(); + const { appDetail, updateAppDetail } = useAppStore(); + const { loadAllDatasets, allDatasets } = useDatasetStore(); + const { isPc } = useSystemStore(); + const [refresh, setRefresh] = useState(false); + + const { register, setValue, getValues, reset, handleSubmit, control } = + useForm({ + defaultValues: getDefaultAppForm() + }); + + const { fields: datasets, replace: replaceKbList } = useFieldArray({ + control, + name: 'dataset.datasets' + }); + + const { + isOpen: isOpenAIChatSetting, + onOpen: onOpenAIChatSetting, + onClose: onCloseAIChatSetting + } = useDisclosure(); + const { + isOpen: isOpenDatasetSelect, + onOpen: onOpenKbSelect, + onClose: onCloseKbSelect + } = useDisclosure(); + const { + isOpen: isOpenDatasetParams, + onOpen: onOpenDatasetParams, + onClose: onCloseDatasetParams + } = useDisclosure(); + const { + isOpen: isOpenCfrModal, + onOpen: onOpenCfrModal, + onClose: onCloseCfrModal + } = useDisclosure(); + + const { openConfirm: openConfirmSave, ConfirmModal: ConfirmSaveModal } = useConfirm({ + content: t('core.app.edit.Confirm Save App Tip') + }); + + const chatModelSelectList = useMemo(() => { + return chatModelList.map((item) => ({ + value: item.model, + label: item.name + })); + }, [refresh]); + + const selectDatasets = useMemo( + () => allDatasets.filter((item) => datasets.find((dataset) => dataset.datasetId === item._id)), + [allDatasets, datasets] + ); + + const selectSimpleTemplate = useMemo( + () => + simpleModeTemplates?.find((item) => item.id === getValues('templateId')) || + SimpleModeTemplate_FastGPT_Universal, + [getValues, refresh] + ); + + const tokenLimit = useMemo(() => { + return ( + chatModelList.find((item) => item.model === getValues('aiSettings.model'))?.quoteMaxToken || + 3000 + ); + }, [getValues, refresh]); + + const datasetSearchMode = useMemo(() => { + const mode = getValues('dataset.searchMode'); + if (!mode) return ''; + return t(DatasetSearchModeMap[mode]?.title); + }, [getValues, t, refresh]); + + const { mutate: onSubmitSave, isLoading: isSaving } = useRequest({ + mutationFn: async (data: AppSimpleEditFormType) => { + const modules = await postForm2Modules(data, data.templateId); + + await updateAppDetail(appDetail._id, { + modules, + type: AppTypeEnum.simple, + simpleTemplateId: data.templateId, + permission: undefined + }); + }, + successToast: t('common.Save Success'), + errorToast: t('common.Save Failed') + }); + + const appModule2Form = useCallback(() => { + const formVal = appModules2Form({ + templateId: appDetail.simpleTemplateId, + modules: appDetail.modules + }); + + reset(formVal); + setTimeout(() => { + setRefresh((state) => !state); + }, 100); + }, [appDetail.modules, appDetail.simpleTemplateId, reset]); + + useEffect(() => { + appModule2Form(); + }, [appModule2Form]); + useQuery(['loadAllDatasets'], loadAllDatasets); + + const BoxStyles: BoxProps = { + px: 5, + py: '16px', + borderBottomWidth: '1px', + borderBottomColor: 'borderColor.low' + }; + const BoxBtnStyles: BoxProps = { + cursor: 'pointer', + px: 3, + py: 1, + borderRadius: 'md', + _hover: { + bg: 'myGray.150' + } + }; + const LabelStyles: BoxProps = { + w: ['60px', '100px'], + flexShrink: 0, + fontSize: ['sm', 'md'] + }; + + return ( + + {/* title */} + + + + {t('core.app.App params config')} + + + + + + + + + + + {/* simple mode select */} + + + {''} + {t('core.app.simple.mode template select')} + + ({ + alias: item.name, + label: item.desc, + value: item.id + })) || [] + } + value={getValues('templateId')} + onchange={(val) => { + setValue('templateId', val); + setRefresh(!refresh); + }} + /> + + + {/* ai */} + {selectSimpleTemplate?.systemForm?.aiSettings && ( + + + {''} + + {t('app.AI Settings')} + + {(selectSimpleTemplate.systemForm.aiSettings.maxToken || + selectSimpleTemplate.systemForm.aiSettings.temperature || + selectSimpleTemplate.systemForm.aiSettings.quoteTemplate || + selectSimpleTemplate.systemForm.aiSettings.quotePrompt) && ( + + + {t('app.Open AI Advanced Settings')} + + )} + + {selectSimpleTemplate.systemForm.aiSettings?.model && ( + + {t('core.ai.Model')} + + { + setValue('aiSettings.model', val); + const maxToken = + chatModelList.find((item) => item.model === getValues('aiSettings.model')) + ?.maxResponse || 4000; + const token = maxToken / 2; + setValue('aiSettings.maxToken', token); + setRefresh(!refresh); + }} + /> + + + )} + + {selectSimpleTemplate.systemForm.aiSettings?.systemPrompt && ( + + + {t('core.ai.Prompt')} + + + + + { + setValue('aiSettings.systemPrompt', e.target.value || ''); + }} + /> + + )} + + )} + + {/* dataset */} + {selectSimpleTemplate?.systemForm?.dataset && ( + + + + {''} + {t('core.dataset.Choose Dataset')} + + {selectSimpleTemplate.systemForm.dataset.datasets && ( + + + {t('common.Choose')} + + )} + {(selectSimpleTemplate.systemForm.dataset.limit || + selectSimpleTemplate.systemForm.dataset.searchMode || + selectSimpleTemplate.systemForm.dataset.searchEmptyText || + selectSimpleTemplate.systemForm.dataset.similarity) && ( + + + {t('common.Params')} + + )} + + {getValues('dataset.datasets').length > 0 && ( + + {t('core.dataset.search.search mode')}: {datasetSearchMode} + {', '} + {t('core.dataset.search.Min Similarity')}: {getValues('dataset.similarity')} + {', '} + {t('core.dataset.search.Max Tokens')}: {getValues('dataset.limit')} + {getValues('dataset.searchEmptyText') === '' + ? '' + : t('core.dataset.Set Empty Result Tip')} + + )} + + {selectDatasets.map((item) => ( + + + router.push({ + pathname: '/dataset/detail', + query: { + datasetId: item._id + } + }) + } + > + + + {item.name} + + + + ))} + + + )} + + {/* cfr */} + {selectSimpleTemplate?.systemForm?.cfr && getValues('dataset.datasets').length > 0 && ( + + {''} + {t('core.module.template.cfr')} + + + + + + {getValues('cfr.background') === 'none' ? t('common.Not open') : t('common.Opened')} + + + )} + + {/* variable */} + {selectSimpleTemplate?.systemForm?.userGuide?.variables && ( + + { + setValue('userGuide.variables', e); + setRefresh(!refresh); + }} + /> + + )} + + {/* welcome */} + {selectSimpleTemplate?.systemForm?.userGuide?.welcomeText && ( + + + {''} + {t('core.app.Welcome Text')} + + + + + { + setValue('userGuide.welcomeText', e.target.value || ''); + }} + /> + + )} + + {/* tts */} + {selectSimpleTemplate?.systemForm?.userGuide?.tts && ( + + { + setValue('userGuide.tts', e); + setRefresh((state) => !state); + }} + /> + + )} + + {/* question guide */} + {selectSimpleTemplate?.systemForm?.userGuide?.questionGuide && ( + + { + const value = e.target.checked; + setValue('userGuide.questionGuide', value); + setRefresh((state) => !state); + }} + /> + + )} + + + + + {isOpenAIChatSetting && ( + { + setValue('aiSettings', e); + onCloseAIChatSetting(); + }} + defaultData={getValues('aiSettings')} + simpleModeTemplate={selectSimpleTemplate} + /> + )} + {isOpenDatasetSelect && ( + ({ + datasetId: item._id, + vectorModel: item.vectorModel + }))} + onClose={onCloseKbSelect} + onChange={replaceKbList} + /> + )} + {isOpenDatasetParams && ( + { + setValue('dataset', { + ...getValues('dataset'), + ...e + }); + + setRefresh((state) => !state); + }} + /> + )} + {isOpenCfrModal && ( + { + setValue('cfr.background', e); + }} + /> + )} + + ); +}; + +export default React.memo(EditForm); diff --git a/projects/app/src/pages/app/detail/components/SimpleEdit/index.tsx b/projects/app/src/pages/app/detail/components/SimpleEdit/index.tsx index d4d60ccebde..3ae2bdc319f 100644 --- a/projects/app/src/pages/app/detail/components/SimpleEdit/index.tsx +++ b/projects/app/src/pages/app/detail/components/SimpleEdit/index.tsx @@ -1,813 +1,36 @@ -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { - Box, - Flex, - Grid, - BoxProps, - Textarea, - useTheme, - useDisclosure, - Button, - IconButton, - Image -} from '@chakra-ui/react'; -import { useUserStore } from '@/web/support/user/useUserStore'; -import { useQuery } from '@tanstack/react-query'; -import { QuestionOutlineIcon, SmallAddIcon } from '@chakra-ui/icons'; -import { useForm, useFieldArray } from 'react-hook-form'; +import React from 'react'; +import { Box, Grid } from '@chakra-ui/react'; import { useSystemStore } from '@/web/common/system/useSystemStore'; -import { appModules2Form, getDefaultAppForm } from '@fastgpt/global/core/app/utils'; -import type { AppSimpleEditFormType } from '@fastgpt/global/core/app/type.d'; -import { chatModelList, simpleModeTemplates } from '@/web/common/system/staticData'; -import { chatNodeSystemPromptTip, welcomeTextTip } from '@fastgpt/global/core/module/template/tip'; -import type { ModuleItemType } from '@fastgpt/global/core/module/type'; -import { useRequest } from '@/web/common/hooks/useRequest'; -import { useConfirm } from '@/web/common/hooks/useConfirm'; -import { streamFetch } from '@/web/common/api/fetch'; -import { useRouter } from 'next/router'; -import { useToast } from '@/web/common/hooks/useToast'; -import { AppSchema } from '@fastgpt/global/core/app/type.d'; -import { delModelById } from '@/web/core/app/api'; -import { useTranslation } from 'next-i18next'; -import { getGuideModule } from '@fastgpt/global/core/module/utils'; -import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; -import { useDatasetStore } from '@/web/core/dataset/store/dataset'; -import { useAppStore } from '@/web/core/app/store/useAppStore'; -import PermissionIconText from '@/components/support/permission/IconText'; - -import { checkChatSupportSelectFileByModules } from '@/web/core/chat/utils'; import { useSticky } from '@/web/common/hooks/useSticky'; -import { postForm2Modules } from '@/web/core/app/utils'; - -import dynamic from 'next/dynamic'; -import MySelect from '@/components/Select'; -import MyTooltip from '@/components/MyTooltip'; -import Avatar from '@/components/Avatar'; -import MyIcon from '@/components/Icon'; -import ChatBox, { type ComponentRef, type StartChatFnProps } from '@/components/ChatBox'; -import { SimpleModeTemplate_FastGPT_Universal } from '@/global/core/app/constants'; -import VariableEdit from '@/components/core/module/Flow/components/modules/VariableEdit'; -import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants'; -import PromptTextarea from '@/components/common/Textarea/PromptTextarea/index'; -import { DatasetSearchModeMap } from '@fastgpt/global/core/dataset/constant'; -import SelectAiModel from '@/components/Select/SelectAiModel'; -const InfoModal = dynamic(() => import('../InfoModal')); -const DatasetSelectModal = dynamic(() => import('@/components/core/module/DatasetSelectModal')); -const DatasetParamsModal = dynamic(() => import('@/components/core/module/DatasetParamsModal')); -const AIChatSettingsModal = dynamic(() => import('@/components/core/module/AIChatSettingsModal')); -const TTSSelect = dynamic( - () => import('@/components/core/module/Flow/components/modules/TTSSelect') -); -const QGSwitch = dynamic(() => import('@/components/core/module/Flow/components/modules/QGSwitch')); +import ChatTest from './ChatTest'; +import AppCard from './AppCard'; +import EditForm from './EditForm'; -function ConfigForm({ - divRef, - isSticky -}: { - divRef: React.RefObject; - isSticky: boolean; -}) { - const theme = useTheme(); - const router = useRouter(); - const { t } = useTranslation(); - const { appDetail, updateAppDetail } = useAppStore(); - const { loadAllDatasets, allDatasets } = useDatasetStore(); +const SimpleEdit = ({ appId }: { appId: string }) => { const { isPc } = useSystemStore(); - const [refresh, setRefresh] = useState(false); - - const { register, setValue, getValues, reset, handleSubmit, control } = - useForm({ - defaultValues: getDefaultAppForm() - }); - - const { fields: datasets, replace: replaceKbList } = useFieldArray({ - control, - name: 'dataset.datasets' - }); - - const { - isOpen: isOpenAIChatSetting, - onOpen: onOpenAIChatSetting, - onClose: onCloseAIChatSetting - } = useDisclosure(); - const { - isOpen: isOpenDatasetSelect, - onOpen: onOpenKbSelect, - onClose: onCloseKbSelect - } = useDisclosure(); - const { - isOpen: isOpenDatasetParams, - onOpen: onOpenKbParams, - onClose: onCloseKbParams - } = useDisclosure(); - - const { openConfirm: openConfirmSave, ConfirmModal: ConfirmSaveModal } = useConfirm({ - content: t('core.app.edit.Confirm Save App Tip') - }); - - const chatModelSelectList = useMemo(() => { - return chatModelList.map((item) => ({ - value: item.model, - label: item.name - })); - }, [refresh]); - - const selectDatasets = useMemo( - () => allDatasets.filter((item) => datasets.find((dataset) => dataset.datasetId === item._id)), - [allDatasets, datasets] - ); - - const selectSimpleTemplate = useMemo( - () => - simpleModeTemplates?.find((item) => item.id === getValues('templateId')) || - SimpleModeTemplate_FastGPT_Universal, - [getValues, refresh] - ); - - const tokenLimit = useMemo(() => { - return ( - chatModelList.find((item) => item.model === getValues('aiSettings.model'))?.quoteMaxToken || - 3000 - ); - }, [getValues, refresh]); - - const datasetSearchMode = useMemo(() => { - const mode = getValues('dataset.searchMode'); - if (!mode) return ''; - return t(DatasetSearchModeMap[mode]?.title); - }, [getValues, t, refresh]); - - const { mutate: onSubmitSave, isLoading: isSaving } = useRequest({ - mutationFn: async (data: AppSimpleEditFormType) => { - const modules = await postForm2Modules(data, data.templateId); - - await updateAppDetail(appDetail._id, { - modules, - type: AppTypeEnum.simple, - simpleTemplateId: data.templateId, - permission: undefined - }); - }, - successToast: t('common.Save Success'), - errorToast: t('common.Save Failed') - }); - - const appModule2Form = useCallback(() => { - const formVal = appModules2Form({ - templateId: appDetail.simpleTemplateId, - modules: appDetail.modules - }); - - reset(formVal); - setTimeout(() => { - setRefresh((state) => !state); - }, 100); - }, [appDetail.modules, appDetail.simpleTemplateId, reset]); - - useEffect(() => { - appModule2Form(); - }, [appModule2Form]); - useQuery(['loadAllDatasets'], loadAllDatasets); - - const BoxStyles: BoxProps = { - bg: 'myWhite.200', - px: 4, - py: 3, - borderRadius: 'lg', - border: theme.borders.base - }; - const BoxBtnStyles: BoxProps = { - cursor: 'pointer', - px: 3, - py: '2px', - borderRadius: 'md', - _hover: { - bg: 'myGray.200' - } - }; - const LabelStyles: BoxProps = { - w: ['60px', '100px'], - flexShrink: 0, - fontSize: ['sm', 'md'] - }; - - return ( - - {/* title */} - - - {t('core.app.App params config')} - - - - - - - - - {/* simple mode select */} - - - {''} - {t('core.app.simple.mode template select')} - - ({ - alias: item.name, - label: item.desc, - value: item.id - })) || [] - } - value={getValues('templateId')} - onchange={(val) => { - setValue('templateId', val); - setRefresh(!refresh); - }} - /> - - - {/* ai */} - {selectSimpleTemplate?.systemForm?.aiSettings && ( - - - {''} - - {t('app.AI Settings')} - - {(selectSimpleTemplate.systemForm.aiSettings.maxToken || - selectSimpleTemplate.systemForm.aiSettings.temperature || - selectSimpleTemplate.systemForm.aiSettings.quoteTemplate || - selectSimpleTemplate.systemForm.aiSettings.quotePrompt) && ( - - - {t('app.Open AI Advanced Settings')} - - )} - - {selectSimpleTemplate.systemForm.aiSettings?.model && ( - - {t('core.ai.Model')} - - { - setValue('aiSettings.model', val); - const maxToken = - chatModelList.find((item) => item.model === getValues('aiSettings.model')) - ?.maxResponse || 4000; - const token = maxToken / 2; - setValue('aiSettings.maxToken', token); - setRefresh(!refresh); - }} - /> - - - )} - - {selectSimpleTemplate.systemForm.aiSettings?.systemPrompt && ( - - - {t('core.ai.Prompt')} - - - - - { - setValue('aiSettings.systemPrompt', e.target.value || ''); - }} - /> - - )} - - )} - - {/* dataset */} - {selectSimpleTemplate?.systemForm?.dataset && ( - - - - {''} - {t('core.dataset.Choose Dataset')} - - {selectSimpleTemplate.systemForm.dataset.datasets && ( - - - {t('common.Choose')} - - )} - {(selectSimpleTemplate.systemForm.dataset.limit || - selectSimpleTemplate.systemForm.dataset.searchMode || - selectSimpleTemplate.systemForm.dataset.searchEmptyText || - selectSimpleTemplate.systemForm.dataset.similarity) && ( - - - {t('common.Params')} - - )} - - {getValues('dataset.datasets').length > 0 && ( - - {t('core.dataset.search.search mode')}: {datasetSearchMode} - {', '} - {t('core.dataset.search.Min Similarity')}: {getValues('dataset.similarity')} - {', '} - {t('core.dataset.search.Max Tokens')}: {getValues('dataset.limit')} - {getValues('dataset.searchEmptyText') === '' - ? '' - : t('core.dataset.Set Empty Result Tip')} - - )} - - {selectDatasets.map((item) => ( - - - router.push({ - pathname: '/dataset/detail', - query: { - datasetId: item._id - } - }) - } - > - - - {item.name} - - - - ))} - - - {selectSimpleTemplate?.systemForm?.cfr && getValues('dataset.datasets').length > 0 && ( - - - {t('core.app.edit.cfr background prompt')} - - - - - { - setValue('cfr.background', e.target.value || ''); - }} - /> - - )} - - )} - - {/* variable */} - {selectSimpleTemplate?.systemForm?.userGuide?.variables && ( - - { - setValue('userGuide.variables', e); - setRefresh(!refresh); - }} - /> - - )} - - {/* welcome */} - {selectSimpleTemplate?.systemForm?.userGuide?.welcomeText && ( - - - {''} - {t('core.app.Welcome Text')} - - - - - { - setValue('userGuide.welcomeText', e.target.value || ''); - }} - /> - - )} - - {/* tts */} - {selectSimpleTemplate?.systemForm?.userGuide?.tts && ( - - { - setValue('userGuide.tts', e); - setRefresh((state) => !state); - }} - /> - - )} - - {/* question guide */} - {selectSimpleTemplate?.systemForm?.userGuide?.questionGuide && ( - - { - const value = e.target.checked; - setValue('userGuide.questionGuide', value); - setRefresh((state) => !state); - }} - /> - - )} - - - - {isOpenAIChatSetting && ( - { - setValue('aiSettings', e); - onCloseAIChatSetting(); - }} - defaultData={getValues('aiSettings')} - simpleModeTemplate={selectSimpleTemplate} - /> - )} - {isOpenDatasetSelect && ( - ({ - datasetId: item._id, - vectorModel: item.vectorModel - }))} - onClose={onCloseKbSelect} - onChange={replaceKbList} - /> - )} - {isOpenDatasetParams && ( - { - setValue('dataset', { - ...getValues('dataset'), - ...e - }); - - setRefresh((state) => !state); - }} - /> - )} - - ); -} - -function Settings({ appId }: { appId: string }) { - const theme = useTheme(); - const router = useRouter(); - const { t } = useTranslation(); - const { toast } = useToast(); const { parentRef, divRef, isSticky } = useSticky(); - const { appDetail } = useAppStore(); - const [settingAppInfo, setSettingAppInfo] = useState(); - - const { openConfirm: openConfirmDel, ConfirmModal: ConfirmDelModal } = useConfirm({ - content: t('app.Confirm Del App Tip') - }); - - /* 点击删除 */ - const { mutate: handleDelModel, isLoading } = useRequest({ - mutationFn: async () => { - if (!appDetail) return null; - await delModelById(appDetail._id); - return 'success'; - }, - onSuccess(res) { - if (!res) return; - toast({ - title: t('common.Delete Success'), - status: 'success' - }); - router.replace(`/app/list`); - }, - errorToast: t('common.Delete Failed') - }); return ( - - - - - - - - AppId:{' '} - - {appId} - - - - {/* basic info */} - - - - - {appDetail.name} - - {appDetail.isOwner && ( - } - variant={'whiteDanger'} - borderRadius={'md'} - aria-label={'delete'} - isLoading={isLoading} - onClick={openConfirmDel(handleDelModel)} - /> - )} - - - {appDetail.intro || '快来给应用一个介绍~'} - - - - - {appDetail.isOwner && ( - - )} - - - - {/* config form */} - - - - {settingAppInfo && ( - setSettingAppInfo(undefined)} /> - )} - - ); -} - -function ChatTest({ appId }: { appId: string }) { - const { t } = useTranslation(); - const { userInfo } = useUserStore(); - const { appDetail } = useAppStore(); - const ChatBoxRef = useRef(null); - const [modules, setModules] = useState([]); - - const startChat = useCallback( - async ({ chatList, controller, generatingMessage, variables }: StartChatFnProps) => { - let historyMaxLen = 0; - - modules.forEach((module) => { - module.inputs.forEach((input) => { - if ( - (input.key === ModuleInputKeyEnum.history || - input.key === ModuleInputKeyEnum.historyMaxAmount) && - typeof input.value === 'number' - ) { - historyMaxLen = Math.max(historyMaxLen, input.value); - } - }); - }); - const history = chatList.slice(-historyMaxLen - 2, -2); - - // 流请求,获取数据 - const { responseText, responseData } = await streamFetch({ - url: '/api/core/chat/chatTest', - data: { - history, - prompt: chatList[chatList.length - 2].value, - modules, - variables, - appId, - appName: `调试-${appDetail.name}` - }, - onMessage: generatingMessage, - abortSignal: controller - }); - - return { responseText, responseData }; - }, - [modules, appId, appDetail.name] - ); - - const resetChatBox = useCallback(() => { - ChatBoxRef.current?.resetHistory([]); - ChatBoxRef.current?.resetVariables(); - }, []); - - useEffect(() => { - resetChatBox(); - setModules(appDetail.modules); - }, [appDetail, resetChatBox]); + + + - return ( - - - - {t('app.Chat Debug')} + + - - } - variant={'whiteDanger'} - borderRadius={'md'} - aria-label={'delete'} - onClick={(e) => { - e.stopPropagation(); - resetChatBox(); - }} - /> - - - - {}} - /> - {appDetail.type !== AppTypeEnum.simple && ( - - {t('app.Advance App TestTip')} - - )} - - ); -} - -const SimpleEdit = ({ appId }: { appId: string }) => { - const { isPc } = useSystemStore(); - return ( - - {isPc && } ); }; -export default SimpleEdit; +export default React.memo(SimpleEdit); diff --git a/projects/app/src/pages/app/detail/index.tsx b/projects/app/src/pages/app/detail/index.tsx index 7d9989416aa..03991d2f8f4 100644 --- a/projects/app/src/pages/app/detail/index.tsx +++ b/projects/app/src/pages/app/detail/index.tsx @@ -9,7 +9,7 @@ import { feConfigs } from '@/web/common/system/staticData'; import Tabs from '@/components/Tabs'; import SideTabs from '@/components/SideTabs'; import Avatar from '@/components/Avatar'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import PageContainer from '@/components/PageContainer'; import Loading from '@/components/Loading'; import SimpleEdit from './components/SimpleEdit'; @@ -52,13 +52,13 @@ const AppDetail = ({ currentTab }: { currentTab: `${TabEnum}` }) => { const tabList = useMemo( () => [ - { label: '简易配置', id: TabEnum.simpleEdit, icon: 'overviewLight' }, + { label: '简易配置', id: TabEnum.simpleEdit, icon: 'common/overviewLight' }, ...(feConfigs?.hide_app_flow ? [] - : [{ label: '高级编排', id: TabEnum.adEdit, icon: 'settingLight' }]), - { label: '外部使用', id: TabEnum.outLink, icon: 'shareLight' }, + : [{ label: '高级编排', id: TabEnum.adEdit, icon: 'common/settingLight' }]), + { label: '外部使用', id: TabEnum.outLink, icon: 'support/outlink/shareLight' }, { label: '对话日志', id: TabEnum.logs, icon: 'core/app/logsLight' }, - { label: '立即对话', id: TabEnum.startChat, icon: 'chat' } + { label: '立即对话', id: TabEnum.startChat, icon: 'core/chat/chatLight' } ], [] ); @@ -139,7 +139,7 @@ const AppDetail = ({ currentTab }: { currentTab: `${TabEnum}` }) => { > } + icon={} bg={'white'} boxShadow={'1px 1px 9px rgba(0,0,0,0.15)'} size={'smSquare'} diff --git a/projects/app/src/pages/app/list/index.tsx b/projects/app/src/pages/app/list/index.tsx index ee9ca67e68f..b7094cae3c3 100644 --- a/projects/app/src/pages/app/list/index.tsx +++ b/projects/app/src/pages/app/list/index.tsx @@ -19,7 +19,7 @@ import { useConfirm } from '@/web/common/hooks/useConfirm'; import { serviceSideProps } from '@/web/common/utils/i18n'; import { useTranslation } from 'next-i18next'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import PageContainer from '@/components/PageContainer'; import Avatar from '@/components/Avatar'; import MyTooltip from '@/components/MyTooltip'; @@ -164,7 +164,7 @@ const MyApps = () => { variant={'whitePrimary'} icon={ - + } aria-label={'chat'} diff --git a/projects/app/src/pages/appStore/components/list.tsx b/projects/app/src/pages/appStore/components/list.tsx index 42e01c0f041..e4361eaffc3 100644 --- a/projects/app/src/pages/appStore/components/list.tsx +++ b/projects/app/src/pages/appStore/components/list.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Box, Flex, Button, Card } from '@chakra-ui/react'; import type { ShareAppItem } from '@/types/app'; import { useRouter } from 'next/router'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import Avatar from '@/components/Avatar'; import MyTooltip from '@/components/MyTooltip'; diff --git a/projects/app/src/pages/chat/components/ChatHeader.tsx b/projects/app/src/pages/chat/components/ChatHeader.tsx index 32002bb4ed9..b80cb3b2bd9 100644 --- a/projects/app/src/pages/chat/components/ChatHeader.tsx +++ b/projects/app/src/pages/chat/components/ChatHeader.tsx @@ -1,7 +1,7 @@ import React, { useMemo } from 'react'; import { Flex, useTheme, Box } from '@chakra-ui/react'; import { useSystemStore } from '@/web/common/system/useSystemStore'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import Tag from '@/components/Tag'; import Avatar from '@/components/Avatar'; import ToolMenu from './ToolMenu'; diff --git a/projects/app/src/pages/chat/components/ChatHistorySlider.tsx b/projects/app/src/pages/chat/components/ChatHistorySlider.tsx index 231d172c215..767615220ea 100644 --- a/projects/app/src/pages/chat/components/ChatHistorySlider.tsx +++ b/projects/app/src/pages/chat/components/ChatHistorySlider.tsx @@ -15,7 +15,7 @@ import { useEditTitle } from '@/web/common/hooks/useEditTitle'; import { useRouter } from 'next/router'; import Avatar from '@/components/Avatar'; import MyTooltip from '@/components/MyTooltip'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import { useTranslation } from 'next-i18next'; import { useConfirm } from '@/web/common/hooks/useConfirm'; import Tabs from '@/components/Tabs'; @@ -156,7 +156,7 @@ const ChatHistorySlider = ({ h={'100%'} color={'primary.600'} borderRadius={'xl'} - leftIcon={} + leftIcon={} overflow={'hidden'} onClick={() => onChangeChat()} > @@ -173,7 +173,7 @@ const ChatHistorySlider = ({ borderRadius={'50%'} onClick={openConfirm(onClearHistory)} > - + )} @@ -211,7 +211,10 @@ const ChatHistorySlider = ({ } })} > - + {item.customTitle || item.title} @@ -236,7 +239,7 @@ const ChatHistorySlider = ({ onSetHistoryTop({ chatId: item.id, top: !item.top }); }} > - + {item.top ? '取消置顶' : '置顶'} )} @@ -254,7 +257,7 @@ const ChatHistorySlider = ({ }); }} > - + {t('common.Custom Title')} )} @@ -326,7 +329,7 @@ const ChatHistorySlider = ({ > } + icon={} bg={'white'} boxShadow={'1px 1px 9px rgba(0,0,0,0.15)'} size={'smSquare'} diff --git a/projects/app/src/pages/chat/components/SliderApps.tsx b/projects/app/src/pages/chat/components/SliderApps.tsx index de64417a8ca..5960a46f7f5 100644 --- a/projects/app/src/pages/chat/components/SliderApps.tsx +++ b/projects/app/src/pages/chat/components/SliderApps.tsx @@ -3,7 +3,7 @@ import { Flex, Box, IconButton } from '@chakra-ui/react'; import { useRouter } from 'next/router'; import { useQuery } from '@tanstack/react-query'; import { useTranslation } from 'next-i18next'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import Avatar from '@/components/Avatar'; import { useAppStore } from '@/web/core/app/store/useAppStore'; @@ -28,7 +28,7 @@ const SliderApps = ({ appId }: { appId: string }) => { > } + icon={} bg={'white'} boxShadow={'1px 1px 9px rgba(0,0,0,0.15)'} size={'smSquare'} diff --git a/projects/app/src/pages/chat/components/ToolMenu.tsx b/projects/app/src/pages/chat/components/ToolMenu.tsx index c5e27af499f..af4b91dc2e8 100644 --- a/projects/app/src/pages/chat/components/ToolMenu.tsx +++ b/projects/app/src/pages/chat/components/ToolMenu.tsx @@ -2,7 +2,7 @@ import React, { useMemo } from 'react'; import { useChatBox } from '@/components/ChatBox'; import type { ChatItemType } from '@fastgpt/global/core/chat/type.d'; import { Menu, MenuButton, MenuList, MenuItem, Box } from '@chakra-ui/react'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import { useRouter } from 'next/router'; const ToolMenu = ({ history }: { history: ChatItemType[] }) => { @@ -12,7 +12,7 @@ const ToolMenu = ({ history }: { history: ChatItemType[] }) => { const menuList = useMemo( () => [ { - icon: 'chat', + icon: 'core/chat/chatLight', label: '新对话', onClick: () => { router.replace({ @@ -24,16 +24,16 @@ const ToolMenu = ({ history }: { history: ChatItemType[] }) => { } }, { - icon: 'apiLight', + icon: 'core/app/appApiLight', label: 'HTML导出', onClick: () => onExportChat({ type: 'html', history }) }, { - icon: 'markdown', + icon: 'file/markdown', label: 'Markdown导出', onClick: () => onExportChat({ type: 'md', history }) }, - { icon: 'pdf', label: 'PDF导出', onClick: () => onExportChat({ type: 'pdf', history }) } + { icon: 'file/pdf', label: 'PDF导出', onClick: () => onExportChat({ type: 'pdf', history }) } ], [history, onExportChat, router] ); diff --git a/projects/app/src/pages/dataset/detail/components/CollectionCard.tsx b/projects/app/src/pages/dataset/detail/components/CollectionCard.tsx index f021f791065..e2dce4bcefc 100644 --- a/projects/app/src/pages/dataset/detail/components/CollectionCard.tsx +++ b/projects/app/src/pages/dataset/detail/components/CollectionCard.tsx @@ -28,7 +28,7 @@ import { useQuery } from '@tanstack/react-query'; import { debounce } from 'lodash'; import { useConfirm } from '@/web/common/hooks/useConfirm'; import { useTranslation } from 'next-i18next'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import MyInput from '@/components/MyInput'; import dayjs from 'dayjs'; import { useRequest } from '@/web/common/hooks/useRequest'; @@ -386,7 +386,7 @@ const CollectionCard = () => { color={'white'} h={['28px', '35px']} > - + {t('dataset.collections.Create And Import')} diff --git a/projects/app/src/pages/dataset/detail/components/DataCard.tsx b/projects/app/src/pages/dataset/detail/components/DataCard.tsx index e126a9d74c7..9286c37573d 100644 --- a/projects/app/src/pages/dataset/detail/components/DataCard.tsx +++ b/projects/app/src/pages/dataset/detail/components/DataCard.tsx @@ -29,7 +29,7 @@ import { getErrText } from '@fastgpt/global/common/error/utils'; import { useConfirm } from '@/web/common/hooks/useConfirm'; import { useTranslation } from 'next-i18next'; import { useRouter } from 'next/router'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import MyInput from '@/components/MyInput'; import { useLoading } from '@/web/common/hooks/useLoading'; import InputDataModal, { RawSourceText, type InputDataType } from '../components/InputDataModal'; @@ -167,7 +167,7 @@ const DataCard = () => { } + icon={} variant={'whitePrimary'} size={'smSquare'} borderRadius={'50%'} diff --git a/projects/app/src/pages/dataset/detail/components/Import/FileSelect.tsx b/projects/app/src/pages/dataset/detail/components/Import/FileSelect.tsx index dbc1cde7f0e..f4917cda0c4 100644 --- a/projects/app/src/pages/dataset/detail/components/Import/FileSelect.tsx +++ b/projects/app/src/pages/dataset/detail/components/Import/FileSelect.tsx @@ -1,4 +1,4 @@ -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import { useLoading } from '@/web/common/hooks/useLoading'; import { useSelectFile } from '@/web/common/file/hooks/useSelectFile'; import { useToast } from '@/web/common/hooks/useToast'; @@ -392,7 +392,7 @@ const FileSelect = ({ onDrop={handleDrop} > - + {isDragging ? ( t('file.Release the mouse to upload the file') ) : ( diff --git a/projects/app/src/pages/dataset/detail/components/Import/ImportModal.tsx b/projects/app/src/pages/dataset/detail/components/Import/ImportModal.tsx index 6d91b69827b..1848e947b9a 100644 --- a/projects/app/src/pages/dataset/detail/components/Import/ImportModal.tsx +++ b/projects/app/src/pages/dataset/detail/components/Import/ImportModal.tsx @@ -98,19 +98,19 @@ const ImportData = ({ gridTemplateColumns={['repeat(1,1fr)', 'repeat(3,1fr)']} list={[ { - icon: 'indexImport', + icon: 'file/indexImport', title: t('core.dataset.import.Chunk Split'), desc: t('core.dataset.import.Chunk Split Tip'), value: ImportTypeEnum.chunk }, { - icon: 'qaImport', + icon: 'file/qaImport', title: t('core.dataset.import.QA Import'), desc: t('core.dataset.import.QA Import Tip'), value: ImportTypeEnum.qa }, { - icon: 'csvImport', + icon: 'file/csv', title: t('core.dataset.import.CSV Import'), desc: t('core.dataset.import.CSV Import Tip'), value: ImportTypeEnum.csv diff --git a/projects/app/src/pages/dataset/detail/components/Import/Provider.tsx b/projects/app/src/pages/dataset/detail/components/Import/Provider.tsx index 2406ec11bb8..52625fd97dc 100644 --- a/projects/app/src/pages/dataset/detail/components/Import/Provider.tsx +++ b/projects/app/src/pages/dataset/detail/components/Import/Provider.tsx @@ -22,8 +22,8 @@ import { } from '@fastgpt/global/core/dataset/constant'; import { Box, Flex, Image, useTheme } from '@chakra-ui/react'; import { CloseIcon } from '@chakra-ui/icons'; -import DeleteIcon, { hoverDeleteStyles } from '@/components/Icon/delete'; -import MyIcon from '@/components/Icon'; +import DeleteIcon, { hoverDeleteStyles } from '@fastgpt/web/components/common/Icon/delete'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import { chunksUpload } from '@/web/core/dataset/utils'; import { postCreateTrainingBill } from '@/web/support/wallet/bill/api'; import { useTranslation } from 'next-i18next'; diff --git a/projects/app/src/pages/dataset/detail/components/InputDataModal.tsx b/projects/app/src/pages/dataset/detail/components/InputDataModal.tsx index e5bdb6b621c..53856041450 100644 --- a/projects/app/src/pages/dataset/detail/components/InputDataModal.tsx +++ b/projects/app/src/pages/dataset/detail/components/InputDataModal.tsx @@ -9,7 +9,7 @@ import { } from '@/web/core/dataset/api'; import { useToast } from '@/web/common/hooks/useToast'; import { getErrText } from '@fastgpt/global/common/error/utils'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import MyModal from '@/components/MyModal'; import MyTooltip from '@/components/MyTooltip'; import { QuestionOutlineIcon } from '@chakra-ui/icons'; @@ -26,7 +26,7 @@ import { DatasetDataIndexTypeEnum } from '@fastgpt/global/core/dataset/constant' import { DatasetDataIndexItemType } from '@fastgpt/global/core/dataset/type'; import SideTabs from '@/components/SideTabs'; import { useLoading } from '@/web/common/hooks/useLoading'; -import DeleteIcon from '@/components/Icon/delete'; +import DeleteIcon from '@fastgpt/web/components/common/Icon/delete'; import { defaultCollectionDetail } from '@/constants/dataset'; import { getDocPath } from '@/web/common/system/doc'; @@ -83,7 +83,7 @@ const InputDataModal = ({ }); const tabList = [ - { label: t('dataset.data.edit.Content'), id: TabEnum.content, icon: 'overviewLight' }, + { label: t('dataset.data.edit.Content'), id: TabEnum.content, icon: 'common/overviewLight' }, { label: t('dataset.data.edit.Index', { amount: indexes.length }), id: TabEnum.index, diff --git a/projects/app/src/pages/dataset/detail/components/Test.tsx b/projects/app/src/pages/dataset/detail/components/Test.tsx index ed3f4e031e7..09f753e48a1 100644 --- a/projects/app/src/pages/dataset/detail/components/Test.tsx +++ b/projects/app/src/pages/dataset/detail/components/Test.tsx @@ -18,7 +18,7 @@ import { import { useDatasetStore } from '@/web/core/dataset/store/dataset'; import { useSearchTestStore, SearchTestStoreItemType } from '@/web/core/dataset/store/searchTest'; import { postSearchText } from '@/web/core/dataset/api'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import { useRequest } from '@/web/common/hooks/useRequest'; import { formatTimeToChatTime } from '@/utils/tools'; import { getErrText } from '@fastgpt/global/common/error/utils'; @@ -190,7 +190,7 @@ const Test = ({ datasetId }: { datasetId: string }) => { // { // label: ( // - // + // // // {t('core.dataset.test.Batch test')} // @@ -244,7 +244,7 @@ const Test = ({ datasetId }: { datasetId: string }) => { }} onClick={onOpen} > - + {selectFile ? selectFile.name : t('core.dataset.test.Batch test Placeholder')} diff --git a/projects/app/src/pages/dataset/detail/index.tsx b/projects/app/src/pages/dataset/detail/index.tsx index f1e451f6b5e..ad7f7ca0254 100644 --- a/projects/app/src/pages/dataset/detail/index.tsx +++ b/projects/app/src/pages/dataset/detail/index.tsx @@ -7,7 +7,7 @@ import { getErrText } from '@fastgpt/global/common/error/utils'; import { useSystemStore } from '@/web/common/system/useSystemStore'; import Tabs from '@/components/Tabs'; import dynamic from 'next/dynamic'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import SideTabs from '@/components/SideTabs'; import PageContainer from '@/components/PageContainer'; import Avatar from '@/components/Avatar'; @@ -54,10 +54,10 @@ const Detail = ({ datasetId, currentTab }: { datasetId: string; currentTab: `${T const { userInfo } = useUserStore(); const tabList = [ - { label: t('core.dataset.Dataset'), id: TabEnum.collectionCard, icon: 'overviewLight' }, + { label: t('core.dataset.Dataset'), id: TabEnum.collectionCard, icon: 'common/overviewLight' }, { label: t('core.dataset.test.Search Test'), id: TabEnum.test, icon: 'kbTest' }, ...(userInfo?.team.canWrite && datasetDetail.isOwner - ? [{ label: t('common.Config'), id: TabEnum.info, icon: 'settingLight' }] + ? [{ label: t('common.Config'), id: TabEnum.info, icon: 'common/settingLight' }] : []) ]; @@ -240,7 +240,7 @@ const Detail = ({ datasetId, currentTab }: { datasetId: string; currentTab: `${T > } + icon={} bg={'white'} boxShadow={'1px 1px 9px rgba(0,0,0,0.15)'} size={'smSquare'} diff --git a/projects/app/src/pages/dataset/list/component/MoveModal.tsx b/projects/app/src/pages/dataset/list/component/MoveModal.tsx index 381e11112e3..e96a19702ca 100644 --- a/projects/app/src/pages/dataset/list/component/MoveModal.tsx +++ b/projects/app/src/pages/dataset/list/component/MoveModal.tsx @@ -13,7 +13,7 @@ import { import Avatar from '@/components/Avatar'; import MyTooltip from '@/components/MyTooltip'; import MyModal from '@/components/MyModal'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constant'; import { useTranslation } from 'next-i18next'; import { useQuery } from '@tanstack/react-query'; diff --git a/projects/app/src/pages/dataset/list/index.tsx b/projects/app/src/pages/dataset/list/index.tsx index b76c497695f..9482534dc27 100644 --- a/projects/app/src/pages/dataset/list/index.tsx +++ b/projects/app/src/pages/dataset/list/index.tsx @@ -25,7 +25,7 @@ import { } from '@/web/core/dataset/api'; import { useTranslation } from 'next-i18next'; import Avatar from '@/components/Avatar'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import { serviceSideProps } from '@/web/common/utils/i18n'; import dynamic from 'next/dynamic'; import { diff --git a/projects/app/src/pages/login/components/LoginForm.tsx b/projects/app/src/pages/login/components/LoginForm.tsx index 0714d87c95e..79f9dbba043 100644 --- a/projects/app/src/pages/login/components/LoginForm.tsx +++ b/projects/app/src/pages/login/components/LoginForm.tsx @@ -19,7 +19,7 @@ import type { ResLogin } from '@/global/support/api/userRes'; import { useToast } from '@/web/common/hooks/useToast'; import { feConfigs } from '@/web/common/system/staticData'; import { useSystemStore } from '@/web/common/system/useSystemStore'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import { customAlphabet } from 'nanoid'; import { getDocPath } from '@/web/common/system/doc'; import Avatar from '@/components/Avatar'; @@ -86,7 +86,7 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => { { label: t('support.user.login.Github'), provider: OAuthEnum.github, - icon: 'gitFill', + icon: 'common/gitFill', redirectUrl: `https://github.com/login/oauth/authorize?client_id=${feConfigs?.oauth?.github}&redirect_uri=${redirectUri}&state=${state.current}&scope=user:email%20read:user` } ] @@ -96,7 +96,7 @@ const LoginForm = ({ setPageType, loginSuccess }: Props) => { { label: t('support.user.login.Google'), provider: OAuthEnum.google, - icon: 'googleFill', + icon: 'common/googleFill', redirectUrl: `https://accounts.google.com/o/oauth2/v2/auth?client_id=${feConfigs?.oauth?.google}&redirect_uri=${redirectUri}&state=${state.current}&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20openid&include_granted_scopes=true` } ] diff --git a/projects/app/src/pages/plugin/edit/Header.tsx b/projects/app/src/pages/plugin/edit/Header.tsx index af73a51fac9..0d9b8fb0486 100644 --- a/projects/app/src/pages/plugin/edit/Header.tsx +++ b/projects/app/src/pages/plugin/edit/Header.tsx @@ -5,7 +5,7 @@ import { useRequest } from '@/web/common/hooks/useRequest'; import { useTranslation } from 'next-i18next'; import { useCopyData } from '@/web/common/hooks/useCopyData'; import dynamic from 'next/dynamic'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import MyTooltip from '@/components/MyTooltip'; import { getFlowStore } from '@/components/core/module/Flow/FlowProvider'; import { filterExportModules, flowNode2Modules } from '@/components/core/module/utils'; @@ -123,7 +123,7 @@ const Header = ({ plugin, onClose }: Props) => { } + icon={} variant={'whiteBase'} aria-label={''} onClick={() => { @@ -138,7 +138,7 @@ const Header = ({ plugin, onClose }: Props) => { } + icon={} variant={'whitePrimary'} size={'smSquare'} aria-label={'save'} @@ -163,7 +163,7 @@ const Header = ({ plugin, onClose }: Props) => { } + icon={} size={'smSquare'} aria-label={'save'} variant={'whitePrimary'} diff --git a/projects/app/src/pages/plugin/list/component/EditModal.tsx b/projects/app/src/pages/plugin/list/component/EditModal.tsx index 4c593a537d5..60fc6af5396 100644 --- a/projects/app/src/pages/plugin/list/component/EditModal.tsx +++ b/projects/app/src/pages/plugin/list/component/EditModal.tsx @@ -14,7 +14,7 @@ import MyTooltip from '@/components/MyTooltip'; import MyModal from '@/components/MyModal'; import { useTranslation } from 'next-i18next'; import { useConfirm } from '@/web/common/hooks/useConfirm'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import { CreateOnePluginParams } from '@fastgpt/global/core/plugin/controller'; import { customAlphabet } from 'nanoid'; const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12); diff --git a/projects/app/src/pages/plugin/list/index.tsx b/projects/app/src/pages/plugin/list/index.tsx index 12399d1bea8..63d5e2acce8 100644 --- a/projects/app/src/pages/plugin/list/index.tsx +++ b/projects/app/src/pages/plugin/list/index.tsx @@ -6,7 +6,7 @@ import { AddIcon } from '@chakra-ui/icons'; import { serviceSideProps } from '@/web/common/utils/i18n'; import { useTranslation } from 'next-i18next'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import PageContainer from '@/components/PageContainer'; import Avatar from '@/components/Avatar'; import EditModal, { defaultForm, FormType } from './component/EditModal'; diff --git a/projects/app/src/pages/tools/index.tsx b/projects/app/src/pages/tools/index.tsx index f9b552001fc..12288c356bd 100644 --- a/projects/app/src/pages/tools/index.tsx +++ b/projects/app/src/pages/tools/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Box, Flex } from '@chakra-ui/react'; import { ChevronRightIcon } from '@chakra-ui/icons'; -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import { useRouter } from 'next/router'; import { feConfigs } from '@/web/common/system/staticData'; import { serviceSideProps } from '@/web/common/utils/i18n'; @@ -13,19 +13,10 @@ const Tools = () => { const router = useRouter(); const list = [ { - icon: 'dbLight', + icon: 'core/dataset/datasetLight', label: '我的知识库', link: '/dataset/list' }, - ...(feConfigs?.show_appStore - ? [ - { - icon: 'appStoreLight', - label: 'AI应用市场', - link: '/appStore' - } - ] - : []), { icon: 'common/navbar/pluginLight', label: '自定义模块', @@ -34,7 +25,7 @@ const Tools = () => { ...(feConfigs?.show_git ? [ { - icon: 'git', + icon: 'common/gitLight', label: 'GitHub 地址', link: 'https://github.com/labring/FastGPT' } diff --git a/projects/app/src/service/moduleDispatch/tools/cfr.ts b/projects/app/src/service/moduleDispatch/tools/cfr.ts index eecbc6c8a5a..341acf5d266 100644 --- a/projects/app/src/service/moduleDispatch/tools/cfr.ts +++ b/projects/app/src/service/moduleDispatch/tools/cfr.ts @@ -26,7 +26,9 @@ export const dispatchCFR = async ({ return Promise.reject('Question is empty'); } - if (histories.length === 0 && !systemPrompt) { + // none + // first chat and no system prompt + if (systemPrompt === 'none' || (histories.length === 0 && !systemPrompt)) { return { [ModuleOutputKeyEnum.text]: userChatInput }; diff --git a/projects/app/src/web/core/dataset/components/SelectCollections.tsx b/projects/app/src/web/core/dataset/components/SelectCollections.tsx index 0bedf48da98..ca6d89854fa 100644 --- a/projects/app/src/web/core/dataset/components/SelectCollections.tsx +++ b/projects/app/src/web/core/dataset/components/SelectCollections.tsx @@ -1,4 +1,4 @@ -import MyIcon from '@/components/Icon'; +import MyIcon from '@fastgpt/web/components/common/Icon'; import MyModal from '@/components/MyModal'; import ParentPaths from '@/components/common/ParentPaths'; import { useLoading } from '@/web/common/hooks/useLoading'; diff --git a/scripts/icon/index.js b/scripts/icon/index.js new file mode 100644 index 00000000000..5060ca074f3 --- /dev/null +++ b/scripts/icon/index.js @@ -0,0 +1,105 @@ +const path = require('path'); +const fs = require('fs'); +const express = require('express'); + +function findSvgFiles(dir, relativePath = '') { + let svgFiles = []; + const items = fs.readdirSync(dir, { withFileTypes: true }); + + for (const item of items) { + const fullPath = path.resolve(dir, item.name); + const relativeItemPath = path.join(relativePath, item.name); + + if (item.isDirectory()) { + const nestedSvgs = findSvgFiles(fullPath, relativeItemPath); + svgFiles = svgFiles.concat(nestedSvgs); + } else if (item.isFile() && item.name.endsWith('.svg')) { + svgFiles.push(relativeItemPath); + } + } + + return svgFiles; +} + +const svgDir = path.resolve(__dirname, '../../packages/web/components/common/Icon/icons'); +const svgPaths = findSvgFiles(svgDir); + +const app = express(); + +app.use('/icons', express.static(svgDir)); + +app.get('/', (req, res) => { + let iconHtml = ``; + + svgPaths.forEach((filePath) => { + const name = filePath.split('.')[0]; + iconHtml += `

+ +
${name}
+
`; + }); + + const html = ` +SVG Icons + + +
+ ${iconHtml} +
+ + + + `; + + res.send(html); +}); + +const PORT = process.env.PORT || 3005; +app.listen(PORT, () => { + console.log(`Preview icons server running at http://localhost:${PORT}`); +}); diff --git a/scripts/icon/init.js b/scripts/icon/init.js new file mode 100644 index 00000000000..f8ce237c3d9 --- /dev/null +++ b/scripts/icon/init.js @@ -0,0 +1,42 @@ +const path = require('path'); +const fs = require('fs'); + +// 递归读取 packages/web/components/common/Icon/icons 下所有的 svg +function findSvgFiles(dir, relativePath = '') { + let svgFiles = []; + + const items = fs.readdirSync(dir, { withFileTypes: true }); + + for (const item of items) { + const fullPath = path.join(dir, item.name); + const relativeItemPath = path.join(relativePath, item.name); + + if (item.isDirectory()) { + const nestedSvgs = findSvgFiles(fullPath, relativeItemPath); + svgFiles = svgFiles.concat(nestedSvgs); + } else if (item.isFile() && item.name.endsWith('.svg')) { + svgFiles.push(relativeItemPath); + } + } + + return svgFiles; +} + +const svgPaths = findSvgFiles(`${__dirname}/../../packages/web/components/common/Icon/icons`); + +let result = ``; + +svgPaths.forEach((path) => { + const name = path.split('.')[0]; + result += ` '${name}': () => import('./icons/${path}'),\n`; +}); + +// 把 result 结果写入 '../../packages/web/components/common/Icon/constants' +fs.writeFileSync( + `${__dirname}/../../packages/web/components/common/Icon/constants.ts`, + `// @ts-nocheck + + export const iconPaths = { + ${result} + };` +); diff --git a/scripts/icon/package-lock.json b/scripts/icon/package-lock.json new file mode 100644 index 00000000000..d41326eb239 --- /dev/null +++ b/scripts/icon/package-lock.json @@ -0,0 +1,613 @@ +{ + "name": "icon", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "icon", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "express": "^4.18.2" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmmirror.com/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmmirror.com/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + } + } +} diff --git a/scripts/icon/package.json b/scripts/icon/package.json new file mode 100644 index 00000000000..bc91adf3ecc --- /dev/null +++ b/scripts/icon/package.json @@ -0,0 +1,15 @@ +{ + "name": "icon", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.18.2" + } +}