wwf
2025-05-20 938c3e5a587ce950a94964ea509b9e7f8834dfae
初始化
1个文件已修改
3,890个文件已添加
416478 ■■■■■ 已修改文件
.dockerignore 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env.example 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.husky/pre-commit 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.storybook/main.ts 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.storybook/preview.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.storybook/storybook.css 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.vscode/extensions.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.vscode/settings.example.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Dockerfile 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
__mocks__/mime.js 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/annotations/page.tsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/configuration/page.tsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/develop/page.tsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/layout-main.tsx 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/logs/page.tsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/cardView.tsx 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/chartView.tsx 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/page.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config-button.tsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config-popup.tsx 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/field.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/panel.tsx 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-config-modal.tsx 390 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-panel.tsx 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/tracing-icon.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/type.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/style.module.css 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/[appId]/workflow/page.tsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/app/(appDetailLayout)/layout.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/AppCard.tsx 426 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/Apps.tsx 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/NewAppCard.tsx 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/assets/add.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/assets/chat-solid.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/assets/chat.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/assets/completion-solid.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/assets/completion.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/assets/discord.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/assets/github.svg 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/assets/link-gray.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/assets/link.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/assets/right-arrow.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/hooks/useAppsQueryState.ts 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/page.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/api/page.tsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/documents/[documentId]/page.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/documents/[documentId]/settings/page.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/documents/create/page.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/documents/page.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/documents/style.module.css 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/hitTesting/page.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout-main.tsx 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout.tsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/settings/page.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/(datasetDetailLayout)/layout.tsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/Container.tsx 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/DatasetCard.tsx 240 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/DatasetFooter.tsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/Datasets.tsx 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/Doc.tsx 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/NewDatasetCard.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/connect/page.tsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/create/page.tsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/layout.tsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/page.tsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/store.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/template/template.en.mdx 2352 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/template/template.ja.mdx 2005 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/template/template.zh.mdx 2394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/education-apply/page.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/explore/apps/page.tsx 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/explore/installed/[appId]/page.tsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/explore/layout.tsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/layout.tsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/list.module.css 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/plugins/page.tsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/tools/page.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(shareLayout)/chat/[token]/page.tsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(shareLayout)/chatbot/[token]/page.tsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(shareLayout)/completion/[token]/page.tsx 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(shareLayout)/layout.tsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(shareLayout)/webapp-signin/page.tsx 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(shareLayout)/workflow/[token]/page.tsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/account/account-page/AvatarWithEdit.tsx 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/account/account-page/index.module.css 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/account/account-page/index.tsx 320 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/account/avatar.tsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/account/delete-account/components/check-email.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/account/delete-account/components/feed-back.tsx 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/account/delete-account/components/verify-email.tsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/account/delete-account/index.tsx 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/account/delete-account/state.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/account/header.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/account/layout.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/account/page.tsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/activate/activateForm.tsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/activate/page.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app-sidebar/app-info.tsx 418 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app-sidebar/basic.tsx 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app-sidebar/completion.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app-sidebar/dataset-info.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app-sidebar/expert.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app-sidebar/index.tsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app-sidebar/navLink.tsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app-sidebar/style.module.css 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/add-annotation-modal/edit-item/index.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/add-annotation-modal/index.tsx 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/batch-add-annotation-modal/csv-downloader.tsx 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/batch-add-annotation-modal/csv-uploader.tsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/batch-add-annotation-modal/index.tsx 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/edit-annotation-modal/edit-item/index.tsx 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/edit-annotation-modal/index.tsx 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/empty-element.tsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/filter.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/header-opts/index.tsx 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/index.tsx 287 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/list.tsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/remove-annotation-confirm-modal/index.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/type.ts 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/view-annotation-modal/hit-history-no-data.tsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/annotation/view-annotation-modal/index.tsx 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/app-publisher/features-wrapper.tsx 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/app-publisher/index.tsx 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/app-publisher/publish-with-multiple-model.tsx 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/app-publisher/suggested-action.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/app-publisher/version-info-modal.tsx 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/feature-panel/index.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/group-name/index.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/icons/citation.tsx 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/icons/more-like-this-icon.tsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/icons/remove-icon/index.tsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/icons/remove-icon/style.module.css 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/icons/suggested-questions-after-answer-icon.tsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/operation-btn/index.tsx 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/var-highlight/index.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/var-highlight/style.module.css 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/warning-mask/cannot-query-dataset.tsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/warning-mask/formatting-changed.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/warning-mask/has-not-set-api.tsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/warning-mask/index.tsx 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/base/warning-mask/style.module.css 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-prompt/advanced-prompt-input.tsx 275 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-prompt/confirm-add-var/index.tsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-prompt/conversation-history/edit-modal.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-prompt/conversation-history/history-panel.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-prompt/index.tsx 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-prompt/message-type-selector.tsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-prompt/prompt-editor-height-resize-wrap.tsx 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-prompt/simple-prompt-input.tsx 284 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-prompt/style.module.css 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-var/config-modal/field.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-var/config-modal/index.tsx 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-var/config-select/index.spec.tsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-var/config-select/index.tsx 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-var/config-string/index.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-var/index.tsx 271 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-var/input-type-icon.tsx 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-var/modal-foot.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-var/select-type-item/index.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-var/select-var-type.tsx 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-var/var-item.tsx 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-vision/index.tsx 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-vision/param-config-content.tsx 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-vision/param-config.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/agent-setting-button.tsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/agent/agent-setting/index.tsx 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/agent/agent-setting/item-panel.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/agent/agent-tools/index.tsx 302 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/agent/prompt-editor.tsx 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/assistant-type-picker/index.tsx 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/automatic/automatic-btn.tsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/automatic/get-automatic-res.tsx 330 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/automatic/style.module.css 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/code-generator/get-code-generator-res.tsx 230 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/config-document.tsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/feature/use-feature.tsx 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/index.tsx 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/ctrl-btn-group/index.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/ctrl-btn-group/style.module.css 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/card-item/index.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/card-item/item.tsx 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/card-item/style.module.css 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/context-var/index.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/context-var/var-picker.tsx 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/index.tsx 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/params-config/config-content.tsx 382 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/params-config/index.tsx 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/params-config/weighted-score.css 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/params-config/weighted-score.tsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/select-dataset/index.tsx 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/settings-modal/index.tsx 390 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/dataset-config/type-icon/index.tsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/debug/chat-user-input.tsx 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/debug/debug-with-multiple-model/chat-item.tsx 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/debug/debug-with-multiple-model/context.tsx 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/debug/debug-with-multiple-model/debug-item.tsx 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/debug/debug-with-multiple-model/index.tsx 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/debug/debug-with-multiple-model/model-parameter-trigger.tsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/debug/debug-with-multiple-model/text-generation-item.tsx 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/debug/debug-with-single-model/index.tsx 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/debug/hooks.tsx 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/debug/index.tsx 561 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/debug/types.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/features/experience-enhance-group/index.tsx 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/features/experience-enhance-group/more-like-this/index.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/hooks/use-advanced-prompt-config.ts 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/images/prompt.svg 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/index.tsx 1068 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/prompt-mode/advanced-mode-waring.tsx 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/prompt-value-panel/index.tsx 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/prompt-value-panel/utils.ts 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/style.module.css 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/tools/external-data-tool-modal.tsx 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/tools/index.tsx 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/create-app-dialog/app-card/index.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/create-app-dialog/app-list/index.tsx 253 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/create-app-dialog/app-list/sidebar.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/create-app-dialog/index.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/create-app-modal/index.tsx 364 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/create-from-dsl-modal/dsl-confirm-modal.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/create-from-dsl-modal/index.tsx 320 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/create-from-dsl-modal/uploader.tsx 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/duplicate-modal/index.tsx 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/log-annotation/index.tsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/log/filter.tsx 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/log/index.tsx 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/log/list.tsx 764 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/log/model-info.tsx 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/log/var-panel.tsx 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/apikey-info-panel/index.tsx 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/appCard.tsx 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/appChart.tsx 450 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/assets/chromeplugin-install.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/assets/chromeplugin-option.svg 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/assets/code-browser.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/assets/iframe-option.svg 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/assets/refresh-hover.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/assets/refresh.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/assets/scripts-option.svg 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/customize/index.tsx 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/embedded/index.tsx 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/embedded/style.module.css 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/settings/index.tsx 474 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/overview/style.module.css 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/store.ts 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/switch-app-modal/index.tsx 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/text-generate/item/index.tsx 383 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/text-generate/item/result-tab.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/text-generate/saved-items/index.tsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/text-generate/saved-items/no-data/index.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/type-selector/index.tsx 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/workflow-log/detail.tsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/workflow-log/filter.tsx 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/workflow-log/index.tsx 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/workflow-log/list.tsx 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/action-button/index.css 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/action-button/index.tsx 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/agent-log-modal/detail.tsx 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/agent-log-modal/index.tsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/agent-log-modal/iteration.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/agent-log-modal/result.tsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/agent-log-modal/tool-call.tsx 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/agent-log-modal/tracing.tsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/answer-icon/index.tsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/app-icon-picker/ImageInput.tsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/app-icon-picker/hooks.tsx 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/app-icon-picker/index.tsx 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/app-icon-picker/style.module.css 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/app-icon-picker/utils.ts 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/app-icon/index.tsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/app-icon/style.module.css 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/app-unavailable.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/audio-btn/audio.player.manager.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/audio-btn/audio.ts 247 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/audio-btn/index.tsx 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/audio-btn/style.module.css 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/audio-gallery/AudioPlayer.tsx 319 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/audio-gallery/index.tsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/auto-height-textarea/common.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/auto-height-textarea/index.tsx 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/auto-height-textarea/style.module.scss 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/avatar/index.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/badge.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/badge/index.css 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/badge/index.tsx 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/block-input/index.tsx 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/button/add-button.tsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/button/index.css 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/button/index.spec.tsx 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/button/index.stories.tsx 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/button/index.tsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/__tests__/__snapshots__/utils.spec.ts.snap 2804 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/__tests__/branchedTestMessages.json 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/__tests__/legacyTestMessages.json 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/__tests__/mixedTestMessages.json 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/__tests__/multiRootNodesMessages.json 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/__tests__/multiRootNodesWithLegacyTestMessages.json 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/__tests__/partialMessages.json 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/__tests__/realWorldMessages.json 441 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/__tests__/utils.spec.ts 271 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/chat-wrapper.tsx 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/context.tsx 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/header-in-mobile.tsx 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/header/index.tsx 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/header/mobile-operation-dropdown.tsx 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/header/operation.tsx 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/hooks.tsx 495 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/index.tsx 253 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/inputs-form/content.tsx 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/inputs-form/index.tsx 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/inputs-form/view-form-dropdown.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/sidebar/index.tsx 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/sidebar/item.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/sidebar/list.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/sidebar/operation.tsx 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat-with-history/sidebar/rename-modal.tsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/answer/__mocks__/markdownContent.ts 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/answer/__mocks__/markdownContentSVG.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/answer/__mocks__/workflowProcess.ts 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/answer/agent-content.tsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/answer/basic-content.tsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/answer/index.stories.tsx 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/answer/index.tsx 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/answer/more.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/answer/operation.tsx 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/answer/suggested-questions.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/answer/tool-detail.tsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/answer/workflow-process.tsx 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/chat-input-area/hooks.ts 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/chat-input-area/index.tsx 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/chat-input-area/operation.tsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/check-input-forms-hooks.ts 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/citation/index.tsx 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/citation/popup.tsx 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/citation/progress-tooltip.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/citation/tooltip.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/content-switch.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/context.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/hooks.ts 710 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/index.tsx 348 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/loading-anim/index.tsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/loading-anim/style.module.css 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/log/index.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/question.stories.tsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/question.tsx 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/thought/index.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/thought/panel.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/thought/tool.tsx 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/try-to-ask.tsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/type.ts 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/chat/utils.ts 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/constants.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/embedded-chatbot/chat-wrapper.tsx 264 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/embedded-chatbot/context.tsx 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/embedded-chatbot/header/index.tsx 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/embedded-chatbot/hooks.tsx 405 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/embedded-chatbot/index.tsx 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/embedded-chatbot/inputs-form/content.tsx 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/embedded-chatbot/inputs-form/index.tsx 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/embedded-chatbot/inputs-form/view-form-dropdown.tsx 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/embedded-chatbot/theme/theme-context.ts 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/embedded-chatbot/theme/utils.ts 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/embedded-chatbot/utils.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/types.ts 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chat/utils.ts 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/checkbox/assets/indeterminate-icon.tsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/checkbox/index.spec.tsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/checkbox/index.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/chip/index.tsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/confirm/index.tsx 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/content-dialog/index.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/copy-btn/index.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/copy-btn/style.module.css 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/copy-feedback/index.tsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/copy-feedback/style.module.css 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/copy-icon/index.tsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/corner-label/index.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/custom-icon/index.tsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/calendar/days-of-week.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/calendar/index.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/calendar/item.tsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/common/option-list-item.tsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/date-picker/footer.tsx 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/date-picker/header.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/date-picker/index.tsx 309 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/hooks.ts 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/time-picker/footer.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/time-picker/header.tsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/time-picker/index.tsx 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/time-picker/options.tsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/types.ts 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/utils/dayjs.ts 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/year-and-month-picker/footer.tsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/year-and-month-picker/header.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/date-and-time-picker/year-and-month-picker/options.tsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/dialog/index.tsx 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/divider/index.spec.tsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/divider/index.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/divider/with-label.tsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/drawer-plus/index.tsx 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/drawer/index.tsx 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/dropdown/index.tsx 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/emoji-picker/Inner.tsx 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/emoji-picker/index.tsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/context.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/hooks.ts 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/index.tsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/annotation-reply/annotation-ctrl-button.tsx 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.tsx 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/annotation-reply/config-param.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/annotation-reply/index.tsx 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/index.tsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/style.module.css 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/annotation-reply/score-slider/index.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/annotation-reply/type.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/annotation-reply/use-annotation-config.ts 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/citation.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/conversation-opener/index.tsx 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/conversation-opener/modal.tsx 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/dialog-wrapper.tsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/feature-bar.tsx 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/feature-card.tsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/file-upload/index.tsx 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/file-upload/setting-content.tsx 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/file-upload/setting-modal.tsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/follow-up.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/image-upload/index.tsx 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/index.tsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/moderation/form-generation.tsx 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/moderation/index.tsx 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/moderation/moderation-content.tsx 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/moderation/moderation-setting-modal.tsx 380 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/more-like-this.tsx 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/speech-to-text.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/text-to-speech/index.tsx 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/text-to-speech/param-config-content.tsx 240 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/text-to-speech/voice-settings.tsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/store.ts 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/types.ts 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-icon/index.tsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/audio-preview.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/constants.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/dynamic-pdf-preview.tsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/file-from-link-or-local/index.tsx 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/file-image-render.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/file-input.tsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/file-list-in-log.tsx 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/file-type-icon.tsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/file-uploader-in-attachment/file-item.tsx 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/file-uploader-in-attachment/index.tsx 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/file-uploader-in-chat-input/file-image-item.tsx 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/file-uploader-in-chat-input/file-item.tsx 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/file-uploader-in-chat-input/file-list.tsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/file-uploader-in-chat-input/index.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/hooks.ts 367 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/index.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/pdf-preview.tsx 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/store.tsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/types.ts 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/utils.spec.ts 614 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/utils.ts 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/file-uploader/video-preview.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/float-popover-container/index.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/float-right-container/index.tsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/components/field/checkbox.tsx 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/components/field/number-input.tsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/components/field/options.tsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/components/field/select.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/components/field/text.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/components/form/submit-button.tsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/components/label.spec.tsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/components/label.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/form-scenarios/demo/contact-fields.tsx 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/form-scenarios/demo/index.tsx 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/form-scenarios/demo/shared-options.tsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/form-scenarios/demo/types.ts 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/form/index.tsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/fullscreen-modal/index.tsx 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/ga/index.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/grid-mask/Grid.svg 2146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/grid-mask/index.tsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/grid-mask/style.module.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/IconBase.spec.tsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/IconBase.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/image/llm/baichuan-text-cn.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/image/llm/minimax-text.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/image/llm/minimax.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/image/llm/tongyi-text-cn.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/image/llm/tongyi-text.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/image/llm/tongyi.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/image/llm/wxyy-text-cn.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/image/llm/wxyy-text.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/image/llm/wxyy.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/avatar/robot.svg 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/avatar/user.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/billing/ar-cube-1.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/billing/asterisk.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/billing/aws-marketplace.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/billing/azure.svg 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/billing/buildings.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/billing/diamond.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/billing/google-cloud.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/billing/group-2.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/billing/keyframe.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/billing/sparkles-soft.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/billing/sparkles.svg 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/d.svg 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/diagonal-dividing-line.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/dify.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/gdpr.svg 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/github.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/highlight.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/iso.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/line-3.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/lock.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/message-chat-square.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/multi-path-retrieval.svg 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/n-to-1-retrieval.svg 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/notion.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/soc2.svg 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/common/sparkles-soft.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/education/triangle.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/files/csv.svg 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/files/doc.svg 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/files/docx.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/files/html.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/files/json.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/files/md.svg 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/files/pdf.svg 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/files/txt.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/files/unknown.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/files/xlsx.svg 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/files/yaml.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/knowledge/chunk.svg 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/knowledge/collapse.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/knowledge/general-type.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/knowledge/layout-right-2-line-mod.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/knowledge/parent-child-type.svg 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/knowledge/selection-mod.svg 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/Anthropic-dark.svg 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/Anthropic-light.svg 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/anthropic-text.svg 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/anthropic.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/azure-openai-service-text.svg 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/azure-openai-service.svg 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/azureai-text.svg 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/azureai.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/baichuan-text.svg 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/baichuan.svg 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/chatglm-text.svg 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/chatglm.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/cohere-text.svg 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/cohere.svg 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/gpt-3.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/gpt-4.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/huggingface-text-hub.svg 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/huggingface-text.svg 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/huggingface.svg 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/iflytek-spark-text-cn.svg 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/iflytek-spark-text.svg 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/iflytek-spark.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/jina-text.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/jina.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/localai-text.svg 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/localai.svg 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/microsoft.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/openai-black.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/openai-blue.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/openai-green.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/openai-text.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/openai-transparent.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/openai-violet.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/openllm-text.svg 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/openllm.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/replicate-text.svg 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/replicate.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/xorbits-inference-text.svg 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/xorbits-inference.svg 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/zhipuai-text-cn.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/zhipuai-text.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/llm/zhipuai.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/model/checked.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/other/Icon-3-dots.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/other/default-tool-icon.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/other/message-3-fill.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/other/row-struct.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/plugins/google.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/plugins/partner-dark.svg 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/plugins/partner-light.svg 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/plugins/verified-dark.svg 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/plugins/verified-light.svg 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/plugins/web-reader.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/plugins/wikipedia.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/thought/data-set.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/thought/loading.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/thought/search.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/thought/thought-list.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/thought/web-reader.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/tracing/langfuse-icon-big.svg 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/tracing/langfuse-icon.svg 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/tracing/langsmith-icon-big.svg 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/tracing/langsmith-icon.svg 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/tracing/opik-icon-big.svg 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/tracing/opik-icon.svg 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/tracing/tracing-icon.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/tracing/weave-icon-big.svg 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/public/tracing/weave-icon.svg 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/features/citations.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/features/content-moderation.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/features/document.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/features/folder-upload.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/features/love-message.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/features/message-fast.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/features/microphone-01.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/features/text-to-audio.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/features/virtual-assistant.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/features/vision.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/alertsAndFeedback/alert-triangle.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/alertsAndFeedback/thumbs-down.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/alertsAndFeedback/thumbs-up.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/arrows/arrow-narrow-left.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/arrows/arrow-up-right.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/arrows/chevron-down-double.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/arrows/chevron-right.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/arrows/chevron-selector-vertical.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/arrows/refresh-ccw-01.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/arrows/refresh-cw-05.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/arrows/reverse-left.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/communication/ai-text.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/communication/chat-bot-slim.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/communication/chat-bot.svg 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/communication/cute-robot.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/communication/message-check-remove.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/communication/message-fast-plus.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/artificial-brain.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/bar-chart-square-02.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/brackets-x.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/code-browser.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/container.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/database-01.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/database-03.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/file-heart-02.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/git-branch-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/prompt-engineering.svg 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/puzzle-piece-01.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/terminal-square.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/variable.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/development/webhooks.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/editor/align-left.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/editor/bezier-curve-03.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/editor/collapse.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/editor/colors.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/editor/image-indent-left.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/editor/left-indent-02.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/editor/letter-spacing-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/editor/type-square.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/education/book-open-01.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/files/clipboard-check.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/files/clipboard.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/files/file-02.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/files/file-arrow-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/files/file-check-02.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/files/file-download-02.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/files/file-plus-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/files/file-plus-02.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/files/file-text.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/files/file-upload.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/files/folder.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/financeAndECommerce/balance.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/financeAndECommerce/coins-stacked-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/financeAndECommerce/gold-coin.svg 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/financeAndECommerce/receipt-list.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/financeAndECommerce/tag-01.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/financeAndECommerce/tag-03.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/at-sign.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/bookmark.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/check-done-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/check.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/checklist-square.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/dots-grid.svg 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/edit-02.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/edit-04.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/edit-05.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/hash-02.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/info-circle.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/link-03.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/link-external-02.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/log-in-04.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/log-out-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/log-out-04.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/menu-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/pin-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/pin-02.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/plus-02.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/refresh.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/settings-01.svg 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/settings-04.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/target-04.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/upload-03.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/upload-cloud-01.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/general/x.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/images/image-plus.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/layout/align-left-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/layout/align-right-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/layout/grid-01.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/layout/layout-grid-02.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/mapsAndTravel/globe-01.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/mapsAndTravel/route.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/mediaAndDevices/microphone-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/mediaAndDevices/play-circle.svg 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/mediaAndDevices/sliders-h.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/mediaAndDevices/speaker.svg 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/mediaAndDevices/stop-circle.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/mediaAndDevices/stop.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/others/apps-02.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/others/bubble-x.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/others/colors.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/others/drag-handle.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/others/env.svg 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/others/exchange-02.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/others/file-code.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/others/global-variable.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/others/icon-3-dots.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/others/long-arrow-left.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/others/long-arrow-right.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/others/tools.svg 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/shapes/cube-outline.svg 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/time/clock-fast-forward.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/time/clock-play-slim.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/time/clock-play.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/time/clock-refresh.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/users/user-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/users/users-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/line/weather/stars-02.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/other/anthropic-text.svg 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/other/generator.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/other/group.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/other/openai.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/other/replay-line.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/plugin/box-sparkle-fill.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/plugin/left-corner.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/FinanceAndECommerce/gold-coin.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/FinanceAndECommerce/scales-02.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/alertsAndFeedback/alert-triangle.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/arrows/chevron-down.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/arrows/high-priority.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/communication/ai-text.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/communication/bubble-text-mod.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/communication/chat-bot.svg 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/communication/cute-robot.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/communication/edit-list.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/communication/list-sparkle.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/communication/logic.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/communication/message-dots-circle.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/communication/message-fast.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/communication/message-heart-circle.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/communication/message-smile-square.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/communication/send-03.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/api-connection-mod.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/api-connection.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/bar-chart-square-02.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/container.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/database-02.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/database-03.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/file-heart-02.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/pattern-recognition.svg 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/prompt-engineering.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/puzzle-piece-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/semantic.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/terminal-square.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/development/variable-02.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/editor/brush-01.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/editor/citations.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/editor/colors.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/editor/paragraph.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/editor/type-square.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/education/beaker-02.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/education/bubble-text.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/education/heart-02.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/education/unblur.svg 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/files/file-05.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/files/file-search-02.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/files/file-zip.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/files/folder.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/answer-triangle.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/arrow-down-round-fill.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/check-circle.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/check-done-01.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/download-02.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/edit-03.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/edit-04.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/eye.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/github.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/message-clock-circle.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/plus-circle.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/question-triangle.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/search-md.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/target-04.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/tool-03.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/x-circle.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/zap-fast.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/general/zap-narrow.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/layout/grid-01.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mapsAndTravel/globe-06.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mapsAndTravel/route.svg 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mediaAndDevices/audio-support-icon.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mediaAndDevices/document-support-icon.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mediaAndDevices/magic-box.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mediaAndDevices/magic-eyes.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mediaAndDevices/magic-wand.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mediaAndDevices/microphone-01.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mediaAndDevices/play.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mediaAndDevices/robot.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mediaAndDevices/sliders-02.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mediaAndDevices/speaker.svg 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mediaAndDevices/stop-circle.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/mediaAndDevices/video-support-icon.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/security/lock-01.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/shapes/corner.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/shapes/star-04.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/shapes/star-06.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/users/user-01.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/users/user-edit-02.svg 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/users/users-01.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/solid/users/users-plus.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/agent.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/answer.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/assigner.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/code.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/docs-extractor.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/end.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/home.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/http.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/if-else.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/iteration-start.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/iteration.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/jinja.svg 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/knowledge-retrieval.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/list-filter.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/llm.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/loop-end.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/loop.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/parameter-extractor.svg 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/question-classifier.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/templating-transform.svg 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/assets/vender/workflow/variable-x.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/script.mjs 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/BaichuanTextCn.module.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/BaichuanTextCn.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/Minimax.module.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/Minimax.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/MinimaxText.module.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/MinimaxText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/Tongyi.module.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/Tongyi.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/TongyiText.module.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/TongyiText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/TongyiTextCn.module.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/TongyiTextCn.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/Wxyy.module.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/Wxyy.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/WxyyText.module.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/WxyyText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/WxyyTextCn.module.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/WxyyTextCn.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/image/llm/index.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/avatar/Robot.json 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/avatar/Robot.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/avatar/User.json 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/avatar/User.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/avatar/index.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/ArCube1.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/ArCube1.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Asterisk.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Asterisk.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/AwsMarketplace.json 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/AwsMarketplace.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Azure.json 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Azure.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Buildings.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Buildings.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Diamond.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Diamond.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/GoogleCloud.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/GoogleCloud.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Group2.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Group2.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Keyframe.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Keyframe.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Sparkles.json 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/Sparkles.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/SparklesSoft.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/SparklesSoft.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/billing/index.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/D.json 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/D.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/DiagonalDividingLine.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/DiagonalDividingLine.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Dify.json 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Dify.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Gdpr.json 340 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Gdpr.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Github.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Github.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Highlight.json 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Highlight.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Iso.json 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Iso.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Line3.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Line3.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Lock.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Lock.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/MessageChatSquare.json 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/MessageChatSquare.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/MultiPathRetrieval.json 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/MultiPathRetrieval.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/NTo1Retrieval.json 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/NTo1Retrieval.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Notion.json 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Notion.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Soc2.json 938 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/Soc2.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/SparklesSoft.json 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/SparklesSoft.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/common/index.ts 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/education/Triangle.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/education/Triangle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/education/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Csv.json 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Csv.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Doc.json 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Doc.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Docx.json 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Docx.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Html.json 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Html.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Json.json 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Json.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Md.json 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Md.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Pdf.json 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Pdf.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Txt.json 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Txt.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Unknown.json 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Unknown.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Xlsx.json 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Xlsx.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Yaml.json 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/Yaml.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/files/index.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/Chunk.json 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/Chunk.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/Collapse.json 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/Collapse.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/GeneralType.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/GeneralType.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/LayoutRight2LineMod.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/LayoutRight2LineMod.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/ParentChildType.json 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/ParentChildType.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/SelectionMod.json 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/SelectionMod.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/knowledge/index.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Anthropic.json 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Anthropic.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/AnthropicDark.json 1046 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/AnthropicDark.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/AnthropicLight.json 1046 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/AnthropicLight.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/AnthropicText.json 539 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/AnthropicText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/AzureOpenaiService.json 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/AzureOpenaiService.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/AzureOpenaiServiceText.json 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/AzureOpenaiServiceText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Azureai.json 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Azureai.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/AzureaiText.json 243 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/AzureaiText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Baichuan.json 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Baichuan.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/BaichuanText.json 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/BaichuanText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Chatglm.json 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Chatglm.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/ChatglmText.json 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/ChatglmText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Cohere.json 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Cohere.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/CohereText.json 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/CohereText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Gpt3.json 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Gpt3.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Gpt4.json 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Gpt4.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Huggingface.json 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Huggingface.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/HuggingfaceText.json 322 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/HuggingfaceText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/HuggingfaceTextHub.json 350 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/HuggingfaceTextHub.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/IflytekSpark.json 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/IflytekSpark.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/IflytekSparkText.json 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/IflytekSparkText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/IflytekSparkTextCn.json 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/IflytekSparkTextCn.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Jina.json 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Jina.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/JinaText.json 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/JinaText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Localai.json 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Localai.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/LocalaiText.json 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/LocalaiText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Microsoft.json 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Microsoft.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenaiBlack.json 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenaiBlack.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenaiBlue.json 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenaiBlue.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenaiGreen.json 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenaiGreen.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenaiText.json 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenaiText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenaiTransparent.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenaiTransparent.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenaiViolet.json 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenaiViolet.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Openllm.json 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Openllm.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenllmText.json 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/OpenllmText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Replicate.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Replicate.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/ReplicateText.json 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/ReplicateText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/XorbitsInference.json 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/XorbitsInference.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/XorbitsInferenceText.json 329 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/XorbitsInferenceText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Zhipuai.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/Zhipuai.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/ZhipuaiText.json 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/ZhipuaiText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/ZhipuaiTextCn.json 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/ZhipuaiTextCn.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/llm/index.ts 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/model/Checked.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/model/Checked.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/model/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/other/DefaultToolIcon.json 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/other/DefaultToolIcon.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/other/Icon3Dots.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/other/Icon3Dots.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/other/Message3Fill.json 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/other/Message3Fill.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/other/RowStruct.json 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/other/RowStruct.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/other/index.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/Google.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/Google.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/PartnerDark.json 447 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/PartnerDark.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/PartnerLight.json 446 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/PartnerLight.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/VerifiedDark.json 457 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/VerifiedDark.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/VerifiedLight.json 456 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/VerifiedLight.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/WebReader.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/WebReader.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/Wikipedia.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/Wikipedia.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/plugins/index.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/thought/DataSet.json 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/thought/DataSet.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/thought/Loading.json 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/thought/Loading.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/thought/Search.json 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/thought/Search.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/thought/ThoughtList.json 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/thought/ThoughtList.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/thought/WebReader.json 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/thought/WebReader.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/thought/index.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/LangfuseIcon.json 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/LangfuseIcon.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/LangfuseIconBig.json 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/LangfuseIconBig.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/LangsmithIcon.json 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/LangsmithIcon.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/LangsmithIconBig.json 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/LangsmithIconBig.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/OpikIcon.json 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/OpikIcon.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/OpikIconBig.json 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/OpikIconBig.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/TracingIcon.json 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/TracingIcon.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/WeaveIcon.json 279 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/WeaveIcon.tsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/WeaveIconBig.json 279 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/WeaveIconBig.tsx 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/public/tracing/index.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/Citations.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/Citations.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/ContentModeration.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/ContentModeration.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/Document.json 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/Document.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/FolderUpload.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/FolderUpload.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/LoveMessage.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/LoveMessage.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/MessageFast.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/MessageFast.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/Microphone01.json 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/Microphone01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/TextToAudio.json 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/TextToAudio.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/VirtualAssistant.json 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/VirtualAssistant.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/Vision.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/Vision.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/features/index.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/alertsAndFeedback/AlertTriangle.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/alertsAndFeedback/AlertTriangle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsDown.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsDown.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsUp.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsUp.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/alertsAndFeedback/index.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/ArrowNarrowLeft.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/ArrowNarrowLeft.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/ArrowUpRight.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/ArrowUpRight.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/ChevronDownDouble.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/ChevronDownDouble.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/ChevronRight.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/ChevronRight.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/ChevronSelectorVertical.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/ChevronSelectorVertical.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/RefreshCcw01.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/RefreshCcw01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/RefreshCw05.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/RefreshCw05.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/ReverseLeft.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/ReverseLeft.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/arrows/index.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/AiText.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/AiText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/ChatBot.json 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/ChatBot.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/ChatBotSlim.json 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/ChatBotSlim.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/CuteRobot.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/CuteRobot.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/MessageCheckRemove.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/MessageCheckRemove.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/MessageFastPlus.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/MessageFastPlus.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/communication/index.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/ArtificialBrain.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/ArtificialBrain.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/BarChartSquare02.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/BarChartSquare02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/BracketsX.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/BracketsX.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/CodeBrowser.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/CodeBrowser.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/Container.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/Container.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/Database01.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/Database01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/Database03.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/Database03.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/FileHeart02.json 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/FileHeart02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/GitBranch01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/GitBranch01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/PromptEngineering.json 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/PromptEngineering.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/PuzzlePiece01.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/PuzzlePiece01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/TerminalSquare.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/TerminalSquare.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/Variable.json 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/Variable.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/Webhooks.json 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/Webhooks.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/development/index.ts 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/AlignLeft.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/AlignLeft.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/BezierCurve03.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/BezierCurve03.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/Collapse.json 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/Collapse.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/Colors.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/Colors.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/ImageIndentLeft.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/ImageIndentLeft.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/LeftIndent02.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/LeftIndent02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/LetterSpacing01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/LetterSpacing01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/TypeSquare.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/TypeSquare.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/editor/index.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/education/BookOpen01.json 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/education/BookOpen01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/education/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/Clipboard.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/Clipboard.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/ClipboardCheck.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/ClipboardCheck.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/File02.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/File02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FileArrow01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FileArrow01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FileCheck02.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FileCheck02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FileDownload02.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FileDownload02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FilePlus01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FilePlus01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FilePlus02.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FilePlus02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FileText.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FileText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FileUpload.json 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/FileUpload.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/Folder.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/Folder.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/files/index.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/Balance.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/Balance.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/CoinsStacked01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/CoinsStacked01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/GoldCoin.json 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/GoldCoin.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/ReceiptList.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/ReceiptList.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/Tag01.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/Tag01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/Tag03.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/Tag03.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/financeAndECommerce/index.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/AtSign.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/AtSign.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Bookmark.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Bookmark.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Check.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Check.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/CheckDone01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/CheckDone01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/ChecklistSquare.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/ChecklistSquare.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/DotsGrid.json 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/DotsGrid.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Edit02.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Edit02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Edit04.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Edit04.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Edit05.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Edit05.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Hash02.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Hash02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/InfoCircle.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/InfoCircle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Link03.json 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Link03.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/LinkExternal02.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/LinkExternal02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/LogIn04.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/LogIn04.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/LogOut01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/LogOut01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/LogOut04.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/LogOut04.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Menu01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Menu01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Pin01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Pin01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Pin02.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Pin02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Plus02.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Plus02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Refresh.json 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Refresh.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Settings01.json 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Settings01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Settings04.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Settings04.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Target04.json 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Target04.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Upload03.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/Upload03.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/UploadCloud01.json 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/UploadCloud01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/X.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/X.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/general/index.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/images/ImagePlus.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/images/ImagePlus.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/images/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/layout/AlignLeft01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/layout/AlignLeft01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/layout/AlignRight01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/layout/AlignRight01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/layout/Grid01.json 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/layout/Grid01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/layout/LayoutGrid02.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/layout/LayoutGrid02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/layout/index.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mapsAndTravel/Globe01.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mapsAndTravel/Globe01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mapsAndTravel/Route.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mapsAndTravel/Route.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mapsAndTravel/index.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/Microphone01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/Microphone01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/PlayCircle.json 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/PlayCircle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/SlidersH.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/SlidersH.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/Speaker.json 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/Speaker.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/Stop.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/Stop.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/StopCircle.json 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/StopCircle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/mediaAndDevices/index.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/Apps02.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/Apps02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/BubbleX.json 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/BubbleX.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/Colors.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/Colors.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/DragHandle.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/DragHandle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/Env.json 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/Env.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/Exchange02.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/Exchange02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/FileCode.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/FileCode.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/GlobalVariable.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/GlobalVariable.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/Icon3Dots.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/Icon3Dots.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/LongArrowLeft.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/LongArrowLeft.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/LongArrowRight.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/LongArrowRight.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/Tools.json 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/Tools.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/others/index.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/shapes/CubeOutline.json 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/shapes/CubeOutline.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/shapes/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/time/ClockFastForward.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/time/ClockFastForward.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/time/ClockPlay.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/time/ClockPlay.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/time/ClockPlaySlim.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/time/ClockPlaySlim.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/time/ClockRefresh.json 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/time/ClockRefresh.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/time/index.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/users/User01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/users/User01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/users/Users01.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/users/Users01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/users/index.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/weather/Stars02.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/weather/Stars02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/line/weather/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/other/AnthropicText.json 539 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/other/AnthropicText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/other/Generator.json 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/other/Generator.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/other/Group.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/other/Group.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/other/Openai.json 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/other/Openai.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/other/ReplayLine.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/other/ReplayLine.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/other/index.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/plugin/BoxSparkleFill.json 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/plugin/BoxSparkleFill.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/plugin/LeftCorner.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/plugin/LeftCorner.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/plugin/index.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/FinanceAndECommerce/GoldCoin.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/FinanceAndECommerce/GoldCoin.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/FinanceAndECommerce/Scales02.json 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/FinanceAndECommerce/Scales02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/FinanceAndECommerce/index.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/alertsAndFeedback/AlertTriangle.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/alertsAndFeedback/AlertTriangle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/alertsAndFeedback/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/arrows/ChevronDown.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/arrows/ChevronDown.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/arrows/HighPriority.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/arrows/HighPriority.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/arrows/index.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/AiText.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/AiText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/BubbleTextMod.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/BubbleTextMod.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/ChatBot.json 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/ChatBot.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/CuteRobot.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/CuteRobot.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/EditList.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/EditList.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/ListSparkle.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/ListSparkle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/Logic.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/Logic.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/MessageDotsCircle.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/MessageDotsCircle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/MessageFast.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/MessageFast.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/MessageHeartCircle.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/MessageHeartCircle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/MessageSmileSquare.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/MessageSmileSquare.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/Send03.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/Send03.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/communication/index.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/ApiConnection.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/ApiConnection.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/ApiConnectionMod.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/ApiConnectionMod.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/BarChartSquare02.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/BarChartSquare02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/Container.json 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/Container.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/Database02.json 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/Database02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/Database03.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/Database03.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/FileHeart02.json 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/FileHeart02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/PatternRecognition.json 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/PatternRecognition.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/PromptEngineering.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/PromptEngineering.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/PuzzlePiece01.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/PuzzlePiece01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/Semantic.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/Semantic.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/TerminalSquare.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/TerminalSquare.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/Variable02.json 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/Variable02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/development/index.ts 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/editor/Brush01.json 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/editor/Brush01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/editor/Citations.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/editor/Citations.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/editor/Colors.json 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/editor/Colors.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/editor/Paragraph.json 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/editor/Paragraph.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/editor/TypeSquare.json 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/editor/TypeSquare.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/editor/index.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/education/Beaker02.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/education/Beaker02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/education/BubbleText.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/education/BubbleText.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/education/Heart02.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/education/Heart02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/education/Unblur.json 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/education/Unblur.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/education/index.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/files/File05.json 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/files/File05.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/files/FileSearch02.json 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/files/FileSearch02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/files/FileZip.json 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/files/FileZip.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/files/Folder.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/files/Folder.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/files/index.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/AnswerTriangle.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/AnswerTriangle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/ArrowDownRoundFill.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/ArrowDownRoundFill.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/CheckCircle.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/CheckCircle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/CheckDone01.json 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/CheckDone01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Download02.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Download02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Edit03.json 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Edit03.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Edit04.json 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Edit04.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Eye.json 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Eye.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Github.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Github.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/MessageClockCircle.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/MessageClockCircle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/PlusCircle.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/PlusCircle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/QuestionTriangle.json 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/QuestionTriangle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/SearchMd.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/SearchMd.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Target04.json 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Target04.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Tool03.json 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/Tool03.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/XCircle.json 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/XCircle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/ZapFast.json 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/ZapFast.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/ZapNarrow.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/ZapNarrow.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/general/index.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/layout/Grid01.json 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/layout/Grid01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/layout/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mapsAndTravel/Globe06.json 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mapsAndTravel/Globe06.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mapsAndTravel/Route.json 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mapsAndTravel/Route.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mapsAndTravel/index.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/AudioSupportIcon.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/AudioSupportIcon.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/DocumentSupportIcon.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/DocumentSupportIcon.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/MagicBox.json 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/MagicBox.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/MagicEyes.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/MagicEyes.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/MagicWand.json 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/MagicWand.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/Microphone01.json 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/Microphone01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/Play.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/Play.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/Robot.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/Robot.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/Sliders02.json 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/Sliders02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/Speaker.json 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/Speaker.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/StopCircle.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/StopCircle.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/VideoSupportIcon.json 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/VideoSupportIcon.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/mediaAndDevices/index.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/security/Lock01.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/security/Lock01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/security/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/shapes/Corner.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/shapes/Corner.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/shapes/Star04.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/shapes/Star04.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/shapes/Star06.json 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/shapes/Star06.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/shapes/index.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/users/User01.json 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/users/User01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/users/UserEdit02.json 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/users/UserEdit02.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/users/Users01.json 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/users/Users01.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/users/UsersPlus.json 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/users/UsersPlus.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/solid/users/index.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Agent.json 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Agent.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Answer.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Answer.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Assigner.json 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Assigner.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Code.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Code.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/DocsExtractor.json 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/DocsExtractor.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/End.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/End.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Home.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Home.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Http.json 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Http.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/IfElse.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/IfElse.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Iteration.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Iteration.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/IterationStart.json 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/IterationStart.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Jinja.json 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Jinja.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/KnowledgeRetrieval.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/KnowledgeRetrieval.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/ListFilter.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/ListFilter.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Llm.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Llm.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Loop.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/Loop.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/LoopEnd.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/LoopEnd.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/ParameterExtractor.json 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/ParameterExtractor.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/QuestionClassifier.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/QuestionClassifier.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/TemplatingTransform.json 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/TemplatingTransform.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/VariableX.json 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/VariableX.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/src/vender/workflow/index.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/utils.spec.ts 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/icons/utils.ts 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/image-gallery/index.tsx 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/image-gallery/style.module.css 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/image-uploader/audio-preview.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/image-uploader/chat-image-uploader.tsx 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/image-uploader/hooks.ts 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/image-uploader/image-link-input.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/image-uploader/image-list.tsx 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/image-uploader/image-preview.tsx 269 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/image-uploader/text-generation-image-uploader.tsx 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/image-uploader/uploader.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/image-uploader/utils.ts 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/image-uploader/video-preview.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/input-number/index.spec.tsx 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/input-number/index.tsx 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/input/index.spec.tsx 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/input/index.tsx 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/install-button/index.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/linked-apps-panel/index.tsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/list-empty/horizontal-line.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/list-empty/index.tsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/list-empty/vertical-line.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/loading/index.spec.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/loading/index.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/loading/style.css 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/logo/dify-logo.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/logo/logo-embedded-chat-avatar.tsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/logo/logo-embedded-chat-header.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/markdown-blocks/button.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/markdown-blocks/form.tsx 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/markdown-blocks/music.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/markdown-blocks/think-block.tsx 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/markdown.tsx 355 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/mermaid/index.tsx 590 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/mermaid/utils.spec.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/mermaid/utils.ts 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/message-log-modal/index.tsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/modal-like-wrap/index.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/modal/index.css 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/modal/index.tsx 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/new-audio-button/index.tsx 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-icon/index.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/assets/clear.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/assets/down-arrow.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/assets/notion-empty-page.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/assets/notion-page.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/assets/search.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/assets/setting.svg 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/base.tsx 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/notion-page-selector-modal/index.module.css 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/notion-page-selector-modal/index.tsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/page-selector/index.tsx 320 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/search-input/index.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/notion-page-selector/workspace-selector/index.tsx 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/pagination/hook.ts 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/pagination/index.tsx 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/pagination/pagination.tsx 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/pagination/type.ts 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/param-item/index.tsx 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/param-item/score-threshold-item.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/param-item/top-k-item.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/popover/index.tsx 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/portal-to-follow-elem/index.spec.tsx 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/portal-to-follow-elem/index.tsx 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/premium-badge/index.css 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/premium-badge/index.tsx 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/progress-bar/index.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/progress-bar/progress-circle.tsx 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/constants.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/hooks.ts 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/index.tsx 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/component-picker-block/hooks.tsx 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/component-picker-block/index.tsx 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/component-picker-block/menu.tsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/component-picker-block/prompt-option.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/component-picker-block/variable-option.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/context-block/component.tsx 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/context-block/context-block-replacement-block.tsx 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/context-block/index.tsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/context-block/node.tsx 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/custom-text/node.tsx 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/history-block/component.tsx 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/history-block/history-block-replacement-block.tsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/history-block/index.tsx 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/history-block/node.tsx 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/on-blur-or-focus-block.tsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/placeholder.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/query-block/component.tsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/query-block/index.tsx 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/query-block/node.tsx 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/query-block/query-block-replacement-block.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/tree-view.tsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/update-block.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/variable-block/index.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/variable-value-block/index.tsx 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/variable-value-block/node.tsx 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/variable-value-block/utils.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/workflow-variable-block/component.tsx 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/workflow-variable-block/index.tsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/workflow-variable-block/node.tsx 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/types.ts 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-editor/utils.ts 328 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-log-modal/card.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/prompt-log-modal/index.tsx 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/qrcode/index.tsx 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/radio-card/index.tsx 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/radio-card/simple/index.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/radio-card/simple/style.module.css 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/radio/component/group/index.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/radio/component/radio/index.tsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/radio/context/index.tsx 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/radio/index.tsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/radio/style.module.css 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/radio/ui.tsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/search-input/index.tsx 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/segmented-control/index.tsx 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/select/index.tsx 382 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/select/locale.tsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/select/pure.tsx 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/simple-pie-chart/index.module.css 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/simple-pie-chart/index.tsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/skeleton/index.tsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/slider/index.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/slider/style.css 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/sort/index.tsx 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/spinner/index.spec.tsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/spinner/index.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/svg-gallery/index.tsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/svg/index.tsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/svg/style.module.css 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/switch/index.tsx 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tab-header/index.tsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tab-slider-new/index.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tab-slider-plain/index.tsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tab-slider/index.tsx 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tag-input/index.tsx 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tag-management/constant.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tag-management/filter.tsx 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tag-management/index.tsx 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tag-management/selector.tsx 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tag-management/store.ts 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tag-management/tag-item-editor.tsx 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tag-management/tag-remove-modal.tsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tag/index.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/text-generation/hooks.ts 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/text-generation/types.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/textarea/index.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/theme-selector.tsx 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/theme-switcher.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/toast/index.spec.tsx 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/toast/index.tsx 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/toast/style.module.css 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tooltip/content.tsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tooltip/index.spec.tsx 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/tooltip/index.tsx 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/video-gallery/VideoPlayer.module.css 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/video-gallery/VideoPlayer.tsx 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/video-gallery/index.tsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/voice-input/index.module.css 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/voice-input/index.tsx 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/voice-input/utils.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/with-input-validation/index.spec.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/with-input-validation/index.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/annotation-full/index.tsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/annotation-full/modal.tsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/annotation-full/style.module.css 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/annotation-full/usage.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/apps-full-in-dialog/index.tsx 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/apps-full-in-dialog/style.module.css 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/billing-page/index.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/config.ts 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/header-billing-btn/index.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/plan/index.tsx 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/pricing/index.tsx 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/pricing/plan-item.tsx 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/pricing/select-plan-range.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/pricing/self-hosted-plan-item.tsx 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/priority-label/index.tsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/progress-bar/index.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/type.ts 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/upgrade-btn/index.tsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/upgrade-btn/style.module.css 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/usage-info/apps-info.tsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/usage-info/index.tsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/usage-info/vector-space-info.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/utils/index.ts 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/vector-space-full/index.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/billing/vector-space-full/style.module.css 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/browser-initor.tsx 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/custom/custom-page/index.tsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/custom/custom-web-app-brand/index.tsx 319 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/custom/custom-web-app-brand/style.module.css 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/custom/style.module.css 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/api/index.tsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/chunk.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/check-rerank-model.ts 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/chunking-mode-label.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/document-file-icon.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/document-picker/document-list.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/document-picker/index.tsx 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/document-picker/preview-document-picker.tsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/document-status-with-action/auto-disabled-document.tsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/document-status-with-action/index-failed.tsx 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/document-status-with-action/status-with-action.tsx 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/economical-retrieval-method-config/index.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/retrieval-method-config/index.tsx 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/retrieval-method-info/index.tsx 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/common/retrieval-param-config/index.tsx 295 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/Icon-3-dots.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/Loading.svg 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/alert-triangle.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/annotation-info.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/arrow-narrow-left.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/book-open-01.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/check.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/close.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/csv.svg 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/doc.svg 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/docx.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/family-mod.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/file-list-3-fill.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/file.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/folder-plus.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/gold.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/html.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/jina.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/json.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/md.svg 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/normal.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/note-mod.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/notion.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/option-card-effect-blue.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/option-card-effect-orange.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/option-card-effect-purple.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/pattern-recognition-mod.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/pdf.svg 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/piggy-bank-01.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/piggy-bank-mod.svg 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/progress-indicator.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/rerank.svg 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/research-mod.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/selection-mod.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/setting-gear-mod.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/sliders-02.svg 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/star-07.svg 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/star.svg 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/trash.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/txt.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/unknown.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/upload-cloud-01.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/watercrawl.svg 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/web.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/xlsx.svg 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/assets/zap-fast.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/embedding-process/index.module.css 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/embedding-process/index.tsx 357 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/empty-dataset-creation-modal/index.module.css 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/empty-dataset-creation-modal/index.tsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/file-preview/index.module.css 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/file-preview/index.tsx 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/file-uploader/index.module.css 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/file-uploader/index.tsx 381 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/icons.ts 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/index.module.css 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/index.tsx 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/notion-page-preview/index.module.css 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/notion-page-preview/index.tsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/step-one/index.module.css 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/step-one/index.tsx 325 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/step-three/index.module.css 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/step-three/index.tsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/step-two/escape.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/step-two/index.module.css 413 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/step-two/index.tsx 1175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/step-two/inputs.tsx 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/step-two/language-select/index.tsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/step-two/option-card.tsx 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/step-two/preview-item/index.tsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/step-two/unescape.ts 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/stepper/index.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/stepper/step.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/stop-embedding-modal/index.module.css 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/stop-embedding-modal/index.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/top-bar/index.tsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/base/checkbox-with-label.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/base/crawled-result-item.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/base/crawled-result.tsx 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/base/crawling.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/base/error-message.tsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/base/field.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/base/input.tsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/base/mock-crawl-result.ts 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/base/options-wrap.tsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/base/url-input.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/firecrawl/header.tsx 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/firecrawl/index.tsx 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/firecrawl/options.tsx 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/index.module.css 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/index.tsx 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/jina-reader/base/checkbox-with-label.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/jina-reader/base/error-message.tsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/jina-reader/base/field.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/jina-reader/base/input.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/jina-reader/base/options-wrap.tsx 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/jina-reader/base/url-input.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/jina-reader/header.tsx 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/jina-reader/index.tsx 230 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/jina-reader/options.tsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/no-data.tsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/preview.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/watercrawl/header.tsx 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/watercrawl/index.tsx 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/create/website/watercrawl/options.tsx 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/atSign.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/bezierCurve.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/bookOpen.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/briefcase.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/cardLoading.svg 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/file.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/globe.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/graduationHat.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/hitLoading.svg 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/layoutRightClose.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/layoutRightShow.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/messageTextCircle.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/normal.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/star.svg 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/target.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/assets/typeSquare.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/batch-modal/csv-downloader.tsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/batch-modal/csv-uploader.tsx 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/batch-modal/index.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/child-segment-detail.tsx 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/child-segment-list.tsx 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/common/action-buttons.tsx 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/common/add-another.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/common/batch-action.tsx 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/common/chunk-content.tsx 203 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/common/dot.tsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/common/empty.tsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/common/full-screen-drawer.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/common/keywords.tsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/common/regeneration-modal.tsx 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/common/segment-index-tag.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/common/tag.tsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/display-toggle.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/index.tsx 735 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/new-child-segment.tsx 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/segment-card/chunk-content.tsx 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/segment-card/index.tsx 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/segment-detail.tsx 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/segment-list.tsx 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/skeleton/full-doc-list-skeleton.tsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/skeleton/general-list-skeleton.tsx 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/skeleton/paragraph-list-skeleton.tsx 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/skeleton/parent-chunk-card-skeleton.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/status-item.tsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/completed/style.module.css 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/embedding/index.tsx 314 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/embedding/skeleton/index.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/embedding/style.module.css 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/index.tsx 300 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/metadata/index.tsx 377 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/metadata/style.module.css 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/new-segment.tsx 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/segment-add/index.tsx 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/settings/index.tsx 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/detail/style.module.css 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/index.tsx 350 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/list.tsx 687 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/rename-modal.tsx 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/documents/style.module.css 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-api/declarations.ts 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-api/external-api-modal/Form.tsx 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-api/external-api-modal/index.tsx 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-api/external-api-panel/index.tsx 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-api/external-knowledge-api-card/index.tsx 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-knowledge-base/connector/index.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-knowledge-base/create/ExternalApiSelect.tsx 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-knowledge-base/create/ExternalApiSelection.tsx 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-knowledge-base/create/InfoPanel.tsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-knowledge-base/create/KnowledgeBaseInfo.tsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-knowledge-base/create/RetrievalSettings.tsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-knowledge-base/create/declarations.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/external-knowledge-base/create/index.tsx 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/formatted-text/flavours/edit-slice.tsx 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/formatted-text/flavours/preview-slice.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/formatted-text/flavours/shared.tsx 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/formatted-text/flavours/type.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/formatted-text/formatted.tsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/assets/clock.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/assets/grid.svg 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/assets/plugin.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/components/child-chunks-item.tsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/components/chunk-detail-modal.tsx 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/components/result-item-external.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/components/result-item-footer.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/components/result-item-meta.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/components/result-item.tsx 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/components/score.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/index.tsx 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/modify-external-retrieval-modal.tsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/modify-retrieval-modal.tsx 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/style.module.css 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/textarea.tsx 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/hit-testing/utils/extension-to-file-type.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/loading.tsx 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/add-metadata-button.tsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/base/date-picker.tsx 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/edit-metadata-batch/add-row.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/edit-metadata-batch/edit-row.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/edit-metadata-batch/edited-beacon.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/edit-metadata-batch/input-combined.tsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/edit-metadata-batch/input-has-set-multiple-value.tsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/edit-metadata-batch/label.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/edit-metadata-batch/modal.tsx 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/hooks/use-batch-edit-document-metadata.ts 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/hooks/use-check-metadata-name.ts 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/hooks/use-edit-dataset-metadata.ts 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/hooks/use-metadata-document.ts 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/metadata-dataset/create-content.tsx 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/metadata-dataset/create-metadata-modal.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/metadata-dataset/dataset-metadata-drawer.tsx 248 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/metadata-dataset/field.tsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/metadata-dataset/select-metadata-modal.tsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/metadata-dataset/select-metadata.tsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/metadata-document/field.tsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/metadata-document/index.tsx 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/metadata-document/info-group.tsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/metadata-document/no-data.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/types.ts 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/metadata/utils/get-icon.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/preview/container.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/preview/header.tsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/preview/index.tsx 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/rename-modal/index.tsx 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/settings/form/index.tsx 354 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/settings/index-method-radio/assets/economy.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/settings/index-method-radio/assets/high-quality.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/settings/index-method-radio/index.tsx 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/datasets/settings/permission-selector/index.tsx 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/ApiServer.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/code.tsx 305 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/doc.tsx 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/index.tsx 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/md.tsx 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/assets/copied.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/assets/copy-hover.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/assets/copy.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/assets/pause.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/assets/play.svg 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/assets/qrcode-hover.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/assets/qrcode.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/assets/svg.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/assets/svged.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/assets/trash-gray.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/assets/trash-red.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/input-copy.tsx 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/secret-key-button.tsx 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/secret-key-generate.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/secret-key-modal.tsx 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/secret-key/style.module.css 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/tag.tsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/template/template.en.mdx 708 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/template/template.ja.mdx 706 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/template/template.zh.mdx 967 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/template/template_advanced_chat.en.mdx 1660 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/template/template_advanced_chat.ja.mdx 1365 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/template/template_advanced_chat.zh.mdx 1684 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/template/template_chat.en.mdx 1700 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/template/template_chat.ja.mdx 1392 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/template/template_chat.zh.mdx 1394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/template/template_workflow.en.mdx 792 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/template/template_workflow.ja.mdx 796 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/develop/template/template_workflow.zh.mdx 783 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/explore/app-card/index.tsx 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/explore/app-list/index.tsx 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/explore/app-list/style.module.css 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/explore/category.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/explore/create-app-modal/index.tsx 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/explore/index.tsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/explore/installed-app/index.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/explore/item-operation/index.tsx 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/explore/item-operation/style.module.css 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/explore/sidebar/app-nav-item/index.tsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/explore/sidebar/index.tsx 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-about/index.tsx 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-dropdown/compliance.tsx 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-dropdown/index.tsx 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-dropdown/support.tsx 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-dropdown/workplace-selector/index.module.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-dropdown/workplace-selector/index.tsx 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/Integrations-page/index.module.css 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/Integrations-page/index.tsx 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/api-based-extension-page/empty.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/api-based-extension-page/index.tsx 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/api-based-extension-page/item.tsx 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/api-based-extension-page/modal.tsx 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/api-based-extension-page/selector.tsx 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/collapse/index.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/data-source-page/data-source-notion/index.tsx 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/data-source-page/data-source-notion/operate/index.tsx 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/data-source-page/data-source-website/config-firecrawl-modal.tsx 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/data-source-page/data-source-website/config-jina-reader-modal.tsx 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/data-source-page/data-source-website/config-watercrawl-modal.tsx 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/data-source-page/data-source-website/index.tsx 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/data-source-page/index.module.css 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/data-source-page/index.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/data-source-page/panel/config-item.tsx 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/data-source-page/panel/index.tsx 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/data-source-page/panel/style.module.css 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/data-source-page/panel/types.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/index.tsx 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/key-validator/KeyInput.tsx 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/key-validator/Operate.tsx 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/key-validator/ValidateStatus.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/key-validator/declarations.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/key-validator/hooks.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/key-validator/index.tsx 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/language-page/index.module.css 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/language-page/index.tsx 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/edit-workspace-modal/index.module.css 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/edit-workspace-modal/index.tsx 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/index.tsx 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/invite-modal/index.module.css 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/invite-modal/index.tsx 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/invite-modal/role-selector.tsx 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/invited-modal/assets/copied.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/invited-modal/assets/copy-hover.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/invited-modal/assets/copy.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/invited-modal/index.module.css 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/invited-modal/index.tsx 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/invited-modal/invitation-link.tsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/members-page/operation/index.tsx 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/menu-dialog.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/declarations.ts 271 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/hooks.spec.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/hooks.ts 353 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/index.tsx 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/install-from-marketplace.tsx 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-badge/index.tsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-icon/index.tsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-modal/Form.tsx 424 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-modal/Input.tsx 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-modal/index.tsx 401 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-modal/model-load-balancing-entry-modal.tsx 348 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-name/index.tsx 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-parameter-modal/agent-model-trigger.tsx 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-parameter-modal/configuration-button.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx 267 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-parameter-modal/model-display.tsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx 295 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-parameter-modal/presets-parameter.tsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-parameter-modal/status-indicators.tsx 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-parameter-modal/trigger.tsx 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-selector/deprecated-model-trigger.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-selector/empty-trigger.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-selector/feature-icon.tsx 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-selector/index.tsx 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-selector/model-trigger.tsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-selector/popup-item.tsx 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/model-selector/popup.tsx 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/provider-added-card/add-model-button.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/provider-added-card/cooldown-timer.tsx 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/provider-added-card/model-list-item.tsx 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-configs.tsx 274 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/provider-added-card/priority-selector.tsx 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/provider-added-card/priority-use-tip.tsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/provider-added-card/quota-panel.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/provider-icon/index.tsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx 265 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/model-provider-page/utils.ts 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/plugin-page/SerpapiPlugin.tsx 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/plugin-page/index.tsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/account-setting/plugin-page/utils.ts 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/app-back/index.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/app-nav/index.tsx 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/app-selector/index.tsx 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/alpha.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/anthropic.svg 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/azure.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/bitbucket.svg 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/file.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/github.svg 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/google.svg 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/gpt.svg 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/hugging-face.svg 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/notion.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/salesforce.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/serpapi.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/sync.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/trash.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/assets/twitter.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/dataset-nav/index.tsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/env-nav/index.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/explore-nav/index.tsx 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/github-star/index.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/header-wrapper.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/index.module.css 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/index.tsx 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/indicator/index.tsx 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/license-env/index.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/maintenance-notice.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/nav/index.module.css 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/nav/index.tsx 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/nav/nav-selector/index.tsx 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/plan-badge/index.tsx 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/plugins-nav/downloading-icon.module.css 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/plugins-nav/downloading-icon.tsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/plugins-nav/index.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/tools-nav/index.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/utils/util.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/i18n-server.tsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/i18n.tsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/base/badges/icon-with-tooltip.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/base/badges/partner.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/base/badges/verified.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/base/key-value-item.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/card/base/card-icon.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/card/base/corner-mark.tsx 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/card/base/description.tsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/card/base/download-count.tsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/card/base/org-info.tsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/card/base/placeholder.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/card/base/title.tsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/card/card-more-info.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/card/index.tsx 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/constants.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/hooks.ts 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/base/check-task-status.ts 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/base/installed.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/base/loading-error.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/base/loading.tsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/base/use-get-icon.ts 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/base/version.tsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/hooks.ts 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/hooks/use-check-installed.tsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/hooks/use-fold-anim-into.ts 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/hooks/use-hide-logic.ts 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/hooks/use-refresh-plugin-list.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-bundle/index.tsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-bundle/item/github-item.tsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-bundle/item/marketplace-item.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-bundle/item/package-item.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-bundle/ready-to-install.tsx 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-bundle/steps/install-multi.tsx 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-bundle/steps/install.tsx 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-bundle/steps/installed.tsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-from-github/index.tsx 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-from-github/steps/selectPackage.tsx 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-from-local-package/index.tsx 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-from-local-package/ready-to-install.tsx 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-from-marketplace/index.tsx 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/install-plugin/utils.ts 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/constants.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/context.tsx 348 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/description/index.tsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/empty/index.tsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/empty/line.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/hooks.ts 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/index.tsx 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/intersection-line/hooks.ts 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/intersection-line/index.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/list/card-wrapper.tsx 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/list/index.tsx 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/list/list-with-collection.tsx 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/list/list-wrapper.tsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/plugin-type-switch.tsx 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/search-box/index.tsx 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/search-box/search-box-wrapper.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/search-box/tags-filter.tsx 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/sort-dropdown/index.tsx 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/types.ts 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/marketplace/utils.ts 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/permission-setting-modal/modal.tsx 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/permission-setting-modal/style.module.css 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/action-list.tsx 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/agent-strategy-list.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/app-selector/app-inputs-form.tsx 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/app-selector/app-inputs-panel.tsx 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/app-selector/app-picker.tsx 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/app-selector/app-trigger.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/app-selector/index.tsx 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/detail-header.tsx 312 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/endpoint-card.tsx 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/endpoint-list.tsx 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/endpoint-modal.tsx 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/index.tsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/model-list.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/model-selector/index.tsx 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/model-selector/llm-params-panel.tsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/model-selector/tts-params-panel.tsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/operation-dropdown.tsx 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/strategy-detail.tsx 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/strategy-item.tsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/tool-selector/hooks.ts 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/tool-selector/index.tsx 458 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/tool-selector/reasoning-config-form.tsx 275 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/tool-selector/tool-credentials-form.tsx 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/tool-selector/tool-item.tsx 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/tool-selector/tool-trigger.tsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-detail-panel/utils.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-item/action.tsx 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-item/index.tsx 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-mutation-model/index.tsx 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/context.tsx 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/debug-info.tsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/empty/index.tsx 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/filter-management/category-filter.tsx 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/filter-management/constant.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/filter-management/index.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/filter-management/search-box.tsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/filter-management/store.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/filter-management/tag-filter.tsx 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/index.tsx 299 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/install-plugin-dropdown.tsx 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/list/index.tsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/plugin-info.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/plugin-tasks/hooks.ts 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/plugin-tasks/index.tsx 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/plugins-panel.tsx 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/use-permission.ts 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/plugin-page/use-uploader.ts 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/provider-card.tsx 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/types.ts 457 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/update-plugin/from-github.tsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/update-plugin/from-market-place.tsx 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/update-plugin/index.tsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/update-plugin/plugin-version-picker.tsx 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/plugins/utils.ts 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/sentry-initor.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/icons/star.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/index.tsx 676 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/info-modal.tsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/menu-dropdown.tsx 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/no-data/index.tsx 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/result/content.tsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/result/header.tsx 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/result/index.tsx 466 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/run-batch/csv-download/index.tsx 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/run-batch/csv-reader/index.tsx 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/run-batch/index.tsx 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/run-batch/res-download/index.tsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/text-generation/run-once/index.tsx 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/share/utils.ts 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/signin/countdown.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/swr-initor.tsx 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/add-tool-modal/D.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/add-tool-modal/category.tsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/add-tool-modal/empty.png 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/add-tool-modal/empty.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/add-tool-modal/index.tsx 257 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/add-tool-modal/tools.tsx 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/add-tool-modal/type.tsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/edit-custom-collection-modal/config-credentials.tsx 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/edit-custom-collection-modal/examples.ts 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/edit-custom-collection-modal/get-schema.tsx 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/edit-custom-collection-modal/index.tsx 366 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/edit-custom-collection-modal/modal.tsx 360 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/edit-custom-collection-modal/test-api.tsx 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/labels/constant.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/labels/filter.tsx 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/labels/selector.tsx 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/marketplace/hooks.ts 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/marketplace/index.tsx 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/provider-list.tsx 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/provider/custom-create-card.tsx 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/provider/detail.tsx 430 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/provider/tool-item.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/setting/build-in/config-credentials.tsx 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/types.ts 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/utils/index.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/utils/to-form-schema.ts 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/workflow-tool/configure-button.tsx 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/workflow-tool/confirm-modal/index.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/workflow-tool/index.tsx 282 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/tools/workflow-tool/method-selector.tsx 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/with-i18n.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/components/workflow-children.tsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/components/workflow-header/chat-variable-trigger.tsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/components/workflow-header/features-trigger.tsx 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/components/workflow-header/index.tsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/components/workflow-main.tsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/components/workflow-panel.tsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/hooks/index.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/hooks/use-is-chat-mode.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/hooks/use-nodes-sync-draft.ts 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/hooks/use-workflow-init.ts 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/hooks/use-workflow-refresh-draft.ts 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/hooks/use-workflow-run.ts 357 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/hooks/use-workflow-start-run.tsx 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/hooks/use-workflow-template.ts 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/index.tsx 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow-app/store/workflow/workflow-slice.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-icon.tsx 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/all-tools.tsx 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/blocks.tsx 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/constants.tsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/hooks.ts 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/index-bar.tsx 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/index.tsx 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/market-place-plugin/action.tsx 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/market-place-plugin/item.tsx 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/market-place-plugin/list.tsx 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/tabs.tsx 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/tool-picker.tsx 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/tool/action-item.tsx 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/tool/tool.tsx 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/tools.tsx 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/types.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/use-sticky-scroll.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/block-selector/view-type-select.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/blocks.tsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/candidate-node.tsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/constants.ts 597 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/context.tsx 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/custom-connection-line.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/custom-edge-linear-gradient-render.tsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/custom-edge.tsx 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/datasets-detail-store/provider.tsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/datasets-detail-store/store.ts 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/dsl-export-confirm-modal.tsx 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/features.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/chat-variable-button.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/checklist.tsx 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/editing-title.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/env-button.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/global-variable-button.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/header-in-normal.tsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/header-in-restoring.tsx 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/header-in-view-history.tsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/index.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/restoring-title.tsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/run-and-history.tsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/running-title.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/undo-redo.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/version-history-button.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/view-history.tsx 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/header/view-workflow-history.tsx 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/help-line/index.tsx 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/help-line/types.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks-store/index.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks-store/provider.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks-store/store.ts 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/index.ts 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-checklist.ts 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-config-vision.ts 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-edges-interactions-without-sync.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-edges-interactions.ts 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-format-time-from-now.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-helpline.ts 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-node-data-update.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-nodes-data.ts 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-nodes-interactions-without-sync.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-nodes-interactions.ts 1552 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-nodes-layout.ts 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-nodes-sync-draft.ts 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-panel-interactions.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-selection-interactions.ts 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-shortcuts.ts 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-history.ts 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-interactions.ts 403 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-mode.ts 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-refresh-draft.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/index.ts 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-agent-log.ts 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-failed.ts 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-finished.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-finished.ts 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-iteration-finished.ts 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-iteration-next.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-iteration-started.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-loop-finished.ts 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-loop-next.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-loop-started.ts 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-retry.ts 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-started.ts 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-run-event.ts 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-started.ts 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-text-chunk.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run-event/use-workflow-text-replace.ts 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-run.ts 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-start-run.tsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow-variables.ts 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/hooks/use-workflow.ts 559 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/index.tsx 379 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/limit-tips.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/node-contextmenu.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/add-button.tsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/add-variable-popup-with-position.tsx 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/add-variable-popup.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/agent-strategy-selector.tsx 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/agent-strategy.tsx 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/before-run-form/form-item.tsx 301 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/before-run-form/form.tsx 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/before-run-form/index.tsx 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/code-generator-button.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/collapse/field-collapse.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/collapse/index.tsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/config-vision.tsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/editor/base.tsx 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/editor/code-editor/editor-support-vars.tsx 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/editor/code-editor/style.css 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/editor/text-editor.tsx 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/editor/wrap.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/error-handle/default-value.tsx 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/error-handle/error-handle-on-node.tsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/error-handle/error-handle-on-panel.tsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/error-handle/error-handle-tip.tsx 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/error-handle/error-handle-type-selector.tsx 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/error-handle/fail-branch-card.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/error-handle/hooks.ts 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/error-handle/types.ts 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/error-handle/utils.ts 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/field.tsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/file-type-item.tsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/file-upload-setting.tsx 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/group.tsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/help-link.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/info-panel.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/input-number-with-slider.tsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/input-support-select-var.tsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/input-var-type-icon.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/install-plugin-button.tsx 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/list-no-data-placeholder.tsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/memory-config.tsx 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/next-step/add.tsx 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/next-step/container.tsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/next-step/index.tsx 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/next-step/item.tsx 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/next-step/line.tsx 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/next-step/operator.tsx 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/node-control.tsx 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/node-handle.tsx 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/node-resizer.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/node-status-icon.tsx 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/option-card.tsx 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/output-vars.tsx 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/panel-operator/change-block.tsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/panel-operator/index.tsx 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/panel-operator/panel-operator-popup.tsx 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/prompt/editor.tsx 306 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/readonly-input-with-select-var.tsx 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/remove-button.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/remove-effect-var-confirm.tsx 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/retry/hooks.ts 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/retry/retry-on-node.tsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/retry/retry-on-panel.tsx 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/retry/style.module.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/retry/types.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/retry/utils.ts 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/selector.tsx 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/setting-item.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/split.tsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/support-var-input/index.tsx 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/switch-plugin-version.tsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/title-description-input.tsx 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/toggle-expand-btn.tsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable-tag.tsx 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/assigned-var-reference-popup.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/constant-field.tsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/picker/field.tsx 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/picker/index.tsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/show/field.tsx 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/show/index.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/tree-indent-line.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/output-var-list.tsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/utils.ts 1496 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/var-full-path-panel.tsx 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/var-list.tsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx 447 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/var-reference-popup.tsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx 367 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/components/variable/var-type-picker.tsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/hooks/use-available-var-list.ts 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/hooks/use-node-crud.ts 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/hooks/use-node-help-link.ts 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/hooks/use-node-info.ts 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/hooks/use-one-step-run.ts 543 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/hooks/use-output-var-list.ts 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/hooks/use-resize-panel.ts 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/hooks/use-toggle-expend.ts 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/hooks/use-var-list.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/node.tsx 323 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/_base/panel.tsx 209 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/agent/components/model-bar.tsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/agent/components/tool-icon.tsx 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/agent/default.ts 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/agent/node.tsx 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/agent/panel.tsx 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/agent/types.ts 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/agent/use-config.ts 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/answer/default.ts 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/answer/node.tsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/answer/panel.tsx 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/answer/types.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/answer/use-config.ts 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/answer/utils.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/assigner/components/operation-selector.tsx 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/assigner/components/var-list/index.tsx 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/assigner/components/var-list/use-var-list.ts 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/assigner/default.ts 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/assigner/hooks.ts 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/assigner/node.tsx 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/assigner/panel.tsx 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/assigner/types.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/assigner/use-config.ts 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/assigner/utils.ts 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/code/code-parser.spec.ts 326 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/code/code-parser.ts 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/code/default.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/code/dependency-picker.tsx 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/code/node.tsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/code/panel.tsx 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/code/types.ts 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/code/use-config.ts 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/code/utils.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/constants.ts 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/document-extractor/default.ts 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/document-extractor/node.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/document-extractor/panel.tsx 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/document-extractor/types.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/document-extractor/use-config.ts 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/end/default.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/end/node.tsx 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/end/panel.tsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/end/types.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/end/use-config.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/end/utils.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/components/api-input.tsx 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/components/authorization/index.tsx 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/components/authorization/radio-group.tsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/components/curl-panel.tsx 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/components/edit-body/index.tsx 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/components/key-value/bulk-edit/index.tsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/components/key-value/index.tsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/components/key-value/key-value-edit/index.tsx 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/components/key-value/key-value-edit/input-item.tsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/components/key-value/key-value-edit/item.tsx 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/components/timeout/index.tsx 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/default.ts 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/hooks/use-key-value-list.ts 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/node.tsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/panel.tsx 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/types.ts 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/use-config.ts 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/http/utils.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/components/condition-add.tsx 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/components/condition-files-list-value.tsx 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/components/condition-list/condition-input.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/components/condition-list/condition-item.tsx 336 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/components/condition-list/condition-operator.tsx 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/components/condition-list/condition-var-selector.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/components/condition-list/index.tsx 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/components/condition-number-input.tsx 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/components/condition-value.tsx 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/components/condition-wrap.tsx 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/default.ts 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/node.tsx 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/panel.tsx 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/types.ts 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/use-config.ts 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/use-is-var-file-attribute.ts 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/if-else/utils.ts 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/index.tsx 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/iteration-start/constants.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/iteration-start/default.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/iteration-start/index.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/iteration-start/types.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/iteration/add-block.tsx 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/iteration/default.ts 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/iteration/node.tsx 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/iteration/panel.tsx 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/iteration/types.ts 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/iteration/use-config.ts 245 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/iteration/use-interactions.ts 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/add-dataset.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/dataset-item.tsx 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/dataset-list.tsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/add-condition.tsx 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-common-variable-selector.tsx.tsx 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-date.tsx 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-item.tsx 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-number.tsx 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-operator.tsx 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-string.tsx 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-value-method.tsx 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-variable-selector.tsx 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/index.tsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/utils.ts 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-filter/index.tsx 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-filter/metadata-filter-selector.tsx 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-icon.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-panel.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-trigger.tsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/components/retrieval-config.tsx 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/default.ts 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/hooks.ts 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/node.tsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/panel.tsx 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/types.ts 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/use-config.ts 452 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/knowledge-retrieval/utils.ts 244 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/list-operator/components/extract-input.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/list-operator/components/filter-condition.tsx 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/list-operator/components/limit-config.tsx 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/list-operator/components/sub-variable-picker.tsx 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/list-operator/default.ts 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/list-operator/node.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/list-operator/panel.tsx 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/list-operator/types.ts 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/list-operator/use-config.ts 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/config-prompt-item.tsx 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/config-prompt.tsx 247 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/code-editor.tsx 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/error-message.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/index.tsx 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/json-importer.tsx 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-config.tsx 301 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/assets/index.tsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/assets/schema-generator-dark.tsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/assets/schema-generator-light.tsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/generated-result.tsx 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/index.tsx 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/prompt-editor.tsx 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/schema-editor.tsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/add-field.tsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/card.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/context.tsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/actions.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/advanced-actions.tsx 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/advanced-options.tsx 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/auto-width-input.tsx 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/index.tsx 277 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/required-switch.tsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/type-selector.tsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/hooks.ts 441 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/index.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/schema-node.tsx 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/store.ts 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/prompt-generator-btn.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/resolution-picker.tsx 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/components/structure-output.tsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/default.ts 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/node.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/panel.tsx 363 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/types.ts 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/use-config.ts 448 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/llm/utils.ts 336 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop-end/default.ts 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop-start/constants.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop-start/default.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop-start/index.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop-start/types.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/add-block.tsx 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/condition-add.tsx 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/condition-files-list-value.tsx 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/condition-list/condition-input.tsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/condition-list/condition-item.tsx 330 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/condition-list/condition-operator.tsx 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/condition-list/condition-var-selector.tsx 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/condition-list/index.tsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/condition-number-input.tsx 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/condition-value.tsx 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/condition-wrap.tsx 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/loop-variables/empty.tsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/loop-variables/form-item.tsx 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/loop-variables/index.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/loop-variables/input-mode-selec.tsx 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/loop-variables/item.tsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/components/loop-variables/variable-type-select.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/default.ts 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/insert-block.tsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/node.tsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/panel.tsx 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/types.ts 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/use-config.ts 379 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/use-interactions.ts 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/use-is-var-file-attribute.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/loop/utils.ts 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/parameter-extractor/components/extract-parameter/import-from-tool.tsx 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/parameter-extractor/components/extract-parameter/item.tsx 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/parameter-extractor/components/extract-parameter/list.tsx 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/parameter-extractor/components/extract-parameter/update.tsx 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/parameter-extractor/components/reasoning-mode-picker.tsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/parameter-extractor/default.ts 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/parameter-extractor/node.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/parameter-extractor/panel.tsx 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/parameter-extractor/types.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/parameter-extractor/use-config.ts 307 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/question-classifier/components/advanced-setting.tsx 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/question-classifier/components/class-item.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/question-classifier/components/class-list.tsx 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/question-classifier/default.ts 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/question-classifier/node.tsx 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/question-classifier/panel.tsx 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/question-classifier/types.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/question-classifier/use-config.ts 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/question-classifier/utils.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/start/components/var-item.tsx 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/start/components/var-list.tsx 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/start/default.ts 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/start/node.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/start/panel.tsx 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/start/types.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/start/use-config.ts 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/start/utils.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/template-transform/default.ts 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/template-transform/node.tsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/template-transform/panel.tsx 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/template-transform/types.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/template-transform/use-config.ts 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/template-transform/utils.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/tool/components/input-var-list.tsx 247 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/tool/default.ts 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/tool/node.tsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/tool/panel.tsx 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/tool/types.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/tool/use-config.ts 325 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/tool/utils.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/utils.ts 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/components/add-variable/index.tsx 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/components/node-group-item.tsx 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/components/node-variable-item.tsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/components/var-group-item.tsx 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/components/var-list/index.tsx 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/components/var-list/use-var-list.ts 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/default.ts 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/hooks.ts 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/node.tsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/panel.tsx 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/types.ts 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/use-config.ts 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/nodes/variable-assigner/utils.ts 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/constants.ts 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/hooks.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/index.tsx 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/context.tsx 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/editor.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/index.tsx 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/plugins/format-detector-plugin/hooks.ts 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/plugins/format-detector-plugin/index.tsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/plugins/link-editor-plugin/component.tsx 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/plugins/link-editor-plugin/hooks.ts 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/plugins/link-editor-plugin/index.tsx 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/store.ts 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/theme/index.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/theme/theme.css 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/toolbar/color-picker.tsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/toolbar/command.tsx 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/toolbar/divider.tsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/toolbar/font-size-selector.tsx 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/toolbar/hooks.ts 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/toolbar/index.tsx 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/toolbar/operator.tsx 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/note-editor/utils.ts 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/note-node/types.ts 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/operator/add-block.tsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/operator/control.tsx 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/operator/export-image.tsx 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/operator/hooks.ts 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/operator/index.tsx 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/operator/tip-popup.tsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/operator/zoom-in-out.tsx 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel-contextmenu.tsx 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/chat-record/index.tsx 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/chat-record/user-input.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/chat-variable-panel/components/array-value-list.tsx 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/chat-variable-panel/components/object-value-item.tsx 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/chat-variable-panel/components/object-value-list.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/chat-variable-panel/components/variable-item.tsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/chat-variable-panel/components/variable-modal-trigger.tsx 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx 398 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/chat-variable-panel/components/variable-type-select.tsx 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/chat-variable-panel/index.tsx 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/chat-variable-panel/type.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/debug-and-preview/conversation-variable-modal.tsx 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/debug-and-preview/empty.tsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/debug-and-preview/hooks.ts 506 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/debug-and-preview/index.tsx 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/debug-and-preview/user-input.tsx 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/env-panel/env-item.tsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/env-panel/index.tsx 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/env-panel/variable-modal.tsx 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/env-panel/variable-trigger.tsx 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/global-variable-panel/index.tsx 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/global-variable-panel/item.tsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/index.tsx 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/inputs-panel.tsx 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/record.tsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/context-menu/index.tsx 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/context-menu/menu-item.tsx 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/context-menu/use-context-menu.ts 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/delete-confirm-modal.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/empty.tsx 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/filter/filter-item.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/filter/filter-switch.tsx 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/filter/index.tsx 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/filter/use-filter.ts 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/index.tsx 279 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/loading/index.tsx 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/loading/item.tsx 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/restore-confirm-modal.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/version-history-panel/version-history-item.tsx 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/panel/workflow-preview.tsx 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/plugin-dependency/hooks.ts 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/plugin-dependency/index.tsx 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/plugin-dependency/store.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/agent-log/agent-log-item.tsx 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/agent-log/agent-log-nav-more.tsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/agent-log/agent-log-nav.tsx 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/agent-log/agent-log-trigger.tsx 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/agent-log/agent-result-panel.tsx 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/agent-log/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/assets/bg-line-error.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/assets/bg-line-running.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/assets/bg-line-success.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/assets/bg-line-warning.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/assets/highlight-dark.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/assets/highlight.svg 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/hooks.ts 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/index.tsx 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/iteration-log/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/iteration-log/iteration-log-trigger.tsx 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/iteration-log/iteration-result-panel.tsx 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/loop-log/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/loop-log/loop-log-trigger.tsx 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/loop-log/loop-result-panel.tsx 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/loop-result-panel.tsx 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/meta.tsx 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/node.tsx 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/output-panel.tsx 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/result-panel.tsx 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/result-text.tsx 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/retry-log/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/retry-log/retry-log-trigger.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/retry-log/retry-result-panel.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/special-result-panel.tsx 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/status-container.tsx 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/status.tsx 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/tracing-panel.tsx 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/agent/data.ts 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/agent/index.spec.ts 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/agent/index.ts 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/graph-to-log-struct.spec.ts 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/graph-to-log-struct.ts 356 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/index.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/iteration/index.spec.ts 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/iteration/index.ts 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/loop/index.spec.ts 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/loop/index.ts 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/parallel/index.ts 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/retry/index.spec.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/run/utils/format-log/retry/index.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/shortcuts-name.tsx 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/simple-node/constants.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/simple-node/index.tsx 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/simple-node/types.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/index.ts 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/workflow/chat-variable-slice.ts 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/workflow/env-variable-slice.ts 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/workflow/form-slice.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/workflow/help-line-slice.ts 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/workflow/history-slice.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/workflow/index.ts 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/workflow/node-slice.ts 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/workflow/panel-slice.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/workflow/tool-slice.ts 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/workflow/version-slice.ts 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/workflow/workflow-draft-slice.ts 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/store/workflow/workflow-slice.ts 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/style.css 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/syncing-data-modal.tsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/types.ts 435 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/update-dsl-modal.tsx 302 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/utils/common.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/utils/edge.ts 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/utils/index.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/utils/layout.ts 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/utils/node.ts 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/utils/tool.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/utils/variable.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/utils/workflow-init.spec.ts 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/utils/workflow-init.ts 338 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/utils/workflow.ts 329 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/workflow/workflow-history-store.tsx 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/dev-only/i18n-checker/page.tsx 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/dev-only/layout.tsx 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/dev-preview/page.tsx 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/education-apply/constants.ts 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/education-apply/education-apply-page.tsx 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/education-apply/hooks.ts 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/education-apply/role-selector.tsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/education-apply/search-input.tsx 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/education-apply/types.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/education-apply/user-info.tsx 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/education-apply/verify-state-modal.tsx 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/forgot-password/ChangePasswordForm.tsx 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/forgot-password/ForgotPasswordForm.tsx 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/forgot-password/page.tsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/init/InitPasswordPopup.tsx 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/init/page.tsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/install/installForm.tsx 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/install/page.tsx 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/layout.tsx 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/page.module.css 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/page.tsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/repos/[owner]/[repo]/releases/route.ts 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/reset-password/check-code/page.tsx 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/reset-password/layout.tsx 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/reset-password/page.tsx 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/reset-password/set-password/page.tsx 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/routePrefixHandle.tsx 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/_header.tsx 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/assets/github.svg 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/assets/google.svg 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/check-code/page.tsx 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/components/mail-and-code-auth.tsx 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/components/mail-and-password-auth.tsx 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/components/social-auth.tsx 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/components/sso-auth.tsx 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/invite-settings/page.tsx 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/layout.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/normalForm.tsx 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/oneMoreStep.tsx 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/page.module.css 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/page.tsx 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/styles/globals.css 700 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/styles/markdown.scss 1044 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/styles/preflight.css 379 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/action.svg 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/csv.svg 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/delete.svg 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/doc.svg 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/docx.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/html.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/json.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/md.svg 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/pdf.svg 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/txt.svg 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/xlsx.svg 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
bin/uglify-embed.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
config/index.ts 332 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/app-context.tsx 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/dataset-detail.ts 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/datasets-context.tsx 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/debug-configuration.ts 263 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/event-emitter.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/explore-context.ts 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/external-api-panel-context.tsx 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/external-knowledge-api-context.tsx 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/i18n.ts 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/modal-context.tsx 380 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/provider-context.tsx 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/query-client.tsx 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
context/workspace-context.tsx 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/entrypoint.sh 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/pm2.json 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eslint.config.mjs 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
global.d.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-app-favicon.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-breakpoints.spec.ts 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-breakpoints.ts 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-i18n.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-import-dsl.ts 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-knowledge.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-metadata.ts 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-mitt.ts 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-moderate.ts 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-pay.tsx 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-tab-searchparams.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-theme.ts 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-timestamp.spec.ts 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hooks/use-timestamp.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/DEV.md 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/README.md 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/auto-gen-i18n.js 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/check-i18n.js 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/app-debug.ts 392 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/app.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/common.ts 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/dataset-documents.ts 396 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/dataset.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/run-log.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/share-app.ts 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/de-DE/workflow.ts 921 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/app-debug.ts 537 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/app.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/billing.ts 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/common.ts 671 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/dataset-creation.ts 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/dataset-documents.ts 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/dataset-hit-testing.ts 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/dataset.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/login.ts 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/share-app.ts 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/en-US/workflow.ts 917 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/app-debug.ts 419 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/app.ts 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/common.ts 671 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/dataset-documents.ts 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/dataset.ts 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/share-app.ts 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/es-ES/workflow.ts 919 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/app-debug.ts 455 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/app.ts 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/common.ts 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/dataset-documents.ts 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/dataset.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/share-app.ts 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fa-IR/workflow.ts 921 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/app-debug.ts 410 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/app.ts 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/common.ts 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/dataset-documents.ts 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/dataset.ts 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/share-app.ts 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/fr-FR/workflow.ts 920 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/app-debug.ts 469 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/app-log.ts 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/app-overview.ts 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/app.ts 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/billing.ts 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/common.ts 694 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/dataset-creation.ts 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/dataset-documents.ts 396 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/dataset-settings.ts 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/dataset.ts 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/explore.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/login.ts 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/register.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/share-app.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/tools.ts 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/hi-IN/workflow.ts 941 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/i18next-config.ts 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/index.ts 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/app-annotation.ts 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/app-api.ts 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/app-debug.ts 471 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/app-log.ts 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/app-overview.ts 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/app.ts 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/billing.ts 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/common.ts 703 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/custom.ts 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/dataset-creation.ts 241 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/dataset-documents.ts 397 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/dataset-hit-testing.ts 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/dataset-settings.ts 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/dataset.ts 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/explore.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/login.ts 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/share-app.ts 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/tools.ts 168 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/it-IT/workflow.ts 946 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/app-annotation.ts 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/app-debug.ts 527 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/app.ts 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/billing.ts 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/common.ts 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/dataset-creation.ts 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/dataset-documents.ts 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/dataset-hit-testing.ts 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/dataset.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/share-app.ts 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ja-JP/workflow.ts 920 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/app-api.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/app-debug.ts 418 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/app-log.ts 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/app.ts 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/common.ts 668 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/dataset-creation.ts 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/dataset-documents.ts 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/dataset.ts 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/layout.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/register.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/share-app.ts 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ko-KR/workflow.ts 921 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/language.ts 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/languages.json 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/app-annotation.ts 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/app-api.ts 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/app-debug.ts 466 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/app-log.ts 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/app-overview.ts 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/app.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/billing.ts 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/common.ts 690 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/custom.ts 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/dataset-creation.ts 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/dataset-documents.ts 396 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/dataset-settings.ts 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/dataset.ts 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/explore.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/login.ts 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/share-app.ts 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/tools.ts 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pl-PL/workflow.ts 921 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/app-debug.ts 423 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/app-log.ts 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/app.ts 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/billing.ts 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/common.ts 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/dataset-documents.ts 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/dataset.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/share-app.ts 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/pt-BR/workflow.ts 921 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/app-debug.ts 427 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/app.ts 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/common.ts 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/dataset-documents.ts 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/dataset.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/share-app.ts 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ro-RO/workflow.ts 921 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/app-debug.ts 463 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/app.ts 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/common.ts 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/dataset-documents.ts 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/dataset.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/share-app.ts 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/ru-RU/workflow.ts 921 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/server.ts 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/app-debug.ts 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/app.ts 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/common.ts 871 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/dataset-documents.ts 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/dataset.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/share-app.ts 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/sl-SI/workflow.ts 1354 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/app-debug.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/app.ts 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/common.ts 667 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/dataset-documents.ts 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/dataset.ts 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/layout.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/login.ts 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/register.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/share-app.ts 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/th-TH/workflow.ts 920 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/app-debug.ts 460 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/app.ts 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/common.ts 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/dataset-documents.ts 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/dataset.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/layout.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/register.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/share-app.ts 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/tr-TR/workflow.ts 922 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/app-debug.ts 418 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/app.ts 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/common.ts 673 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/dataset-documents.ts 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/dataset.ts 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/share-app.ts 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/uk-UA/workflow.ts 921 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/app-annotation.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/app-debug.ts 418 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/app-log.ts 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/app.ts 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/common.ts 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/dataset-documents.ts 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/dataset.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/share-app.ts 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/vi-VN/workflow.ts 921 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/app-annotation.ts 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/app-debug.ts 529 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/app.ts 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/billing.ts 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/common.ts 671 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/dataset-creation.ts 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/dataset-documents.ts 393 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/dataset-hit-testing.ts 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/dataset.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/share-app.ts 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/time.ts 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/workflow.ts 918 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/app-annotation.ts 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/app-api.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/app-debug.ts 404 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/app-log.ts 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/app-overview.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/app.ts 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/billing.ts 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/common.ts 672 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/custom.ts 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/dataset-creation.ts 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/dataset-documents.ts 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/dataset-hit-testing.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/dataset-settings.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/dataset.ts 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/education.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/explore.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/layout.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/login.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/plugin-tags.ts 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/plugin.ts 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/register.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/run-log.ts 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/share-app.ts 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/time.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/tools.ts 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/workflow.ts 921 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jest.config.ts 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jest.setup.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
middleware.ts 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/app.ts 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/common.ts 304 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/datasets.ts 694 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/debug.ts 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/explore.ts 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/log.ts 355 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/share.ts 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/user.ts 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
next.config.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pnpm-lock.yaml 18718 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
postcss.config.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/education/bg.png 补丁 | 查看 | 原始文档 | blame | 历史
public/embed.js 441 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/embed.min.js 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
public/logo/logo-embedded-chat-avatar.png 补丁 | 查看 | 原始文档 | blame | 历史
public/logo/logo-embedded-chat-header.png 补丁 | 查看 | 原始文档 | blame | 历史
public/logo/logo-embedded-chat-header@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/logo/logo-embedded-chat-header@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/logo/logo-monochrome-white.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/logo/logo-site-dark.png 补丁 | 查看 | 原始文档 | blame | 历史
public/logo/logo-site.png 补丁 | 查看 | 原始文档 | blame | 历史
public/logo/logo.svg 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/pdf.worker.min.mjs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/Agent.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/Agent@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/Agent@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/Chatbot.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/Chatbot@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/Chatbot@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/Chatflow.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/Chatflow@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/Chatflow@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/TextGenerator.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/TextGenerator@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/TextGenerator@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/Workflow.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/Workflow@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/dark/Workflow@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/Agent.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/Agent@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/Agent@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/Chatbot.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/Chatbot@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/Chatbot@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/Chatflow.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/Chatflow@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/Chatflow@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/TextGenerator.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/TextGenerator@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/TextGenerator@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/Workflow.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/Workflow@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/screenshots/light/Workflow@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/base/browser/ui/codicons/codicon/codicon.ttf 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/base/common/worker/simpleWorker.nls.de.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/base/common/worker/simpleWorker.nls.es.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/base/common/worker/simpleWorker.nls.fr.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/base/common/worker/simpleWorker.nls.it.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/base/common/worker/simpleWorker.nls.ja.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/base/common/worker/simpleWorker.nls.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/base/common/worker/simpleWorker.nls.ko.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/base/common/worker/simpleWorker.nls.ru.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/base/common/worker/simpleWorker.nls.zh-cn.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/base/common/worker/simpleWorker.nls.zh-tw.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/base/worker/workerMain.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/abap/abap.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/apex/apex.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/azcli/azcli.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/bat/bat.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/bicep/bicep.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/cameligo/cameligo.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/clojure/clojure.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/coffee/coffee.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/cpp/cpp.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/csharp/csharp.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/csp/csp.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/css/css.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/cypher/cypher.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/dart/dart.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/dockerfile/dockerfile.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/ecl/ecl.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/elixir/elixir.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/flow9/flow9.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/freemarker2/freemarker2.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/fsharp/fsharp.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/go/go.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/graphql/graphql.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/handlebars/handlebars.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/hcl/hcl.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/html/html.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/ini/ini.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/java/java.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/javascript/javascript.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/julia/julia.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/kotlin/kotlin.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/less/less.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/lexon/lexon.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/liquid/liquid.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/lua/lua.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/m3/m3.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/markdown/markdown.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/mdx/mdx.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/mips/mips.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/msdax/msdax.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/mysql/mysql.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/objective-c/objective-c.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/pascal/pascal.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/pascaligo/pascaligo.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/perl/perl.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/pgsql/pgsql.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/php/php.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/pla/pla.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/postiats/postiats.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/powerquery/powerquery.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/powershell/powershell.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/protobuf/protobuf.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/pug/pug.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/python/python.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/qsharp/qsharp.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/r/r.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/razor/razor.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/redis/redis.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/redshift/redshift.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/restructuredtext/restructuredtext.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/ruby/ruby.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/rust/rust.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/sb/sb.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/scala/scala.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/scheme/scheme.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/scss/scss.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/shell/shell.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/solidity/solidity.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/sophia/sophia.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/sparql/sparql.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/sql/sql.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/st/st.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/swift/swift.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/systemverilog/systemverilog.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/tcl/tcl.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/twig/twig.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/typescript/typescript.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/vb/vb.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/wgsl/wgsl.js 307 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/xml/xml.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/basic-languages/yaml/yaml.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/editor/editor.main.css 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/editor/editor.main.js 762 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/editor/editor.main.nls.de.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/editor/editor.main.nls.es.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/editor/editor.main.nls.fr.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/editor/editor.main.nls.it.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/editor/editor.main.nls.ja.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/editor/editor.main.nls.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/editor/editor.main.nls.ko.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/editor/editor.main.nls.ru.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/editor/editor.main.nls.zh-cn.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/editor/editor.main.nls.zh-tw.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/language/css/cssMode.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/language/css/cssWorker.js 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/language/html/htmlMode.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/language/html/htmlWorker.js 452 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/language/json/jsonMode.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/language/json/jsonWorker.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/language/typescript/tsMode.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/language/typescript/tsWorker.js 37249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vs/loader.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/_tools_util.spec.ts 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/_tools_util.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/annotation.ts 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/apps.ts 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/base.ts 584 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/billing.ts 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/common.ts 353 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/datasets.ts 289 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/debug.ts 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/demo/index.tsx 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/explore.ts 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/fetch.ts 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/knowledge/use-create-dataset.ts 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/knowledge/use-document.ts 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/knowledge/use-hit-testing.ts 补丁 | 查看 | 原始文档 | blame | 历史
service/knowledge/use-import.ts 补丁 | 查看 | 原始文档 | blame | 历史
service/knowledge/use-metadata.ts 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/knowledge/use-segment.ts 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/log.ts 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/plugins.ts 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/refresh-token.ts 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/share.ts 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/sso.ts 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/strategy.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/tag.ts 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/tools.ts 160 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/use-apps.ts 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/use-base.ts 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/use-common.ts 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/use-education.ts 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/use-endpoints.ts 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/use-models.ts 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/use-plugins.ts 529 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/use-strategy.ts 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/use-tools.ts 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/use-workflow.ts 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/workflow.ts 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tailwind-common-config.ts 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tailwind.config.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
themes/dark.css 739 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
themes/light.css 739 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
themes/manual-dark.css 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
themes/manual-light.css 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
themes/markdown-dark.css 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
themes/markdown-light.css 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
themes/tailwind-theme-var-define.ts 740 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
tsconfig.json 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
types/app.ts 450 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
types/feature.ts 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
types/workflow.ts 354 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
typography.js 357 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/app-redirection.ts 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/classnames.spec.ts 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/classnames.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/clipboard.ts 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/context.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/emoji.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/format.spec.ts 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/format.ts 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/get-icon.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/index.spec.ts 295 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/index.ts 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/model-config.ts 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/permission.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/semver.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/time.ts 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/timezone.json 1274 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/timezone.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/tool-call.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/var-basePath.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/var.ts 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/zod.spec.ts 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.dockerignore
New file
@@ -0,0 +1,24 @@
.env
.env.*
# Logs
logs
*.log*
# node
node_modules
.husky
.next
# vscode
.vscode
# webstorm
.idea
*.iml
*.iws
*.ipr
# Jetbrains
.idea
.env.example
New file
@@ -0,0 +1,60 @@
# For production release, change this to PRODUCTION
NEXT_PUBLIC_DEPLOY_ENV=DEVELOPMENT
# The deployment edition, SELF_HOSTED
NEXT_PUBLIC_EDITION=SELF_HOSTED
# The base URL of console application, refers to the Console base URL of WEB service if console domain is
# different from api or web app domain.
# example: http://cloud.dify.ai/console/api
NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api
NEXT_PUBLIC_WEB_PREFIX=http://localhost:3000
# The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from
# console or api domain.
# example: http://udify.app/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api
NEXT_PUBLIC_PUBLIC_WEB_PREFIX=http://localhost:3000
# The API PREFIX for MARKETPLACE
NEXT_PUBLIC_MARKETPLACE_API_PREFIX=https://marketplace.dify.ai/api/v1
# The URL for MARKETPLACE
NEXT_PUBLIC_MARKETPLACE_URL_PREFIX=https://marketplace.dify.ai
# SENTRY
NEXT_PUBLIC_SENTRY_DSN=
# Disable Next.js Telemetry (https://nextjs.org/telemetry)
NEXT_TELEMETRY_DISABLED=1
# Disable Upload Image as WebApp icon default is false
NEXT_PUBLIC_UPLOAD_IMAGE_AS_ICON=false
# The timeout for the text generation in millisecond
NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS=60000
# CSP https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
NEXT_PUBLIC_CSP_WHITELIST=
# Default is not allow to embed into iframe to prevent Clickjacking: https://owasp.org/www-community/attacks/Clickjacking
NEXT_PUBLIC_ALLOW_EMBED=
# Github Access Token, used for invoking Github API
NEXT_PUBLIC_GITHUB_ACCESS_TOKEN=
# The maximum number of top-k value for RAG.
NEXT_PUBLIC_TOP_K_MAX_VALUE=10
# The maximum number of tokens for segmentation
NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH=4000
# Maximum loop count in the workflow
NEXT_PUBLIC_LOOP_NODE_MAX_COUNT=100
# Maximum number of tools in the agent/workflow
NEXT_PUBLIC_MAX_TOOLS_NUM=10
# Maximum number of Parallelism branches in the workflow
NEXT_PUBLIC_MAX_PARALLEL_LIMIT=10
# The maximum number of iterations for agent setting
NEXT_PUBLIC_MAX_ITERATIONS_NUM=5
NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER=true
NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL=true
NEXT_PUBLIC_ENABLE_WEBSITE_WATERCRAWL=true
.gitignore
New file
@@ -0,0 +1,56 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
/.history
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
# npm
package-lock.json
# yarn
.pnp.cjs
.pnp.loader.mjs
.yarn/
.favorites.json
# storybook
/storybook-static
*storybook.log
# mise
mise.toml
.husky/pre-commit
New file
@@ -0,0 +1,78 @@
#!/bin/sh
# get the list of modified files
files=$(git diff --cached --name-only)
# check if api or web directory is modified
api_modified=false
web_modified=false
for file in $files
do
    # Use POSIX compliant pattern matching
    case "$file" in
        api/*.py)
            # set api_modified flag to true
            api_modified=true
            ;;
        web/*)
            # set web_modified flag to true
            web_modified=true
            ;;
    esac
done
# run linters based on the modified modules
if $api_modified; then
    echo "Running Ruff linter on api module"
    # run Ruff linter auto-fixing
    uv run --project api --dev ruff check --fix ./api
    # run Ruff linter checks
    uv run --project api --dev ruff check  ./api || status=$?
    status=${status:-0}
    if [ $status -ne 0 ]; then
      echo "Ruff linter on api module error, exit code: $status"
      echo "Please run 'dev/reformat' to fix the fixable linting errors."
      exit 1
    fi
fi
if $web_modified; then
    echo "Running ESLint on web module"
    cd ./web || exit 1
    lint-staged
    echo "Running unit tests check"
    modified_files=$(git diff --cached --name-only -- utils | grep -v '\.spec\.ts$' || true)
    if [ -n "$modified_files" ]; then
        for file in $modified_files; do
            test_file="${file%.*}.spec.ts"
            echo "Checking for test file: $test_file"
            # check if the test file exists
            if [ -f "../$test_file" ]; then
                echo "Detected changes in $file, running corresponding unit tests..."
                pnpm run test "../$test_file"
                if [ $? -ne 0 ]; then
                    echo "Unit tests failed. Please fix the errors before committing."
                    exit 1
                fi
                echo "Unit tests for $file passed."
            else
                echo "Warning: $file does not have a corresponding test file."
            fi
        done
        echo "All unit tests for modified web/utils files have passed."
    fi
    cd ../
fi
.storybook/main.ts
New file
@@ -0,0 +1,19 @@
import type { StorybookConfig } from '@storybook/nextjs'
const config: StorybookConfig = {
  // stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  stories: ['../app/components/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: [
    '@storybook/addon-onboarding',
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@chromatic-com/storybook',
    '@storybook/addon-interactions',
  ],
  framework: {
    name: '@storybook/nextjs',
    options: {},
  },
  staticDirs: ['../public'],
}
export default config
.storybook/preview.tsx
New file
@@ -0,0 +1,37 @@
import React from 'react'
import type { Preview } from '@storybook/react'
import { withThemeByDataAttribute } from '@storybook/addon-themes'
import I18nServer from '../app/components/i18n-server'
import '../app/styles/globals.css'
import '../app/styles/markdown.scss'
import './storybook.css'
export const decorators = [
  withThemeByDataAttribute({
    themes: {
      light: 'light',
      dark: 'dark',
    },
    defaultTheme: 'light',
    attributeName: 'data-theme',
  }),
  (Story) => {
    return <I18nServer>
      <Story />
    </I18nServer>
  },
]
const preview: Preview = {
  parameters: {
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/i,
      },
    },
  },
}
export default preview
.storybook/storybook.css
New file
@@ -0,0 +1,6 @@
html,
body {
  max-width: unset;
  overflow: auto;
  user-select: text;
}
.vscode/extensions.json
New file
@@ -0,0 +1,7 @@
{
  "recommendations": [
    "bradlc.vscode-tailwindcss",
    "firsttris.vscode-jest-runner",
    "kisstkondoros.vscode-codemetrics"
  ]
}
.vscode/settings.example.json
New file
@@ -0,0 +1,26 @@
{
  "prettier.enable": false,
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "eslint.format.enable": true,
  "[python]": {
    "editor.formatOnType": true
  },
  "[html]": {
    "editor.defaultFormatter": "vscode.html-language-features"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "vscode.typescript-language-features"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "vscode.typescript-language-features"
  },
  "[jsonc]": {
    "editor.defaultFormatter": "vscode.json-language-features"
  },
  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.enablePromptUseWorkspaceTsdk": true,
  "npm.packageManager": "pnpm"
}
Dockerfile
New file
@@ -0,0 +1,76 @@
# base image
FROM node:22-alpine3.21 AS base
LABEL maintainer="takatost@gmail.com"
# if you located in China, you can use aliyun mirror to speed up
# RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache tzdata
RUN npm install -g pnpm@10.8.0
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
# install packages
FROM base AS packages
WORKDIR /app/web
COPY package.json .
COPY pnpm-lock.yaml .
# if you located in China, you can use taobao registry to speed up
# RUN pnpm install --frozen-lockfile --registry https://registry.npmmirror.com/
RUN pnpm install --frozen-lockfile
# build resources
FROM base AS builder
WORKDIR /app/web
COPY --from=packages /app/web/ .
COPY . .
ENV NODE_OPTIONS="--max-old-space-size=4096"
RUN pnpm build
# production stage
FROM base AS production
ENV NODE_ENV=production
ENV EDITION=SELF_HOSTED
ENV DEPLOY_ENV=PRODUCTION
ENV CONSOLE_API_URL=http://127.0.0.1:5001
ENV APP_API_URL=http://127.0.0.1:5001
ENV MARKETPLACE_API_URL=https://marketplace.dify.ai
ENV MARKETPLACE_URL=https://marketplace.dify.ai
ENV PORT=3000
ENV NEXT_TELEMETRY_DISABLED=1
ENV PM2_INSTANCES=2
# set timezone
ENV TZ=UTC
RUN ln -s /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo ${TZ} > /etc/timezone
WORKDIR /app/web
COPY --from=builder /app/web/public ./public
COPY --from=builder /app/web/.next/standalone ./
COPY --from=builder /app/web/.next/static ./.next/static
COPY docker/entrypoint.sh ./entrypoint.sh
# global runtime packages
RUN pnpm add -g pm2 \
    && mkdir /.pm2 \
    && chown -R 1001:0 /.pm2 /app/web \
    && chmod -R g=u /.pm2 /app/web
ARG COMMIT_SHA
ENV COMMIT_SHA=${COMMIT_SHA}
USER 1001
EXPOSE 3000
ENTRYPOINT ["/bin/sh", "./entrypoint.sh"]
README.md
@@ -1,4 +1,120 @@
## app-qxueyou-dify
# Dify Frontend
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
### Run by source code
Before starting the web frontend service, please make sure the following environment is ready.
- [Node.js](https://nodejs.org) >= v22.11.x
- [pnpm](https://pnpm.io) v10.x
First, install the dependencies:
```bash
pnpm install
```
Then, configure the environment variables. Create a file named `.env.local` in the current directory and copy the contents from `.env.example`. Modify the values of these environment variables according to your requirements:
```bash
cp .env.example .env.local
```
```
# For production release, change this to PRODUCTION
NEXT_PUBLIC_DEPLOY_ENV=DEVELOPMENT
# The deployment edition, SELF_HOSTED
NEXT_PUBLIC_EDITION=SELF_HOSTED
# The base URL of console application, refers to the Console base URL of WEB service if console domain is
# different from api or web app domain.
# example: http://cloud.dify.ai/console/api
NEXT_PUBLIC_API_PREFIX=http://localhost:5001/console/api
NEXT_PUBLIC_WEB_PREFIX=http://localhost:3000
# The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from
# console or api domain.
# example: http://udify.app/api
NEXT_PUBLIC_PUBLIC_API_PREFIX=http://localhost:5001/api
NEXT_PUBLIC_PUBLIC_WEB_PREFIX=http://localhost:3000
# SENTRY
NEXT_PUBLIC_SENTRY_DSN=
```
Finally, run the development server:
```bash
pnpm run dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the file under folder `app`. The page auto-updates as you edit the file.
## Deploy
### Deploy on server
First, build the app for production:
```bash
pnpm run build
```
Then, start the server:
```bash
pnpm run start
```
If you want to customize the host and port:
```bash
pnpm run start --port=3001 --host=0.0.0.0
```
If you want to customize the number of instances launched by PM2, you can configure `PM2_INSTANCES` in `docker-compose.yaml` or `Dockerfile`.
## Storybook
This project uses [Storybook](https://storybook.js.org/) for UI component development.
To start the storybook server, run:
```bash
pnpm storybook
```
Open [http://localhost:6006](http://localhost:6006) with your browser to see the result.
## Lint Code
If your IDE is VSCode, rename `web/.vscode/settings.example.json` to `web/.vscode/settings.json` for lint code setting.
## Test
We start to use [Jest](https://jestjs.io/) and [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) for Unit Testing.
You can create a test file with a suffix of `.spec` beside the file that to be tested. For example, if you want to test a file named `util.ts`. The test file name should be `util.spec.ts`.
Run test:
```bash
pnpm run test
```
If you are not familiar with writing tests, here is some code to refer to:
* [classnames.spec.ts](./utils/classnames.spec.ts)
* [index.spec.tsx](./app/components/base/button/index.spec.tsx)
## Documentation
Visit <https://docs.dify.ai/getting-started/readme> to view the full documentation.
## Community
The Dify community can be found on [Discord community](https://discord.gg/5AEfbxcd9k), where you can ask questions, voice ideas, and share your projects.
__mocks__/mime.js
app/(commonLayout)/app/(appDetailLayout)/[appId]/annotations/page.tsx
New file
@@ -0,0 +1,15 @@
import React from 'react'
import Main from '@/app/components/app/log-annotation'
import { PageType } from '@/app/components/base/features/new-feature-panel/annotation-reply/type'
export type IProps = {
  params: Promise<{ appId: string }>
}
const Logs = async () => {
  return (
    <Main pageType={PageType.annotation} />
  )
}
export default Logs
app/(commonLayout)/app/(appDetailLayout)/[appId]/configuration/page.tsx
New file
@@ -0,0 +1,10 @@
import React from 'react'
import Configuration from '@/app/components/app/configuration'
const IConfiguration = async () => {
  return (
    <Configuration />
  )
}
export default IConfiguration
app/(commonLayout)/app/(appDetailLayout)/[appId]/develop/page.tsx
New file
@@ -0,0 +1,19 @@
import React from 'react'
import type { Locale } from '@/i18n'
import DevelopMain from '@/app/components/develop'
export type IDevelopProps = {
  params: Promise<{ locale: Locale; appId: string }>
}
const Develop = async (props: IDevelopProps) => {
  const params = await props.params
  const {
    appId,
  } = params
  return <DevelopMain appId={appId} />
}
export default Develop
app/(commonLayout)/app/(appDetailLayout)/[appId]/layout-main.tsx
New file
@@ -0,0 +1,177 @@
'use client'
import type { FC } from 'react'
import { useUnmount } from 'ahooks'
import React, { useCallback, useEffect, useState } from 'react'
import { usePathname, useRouter } from 'next/navigation'
import {
  RiDashboard2Fill,
  RiDashboard2Line,
  RiFileList3Fill,
  RiFileList3Line,
  RiTerminalBoxFill,
  RiTerminalBoxLine,
  RiTerminalWindowFill,
  RiTerminalWindowLine,
} from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { useShallow } from 'zustand/react/shallow'
import { useContextSelector } from 'use-context-selector'
import s from './style.module.css'
import cn from '@/utils/classnames'
import { useStore } from '@/app/components/app/store'
import AppSideBar from '@/app/components/app-sidebar'
import type { NavIcon } from '@/app/components/app-sidebar/navLink'
import { fetchAppDetail, fetchAppSSO } from '@/service/apps'
import AppContext, { useAppContext } from '@/context/app-context'
import Loading from '@/app/components/base/loading'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import type { App } from '@/types/app'
export type IAppDetailLayoutProps = {
  children: React.ReactNode
  appId: string
}
const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
  const {
    children,
    appId, // get appId in path
  } = props
  const { t } = useTranslation()
  const router = useRouter()
  const pathname = usePathname()
  const media = useBreakpoints()
  const isMobile = media === MediaType.mobile
  const { isCurrentWorkspaceEditor, isLoadingCurrentWorkspace } = useAppContext()
  const { appDetail, setAppDetail, setAppSiderbarExpand } = useStore(useShallow(state => ({
    appDetail: state.appDetail,
    setAppDetail: state.setAppDetail,
    setAppSiderbarExpand: state.setAppSiderbarExpand,
  })))
  const [isLoadingAppDetail, setIsLoadingAppDetail] = useState(false)
  const [appDetailRes, setAppDetailRes] = useState<App | null>(null)
  const [navigation, setNavigation] = useState<Array<{
    name: string
    href: string
    icon: NavIcon
    selectedIcon: NavIcon
  }>>([])
  const systemFeatures = useContextSelector(AppContext, state => state.systemFeatures)
  const getNavigations = useCallback((appId: string, isCurrentWorkspaceEditor: boolean, mode: string) => {
    const navs = [
      ...(isCurrentWorkspaceEditor
        ? [{
          name: t('common.appMenus.promptEng'),
          href: `/app/${appId}/${(mode === 'workflow' || mode === 'advanced-chat') ? 'workflow' : 'configuration'}`,
          icon: RiTerminalWindowLine,
          selectedIcon: RiTerminalWindowFill,
        }]
        : []
      ),
      {
        name: t('common.appMenus.apiAccess'),
        href: `/app/${appId}/develop`,
        icon: RiTerminalBoxLine,
        selectedIcon: RiTerminalBoxFill,
      },
      ...(isCurrentWorkspaceEditor
        ? [{
          name: mode !== 'workflow'
            ? t('common.appMenus.logAndAnn')
            : t('common.appMenus.logs'),
          href: `/app/${appId}/logs`,
          icon: RiFileList3Line,
          selectedIcon: RiFileList3Fill,
        }]
        : []
      ),
      {
        name: t('common.appMenus.overview'),
        href: `/app/${appId}/overview`,
        icon: RiDashboard2Line,
        selectedIcon: RiDashboard2Fill,
      },
    ]
    return navs
  }, [])
  useEffect(() => {
    if (appDetail) {
      document.title = `${(appDetail.name || 'App')} - Dify`
      const localeMode = localStorage.getItem('app-detail-collapse-or-expand') || 'expand'
      const mode = isMobile ? 'collapse' : 'expand'
      setAppSiderbarExpand(isMobile ? mode : localeMode)
      // TODO: consider screen size and mode
      // if ((appDetail.mode === 'advanced-chat' || appDetail.mode === 'workflow') && (pathname).endsWith('workflow'))
      //   setAppSiderbarExpand('collapse')
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [appDetail, isMobile])
  useEffect(() => {
    setAppDetail()
    setIsLoadingAppDetail(true)
    fetchAppDetail({ url: '/apps', id: appId }).then((res) => {
      setAppDetailRes(res)
    }).catch((e: any) => {
      if (e.status === 404)
        router.replace('/apps')
    }).finally(() => {
      setIsLoadingAppDetail(false)
    })
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [appId, pathname])
  useEffect(() => {
    if (!appDetailRes || isLoadingCurrentWorkspace || isLoadingAppDetail)
      return
    const res = appDetailRes
    // redirection
    const canIEditApp = isCurrentWorkspaceEditor
    if (!canIEditApp && (pathname.endsWith('configuration') || pathname.endsWith('workflow') || pathname.endsWith('logs'))) {
      router.replace(`/app/${appId}/overview`)
      return
    }
    if ((res.mode === 'workflow' || res.mode === 'advanced-chat') && (pathname).endsWith('configuration')) {
      router.replace(`/app/${appId}/workflow`)
    }
    else if ((res.mode !== 'workflow' && res.mode !== 'advanced-chat') && (pathname).endsWith('workflow')) {
      router.replace(`/app/${appId}/configuration`)
    }
    else {
      setAppDetail({ ...res, enable_sso: false })
      setNavigation(getNavigations(appId, isCurrentWorkspaceEditor, res.mode))
      if (systemFeatures.enable_web_sso_switch_component && canIEditApp) {
        fetchAppSSO({ appId }).then((ssoRes) => {
          setAppDetail({ ...res, enable_sso: ssoRes.enabled })
        })
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [appDetailRes, isCurrentWorkspaceEditor, isLoadingAppDetail, isLoadingCurrentWorkspace, systemFeatures.enable_web_sso_switch_component])
  useUnmount(() => {
    setAppDetail()
  })
  if (!appDetail) {
    return (
      <div className='flex h-full items-center justify-center bg-background-body'>
        <Loading />
      </div>
    )
  }
  return (
    <div className={cn(s.app, 'relative flex', 'overflow-hidden')}>
      {appDetail && (
        <AppSideBar title={appDetail.name} icon={appDetail.icon} icon_background={appDetail.icon_background as string} desc={appDetail.mode} navigation={navigation} />
      )}
      <div className="grow overflow-hidden bg-components-panel-bg">
        {children}
      </div>
    </div>
  )
}
export default React.memo(AppDetailLayout)
app/(commonLayout)/app/(appDetailLayout)/[appId]/layout.tsx
New file
@@ -0,0 +1,14 @@
import Main from './layout-main'
const AppDetailLayout = async (props: {
  children: React.ReactNode
  params: Promise<{ appId: string }>
}) => {
  const {
    children,
    params,
  } = props
  return <Main appId={(await params).appId}>{children}</Main>
}
export default AppDetailLayout
app/(commonLayout)/app/(appDetailLayout)/[appId]/logs/page.tsx
New file
@@ -0,0 +1,11 @@
import React from 'react'
import Main from '@/app/components/app/log-annotation'
import { PageType } from '@/app/components/base/features/new-feature-panel/annotation-reply/type'
const Logs = async () => {
  return (
    <Main pageType={PageType.log} />
  )
}
export default Logs
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/cardView.tsx
New file
@@ -0,0 +1,144 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { useContext, useContextSelector } from 'use-context-selector'
import AppCard from '@/app/components/app/overview/appCard'
import Loading from '@/app/components/base/loading'
import { ToastContext } from '@/app/components/base/toast'
import {
  fetchAppDetail,
  fetchAppSSO,
  updateAppSSO,
  updateAppSiteAccessToken,
  updateAppSiteConfig,
  updateAppSiteStatus,
} from '@/service/apps'
import type { App, AppSSO } from '@/types/app'
import type { UpdateAppSiteCodeResponse } from '@/models/app'
import { asyncRunSafe } from '@/utils'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import type { IAppCardProps } from '@/app/components/app/overview/appCard'
import { useStore as useAppStore } from '@/app/components/app/store'
import AppContext from '@/context/app-context'
export type ICardViewProps = {
  appId: string
  isInPanel?: boolean
  className?: string
}
const CardView: FC<ICardViewProps> = ({ appId, isInPanel, className }) => {
  const { t } = useTranslation()
  const { notify } = useContext(ToastContext)
  const appDetail = useAppStore(state => state.appDetail)
  const setAppDetail = useAppStore(state => state.setAppDetail)
  const systemFeatures = useContextSelector(AppContext, state => state.systemFeatures)
  const updateAppDetail = async () => {
    try {
      const res = await fetchAppDetail({ url: '/apps', id: appId })
      if (systemFeatures.enable_web_sso_switch_component) {
        const ssoRes = await fetchAppSSO({ appId })
        setAppDetail({ ...res, enable_sso: ssoRes.enabled })
      }
      else {
        setAppDetail({ ...res })
      }
    }
    catch (error) { console.error(error) }
  }
  const handleCallbackResult = (err: Error | null, message?: string) => {
    const type = err ? 'error' : 'success'
    message ||= (type === 'success' ? 'modifiedSuccessfully' : 'modifiedUnsuccessfully')
    if (type === 'success')
      updateAppDetail()
    notify({
      type,
      message: t(`common.actionMsg.${message}`),
    })
  }
  const onChangeSiteStatus = async (value: boolean) => {
    const [err] = await asyncRunSafe<App>(
      updateAppSiteStatus({
        url: `/apps/${appId}/site-enable`,
        body: { enable_site: value },
      }) as Promise<App>,
    )
    handleCallbackResult(err)
  }
  const onChangeApiStatus = async (value: boolean) => {
    const [err] = await asyncRunSafe<App>(
      updateAppSiteStatus({
        url: `/apps/${appId}/api-enable`,
        body: { enable_api: value },
      }) as Promise<App>,
    )
    handleCallbackResult(err)
  }
  const onSaveSiteConfig: IAppCardProps['onSaveSiteConfig'] = async (params) => {
    const [err] = await asyncRunSafe<App>(
      updateAppSiteConfig({
        url: `/apps/${appId}/site`,
        body: params,
      }) as Promise<App>,
    )
    if (!err)
      localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
    if (systemFeatures.enable_web_sso_switch_component) {
      const [sso_err] = await asyncRunSafe<AppSSO>(
        updateAppSSO({ id: appId, enabled: Boolean(params.enable_sso) }) as Promise<AppSSO>,
      )
      if (sso_err) {
        handleCallbackResult(sso_err)
        return
      }
    }
    handleCallbackResult(err)
  }
  const onGenerateCode = async () => {
    const [err] = await asyncRunSafe<UpdateAppSiteCodeResponse>(
      updateAppSiteAccessToken({
        url: `/apps/${appId}/site/access-token-reset`,
      }) as Promise<UpdateAppSiteCodeResponse>,
    )
    handleCallbackResult(err, err ? 'generatedUnsuccessfully' : 'generatedSuccessfully')
  }
  if (!appDetail)
    return <Loading />
  return (
    <div className={className || 'mb-6 grid w-full grid-cols-1 gap-6 xl:grid-cols-2'}>
      <AppCard
        appInfo={appDetail}
        cardType="webapp"
        isInPanel={isInPanel}
        onChangeStatus={onChangeSiteStatus}
        onGenerateCode={onGenerateCode}
        onSaveSiteConfig={onSaveSiteConfig}
      />
      <AppCard
        cardType="api"
        appInfo={appDetail}
        isInPanel={isInPanel}
        onChangeStatus={onChangeApiStatus}
      />
    </div>
  )
}
export default CardView
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/chartView.tsx
New file
@@ -0,0 +1,106 @@
'use client'
import React, { useState } from 'react'
import dayjs from 'dayjs'
import quarterOfYear from 'dayjs/plugin/quarterOfYear'
import { useTranslation } from 'react-i18next'
import type { PeriodParams } from '@/app/components/app/overview/appChart'
import { AvgResponseTime, AvgSessionInteractions, AvgUserInteractions, ConversationsChart, CostChart, EndUsersChart, MessagesChart, TokenPerSecond, UserSatisfactionRate, WorkflowCostChart, WorkflowDailyTerminalsChart, WorkflowMessagesChart } from '@/app/components/app/overview/appChart'
import type { Item } from '@/app/components/base/select'
import { SimpleSelect } from '@/app/components/base/select'
import { TIME_PERIOD_MAPPING } from '@/app/components/app/log/filter'
import { useStore as useAppStore } from '@/app/components/app/store'
dayjs.extend(quarterOfYear)
const today = dayjs()
const queryDateFormat = 'YYYY-MM-DD HH:mm'
export type IChartViewProps = {
  appId: string
}
export default function ChartView({ appId }: IChartViewProps) {
  const { t } = useTranslation()
  const appDetail = useAppStore(state => state.appDetail)
  const isChatApp = appDetail?.mode !== 'completion' && appDetail?.mode !== 'workflow'
  const isWorkflow = appDetail?.mode === 'workflow'
  const [period, setPeriod] = useState<PeriodParams>({ name: t('appLog.filter.period.last7days'), query: { start: today.subtract(7, 'day').startOf('day').format(queryDateFormat), end: today.endOf('day').format(queryDateFormat) } })
  const onSelect = (item: Item) => {
    if (item.value === -1) {
      setPeriod({ name: item.name, query: undefined })
    }
    else if (item.value === 0) {
      const startOfToday = today.startOf('day').format(queryDateFormat)
      const endOfToday = today.endOf('day').format(queryDateFormat)
      setPeriod({ name: item.name, query: { start: startOfToday, end: endOfToday } })
    }
    else {
      setPeriod({ name: item.name, query: { start: today.subtract(item.value as number, 'day').startOf('day').format(queryDateFormat), end: today.endOf('day').format(queryDateFormat) } })
    }
  }
  if (!appDetail)
    return null
  return (
    <div>
      <div className='system-xl-semibold mb-4 mt-8 flex flex-row items-center text-text-primary'>
        <span className='mr-3'>{t('appOverview.analysis.title')}</span>
        <SimpleSelect
          items={Object.entries(TIME_PERIOD_MAPPING).map(([k, v]) => ({ value: k, name: t(`appLog.filter.period.${v.name}`) }))}
          className='mt-0 !w-40'
          onSelect={(item) => {
            const id = item.value
            const value = TIME_PERIOD_MAPPING[id]?.value ?? '-1'
            const name = item.name || t('appLog.filter.period.allTime')
            onSelect({ value, name })
          }}
          defaultValue={'2'}
        />
      </div>
      {!isWorkflow && (
        <div className='mb-6 grid w-full grid-cols-1 gap-6 xl:grid-cols-2'>
          <ConversationsChart period={period} id={appId} />
          <EndUsersChart period={period} id={appId} />
        </div>
      )}
      {!isWorkflow && (
        <div className='mb-6 grid w-full grid-cols-1 gap-6 xl:grid-cols-2'>
          {isChatApp
            ? (
              <AvgSessionInteractions period={period} id={appId} />
            )
            : (
              <AvgResponseTime period={period} id={appId} />
            )}
          <TokenPerSecond period={period} id={appId} />
        </div>
      )}
      {!isWorkflow && (
        <div className='mb-6 grid w-full grid-cols-1 gap-6 xl:grid-cols-2'>
          <UserSatisfactionRate period={period} id={appId} />
          <CostChart period={period} id={appId} />
        </div>
      )}
      {!isWorkflow && isChatApp && (
        <div className='mb-6 grid w-full grid-cols-1 gap-6 xl:grid-cols-2'>
          <MessagesChart period={period} id={appId} />
        </div>
      )}
      {isWorkflow && (
        <div className='mb-6 grid w-full grid-cols-1 gap-6 xl:grid-cols-2'>
          <WorkflowMessagesChart period={period} id={appId} />
          <WorkflowDailyTerminalsChart period={period} id={appId} />
        </div>
      )}
      {isWorkflow && (
        <div className='mb-6 grid w-full grid-cols-1 gap-6 xl:grid-cols-2'>
          <WorkflowCostChart period={period} id={appId} />
          <AvgUserInteractions period={period} id={appId} />
        </div>
      )}
    </div>
  )
}
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/page.tsx
New file
@@ -0,0 +1,28 @@
import React from 'react'
import ChartView from './chartView'
import CardView from './cardView'
import TracingPanel from './tracing/panel'
import ApikeyInfoPanel from '@/app/components/app/overview/apikey-info-panel'
export type IDevelopProps = {
  params: Promise<{ appId: string }>
}
const Overview = async (props: IDevelopProps) => {
  const params = await props.params
  const {
    appId,
  } = params
  return (
    <div className="h-full overflow-scroll bg-chatbot-bg px-4 py-6 sm:px-12">
      <ApikeyInfoPanel />
      <TracingPanel />
      <CardView appId={appId} />
      <ChartView appId={appId} />
    </div>
  )
}
export default Overview
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config-button.tsx
New file
@@ -0,0 +1,71 @@
'use client'
import type { FC } from 'react'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import {
  RiEqualizer2Line,
} from '@remixicon/react'
import type { PopupProps } from './config-popup'
import ConfigPopup from './config-popup'
import cn from '@/utils/classnames'
import {
  PortalToFollowElem,
  PortalToFollowElemContent,
  PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
type Props = {
  readOnly: boolean
  className?: string
  hasConfigured: boolean
  controlShowPopup?: number
} & PopupProps
const ConfigBtn: FC<Props> = ({
  className,
  hasConfigured,
  controlShowPopup,
  ...popupProps
}) => {
  const [open, doSetOpen] = useState(false)
  const openRef = useRef(open)
  const setOpen = useCallback((v: boolean) => {
    doSetOpen(v)
    openRef.current = v
  }, [doSetOpen])
  const handleTrigger = useCallback(() => {
    setOpen(!openRef.current)
  }, [setOpen])
  useEffect(() => {
    if (controlShowPopup)
      // setOpen(!openRef.current)
      setOpen(true)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [controlShowPopup])
  if (popupProps.readOnly && !hasConfigured)
    return null
  return (
    <PortalToFollowElem
      open={open}
      onOpenChange={setOpen}
      placement='bottom-end'
      offset={{
        mainAxis: 12,
        crossAxis: hasConfigured ? 8 : 49,
      }}
    >
      <PortalToFollowElemTrigger onClick={handleTrigger}>
        <div className={cn(className, 'rounded-md p-1')}>
          <RiEqualizer2Line className='h-4 w-4 text-text-tertiary' />
        </div>
      </PortalToFollowElemTrigger>
      <PortalToFollowElemContent className='z-[11]'>
        <ConfigPopup {...popupProps} />
      </PortalToFollowElemContent>
    </PortalToFollowElem>
  )
}
export default React.memo(ConfigBtn)
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config-popup.tsx
New file
@@ -0,0 +1,259 @@
'use client'
import type { FC } from 'react'
import React, { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import TracingIcon from './tracing-icon'
import ProviderPanel from './provider-panel'
import type { LangFuseConfig, LangSmithConfig, OpikConfig, WeaveConfig } from './type'
import { TracingProvider } from './type'
import ProviderConfigModal from './provider-config-modal'
import Indicator from '@/app/components/header/indicator'
import Switch from '@/app/components/base/switch'
import Tooltip from '@/app/components/base/tooltip'
import Divider from '@/app/components/base/divider'
import cn from '@/utils/classnames'
const I18N_PREFIX = 'app.tracing'
export type PopupProps = {
  appId: string
  readOnly: boolean
  enabled: boolean
  onStatusChange: (enabled: boolean) => void
  chosenProvider: TracingProvider | null
  onChooseProvider: (provider: TracingProvider) => void
  langSmithConfig: LangSmithConfig | null
  langFuseConfig: LangFuseConfig | null
  opikConfig: OpikConfig | null
  weaveConfig: WeaveConfig | null
  onConfigUpdated: (provider: TracingProvider, payload: LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig) => void
  onConfigRemoved: (provider: TracingProvider) => void
}
const ConfigPopup: FC<PopupProps> = ({
  appId,
  readOnly,
  enabled,
  onStatusChange,
  chosenProvider,
  onChooseProvider,
  langSmithConfig,
  langFuseConfig,
  opikConfig,
  weaveConfig,
  onConfigUpdated,
  onConfigRemoved,
}) => {
  const { t } = useTranslation()
  const [currentProvider, setCurrentProvider] = useState<TracingProvider | null>(TracingProvider.langfuse)
  const [isShowConfigModal, {
    setTrue: showConfigModal,
    setFalse: hideConfigModal,
  }] = useBoolean(false)
  const handleOnConfig = useCallback((provider: TracingProvider) => {
    return () => {
      setCurrentProvider(provider)
      showConfigModal()
    }
  }, [showConfigModal])
  const handleOnChoose = useCallback((provider: TracingProvider) => {
    return () => {
      onChooseProvider(provider)
    }
  }, [onChooseProvider])
  const handleConfigUpdated = useCallback((payload: LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig) => {
    onConfigUpdated(currentProvider!, payload)
    hideConfigModal()
  }, [currentProvider, hideConfigModal, onConfigUpdated])
  const handleConfigRemoved = useCallback(() => {
    onConfigRemoved(currentProvider!)
    hideConfigModal()
  }, [currentProvider, hideConfigModal, onConfigRemoved])
  const providerAllConfigured = langSmithConfig && langFuseConfig && opikConfig && weaveConfig
  const providerAllNotConfigured = !langSmithConfig && !langFuseConfig && !opikConfig && !weaveConfig
  const switchContent = (
    <Switch
      className='ml-3'
      defaultValue={enabled}
      onChange={onStatusChange}
      disabled={providerAllNotConfigured}
    />
  )
  const langSmithPanel = (
    <ProviderPanel
      type={TracingProvider.langSmith}
      readOnly={readOnly}
      config={langSmithConfig}
      hasConfigured={!!langSmithConfig}
      onConfig={handleOnConfig(TracingProvider.langSmith)}
      isChosen={chosenProvider === TracingProvider.langSmith}
      onChoose={handleOnChoose(TracingProvider.langSmith)}
      key="langSmith-provider-panel"
    />
  )
  const langfusePanel = (
    <ProviderPanel
      type={TracingProvider.langfuse}
      readOnly={readOnly}
      config={langFuseConfig}
      hasConfigured={!!langFuseConfig}
      onConfig={handleOnConfig(TracingProvider.langfuse)}
      isChosen={chosenProvider === TracingProvider.langfuse}
      onChoose={handleOnChoose(TracingProvider.langfuse)}
      key="langfuse-provider-panel"
    />
  )
  const opikPanel = (
    <ProviderPanel
      type={TracingProvider.opik}
      readOnly={readOnly}
      config={opikConfig}
      hasConfigured={!!opikConfig}
      onConfig={handleOnConfig(TracingProvider.opik)}
      isChosen={chosenProvider === TracingProvider.opik}
      onChoose={handleOnChoose(TracingProvider.opik)}
      key="opik-provider-panel"
    />
  )
  const weavePanel = (
    <ProviderPanel
      type={TracingProvider.weave}
      readOnly={readOnly}
      config={weaveConfig}
      hasConfigured={!!weaveConfig}
      onConfig={handleOnConfig(TracingProvider.weave)}
      isChosen={chosenProvider === TracingProvider.weave}
      onChoose={handleOnChoose(TracingProvider.weave)}
      key="weave-provider-panel"
    />
  )
  const configuredProviderPanel = () => {
    const configuredPanels: JSX.Element[] = []
    if (langFuseConfig)
      configuredPanels.push(langfusePanel)
    if (langSmithConfig)
      configuredPanels.push(langSmithPanel)
    if (opikConfig)
      configuredPanels.push(opikPanel)
    if (weaveConfig)
      configuredPanels.push(weavePanel)
    return configuredPanels
  }
  const moreProviderPanel = () => {
    const notConfiguredPanels: JSX.Element[] = []
    if (!langFuseConfig)
      notConfiguredPanels.push(langfusePanel)
    if (!langSmithConfig)
      notConfiguredPanels.push(langSmithPanel)
    if (!opikConfig)
      notConfiguredPanels.push(opikPanel)
    if (!weaveConfig)
      notConfiguredPanels.push(weavePanel)
    return notConfiguredPanels
  }
  const configuredProviderConfig = () => {
    if (currentProvider === TracingProvider.langSmith)
      return langSmithConfig
    if (currentProvider === TracingProvider.langfuse)
      return langFuseConfig
    if (currentProvider === TracingProvider.opik)
      return opikConfig
    return weaveConfig
  }
  return (
    <div className='w-[420px] rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg p-4 shadow-xl'>
      <div className='flex items-center justify-between'>
        <div className='flex items-center'>
          <TracingIcon size='md' className='mr-2' />
          <div className='title-2xl-semi-bold text-text-primary'>{t(`${I18N_PREFIX}.tracing`)}</div>
        </div>
        <div className='flex items-center'>
          <Indicator color={enabled ? 'green' : 'gray'} />
          <div className={cn('system-xs-semibold-uppercase ml-1 text-text-tertiary', enabled && 'text-util-colors-green-green-600')}>
            {t(`${I18N_PREFIX}.${enabled ? 'enabled' : 'disabled'}`)}
          </div>
          {!readOnly && (
            <>
              {providerAllNotConfigured
                ? (
                  <Tooltip
                    popupContent={t(`${I18N_PREFIX}.disabledTip`)}
                  >
                    {switchContent}
                  </Tooltip>
                )
                : switchContent}
            </>
          )}
        </div>
      </div>
      <div className='system-xs-regular mt-2 text-text-tertiary'>
        {t(`${I18N_PREFIX}.tracingDescription`)}
      </div>
      <Divider className='my-3' />
      <div className='relative'>
        {(providerAllConfigured || providerAllNotConfigured)
          ? (
            <>
              <div className='system-xs-medium-uppercase text-text-tertiary'>{t(`${I18N_PREFIX}.configProviderTitle.${providerAllConfigured ? 'configured' : 'notConfigured'}`)}</div>
              <div className='mt-2 space-y-2'>
                {langfusePanel}
                {langSmithPanel}
                {opikPanel}
                {weavePanel}
              </div>
            </>
          )
          : (
            <>
              <div className='system-xs-medium-uppercase text-text-tertiary'>{t(`${I18N_PREFIX}.configProviderTitle.configured`)}</div>
              <div className='mt-2 space-y-2'>
                {configuredProviderPanel()}
              </div>
              <div className='system-xs-medium-uppercase mt-3 text-text-tertiary'>{t(`${I18N_PREFIX}.configProviderTitle.moreProvider`)}</div>
              <div className='mt-2 space-y-2'>
                {moreProviderPanel()}
              </div>
            </>
          )}
      </div>
      {isShowConfigModal && (
        <ProviderConfigModal
          appId={appId}
          type={currentProvider!}
          payload={configuredProviderConfig()}
          onCancel={hideConfigModal}
          onSaved={handleConfigUpdated}
          onChosen={onChooseProvider}
          onRemoved={handleConfigRemoved}
        />
      )}
    </div>
  )
}
export default React.memo(ConfigPopup)
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config.ts
New file
@@ -0,0 +1,8 @@
import { TracingProvider } from './type'
export const docURL = {
  [TracingProvider.langSmith]: 'https://docs.smith.langchain.com/',
  [TracingProvider.langfuse]: 'https://docs.langfuse.com',
  [TracingProvider.opik]: 'https://www.comet.com/docs/opik/tracing/integrations/dify#setup-instructions',
  [TracingProvider.weave]: 'https://weave-docs.wandb.ai/',
}
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/field.tsx
New file
@@ -0,0 +1,41 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import cn from '@/utils/classnames'
import Input from '@/app/components/base/input'
type Props = {
  className?: string
  label: string
  labelClassName?: string
  value: string | number
  onChange: (value: string) => void
  isRequired?: boolean
  placeholder?: string
}
const Field: FC<Props> = ({
  className,
  label,
  labelClassName,
  value,
  onChange,
  isRequired = false,
  placeholder = '',
}) => {
  return (
    <div className={cn(className)}>
      <div className='flex py-[7px]'>
        <div className={cn(labelClassName, 'flex h-[18px] items-center text-[13px] font-medium text-text-primary')}>{label} </div>
        {isRequired && <span className='ml-0.5 text-xs font-semibold text-[#D92D20]'>*</span>}
      </div>
      <Input
        value={value}
        onChange={e => onChange(e.target.value)}
        className='h-9'
        placeholder={placeholder}
      />
    </div>
  )
}
export default React.memo(Field)
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/panel.tsx
New file
@@ -0,0 +1,238 @@
'use client'
import type { FC } from 'react'
import React, { useCallback, useEffect, useState } from 'react'
import {
  RiArrowDownDoubleLine,
} from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { usePathname } from 'next/navigation'
import { useBoolean } from 'ahooks'
import type { LangFuseConfig, LangSmithConfig, OpikConfig, WeaveConfig } from './type'
import { TracingProvider } from './type'
import TracingIcon from './tracing-icon'
import ConfigButton from './config-button'
import cn from '@/utils/classnames'
import { LangfuseIcon, LangsmithIcon, OpikIcon, WeaveIcon } from '@/app/components/base/icons/src/public/tracing'
import Indicator from '@/app/components/header/indicator'
import { fetchTracingConfig as doFetchTracingConfig, fetchTracingStatus, updateTracingStatus } from '@/service/apps'
import type { TracingStatus } from '@/models/app'
import Toast from '@/app/components/base/toast'
import { useAppContext } from '@/context/app-context'
import Loading from '@/app/components/base/loading'
import Divider from '@/app/components/base/divider'
const I18N_PREFIX = 'app.tracing'
const Title = ({
  className,
}: {
  className?: string
}) => {
  const { t } = useTranslation()
  return (
    <div className={cn('system-xl-semibold flex items-center text-text-primary', className)}>
      {t('common.appMenus.overview')}
    </div>
  )
}
const Panel: FC = () => {
  const { t } = useTranslation()
  const pathname = usePathname()
  const matched = pathname.match(/\/app\/([^/]+)/)
  const appId = (matched?.length && matched[1]) ? matched[1] : ''
  const { isCurrentWorkspaceEditor } = useAppContext()
  const readOnly = !isCurrentWorkspaceEditor
  const [isLoaded, {
    setTrue: setLoaded,
  }] = useBoolean(false)
  const [tracingStatus, setTracingStatus] = useState<TracingStatus | null>(null)
  const enabled = tracingStatus?.enabled || false
  const handleTracingStatusChange = async (tracingStatus: TracingStatus, noToast?: boolean) => {
    await updateTracingStatus({ appId, body: tracingStatus })
    setTracingStatus(tracingStatus)
    if (!noToast) {
      Toast.notify({
        type: 'success',
        message: t('common.api.success'),
      })
    }
  }
  const handleTracingEnabledChange = (enabled: boolean) => {
    handleTracingStatusChange({
      tracing_provider: tracingStatus?.tracing_provider || null,
      enabled,
    })
  }
  const handleChooseProvider = (provider: TracingProvider) => {
    handleTracingStatusChange({
      tracing_provider: provider,
      enabled: true,
    })
  }
  const inUseTracingProvider: TracingProvider | null = tracingStatus?.tracing_provider || null
  const InUseProviderIcon
    = inUseTracingProvider === TracingProvider.langSmith
      ? LangsmithIcon
      : inUseTracingProvider === TracingProvider.langfuse
        ? LangfuseIcon
        : inUseTracingProvider === TracingProvider.opik
          ? OpikIcon
          : inUseTracingProvider === TracingProvider.weave
            ? WeaveIcon
            : LangsmithIcon
  const [langSmithConfig, setLangSmithConfig] = useState<LangSmithConfig | null>(null)
  const [langFuseConfig, setLangFuseConfig] = useState<LangFuseConfig | null>(null)
  const [opikConfig, setOpikConfig] = useState<OpikConfig | null>(null)
  const [weaveConfig, setWeaveConfig] = useState<WeaveConfig | null>(null)
  const hasConfiguredTracing = !!(langSmithConfig || langFuseConfig || opikConfig || weaveConfig)
  const fetchTracingConfig = async () => {
    const { tracing_config: langSmithConfig, has_not_configured: langSmithHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.langSmith })
    if (!langSmithHasNotConfig)
      setLangSmithConfig(langSmithConfig as LangSmithConfig)
    const { tracing_config: langFuseConfig, has_not_configured: langFuseHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.langfuse })
    if (!langFuseHasNotConfig)
      setLangFuseConfig(langFuseConfig as LangFuseConfig)
    const { tracing_config: opikConfig, has_not_configured: OpikHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.opik })
    if (!OpikHasNotConfig)
      setOpikConfig(opikConfig as OpikConfig)
    const { tracing_config: weaveConfig, has_not_configured: weaveHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.weave })
    if (!weaveHasNotConfig)
      setWeaveConfig(weaveConfig as WeaveConfig)
  }
  const handleTracingConfigUpdated = async (provider: TracingProvider) => {
    // call api to hide secret key value
    const { tracing_config } = await doFetchTracingConfig({ appId, provider })
    if (provider === TracingProvider.langSmith)
      setLangSmithConfig(tracing_config as LangSmithConfig)
    else if (provider === TracingProvider.langfuse)
      setLangFuseConfig(tracing_config as LangFuseConfig)
    else if (provider === TracingProvider.opik)
      setOpikConfig(tracing_config as OpikConfig)
    else if (provider === TracingProvider.weave)
      setWeaveConfig(tracing_config as WeaveConfig)
  }
  const handleTracingConfigRemoved = (provider: TracingProvider) => {
    if (provider === TracingProvider.langSmith)
      setLangSmithConfig(null)
    else if (provider === TracingProvider.langfuse)
      setLangFuseConfig(null)
    else if (provider === TracingProvider.opik)
      setOpikConfig(null)
    else if (provider === TracingProvider.weave)
      setWeaveConfig(null)
    if (provider === inUseTracingProvider) {
      handleTracingStatusChange({
        enabled: false,
        tracing_provider: null,
      }, true)
    }
  }
  useEffect(() => {
    (async () => {
      const tracingStatus = await fetchTracingStatus({ appId })
      setTracingStatus(tracingStatus)
      await fetchTracingConfig()
      setLoaded()
    })()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])
  const [controlShowPopup, setControlShowPopup] = useState<number>(0)
  const showPopup = useCallback(() => {
    setControlShowPopup(Date.now())
  }, [setControlShowPopup])
  if (!isLoaded) {
    return (
      <div className='mb-3 flex items-center justify-between'>
        <Title className='h-[41px]' />
        <div className='w-[200px]'>
          <Loading />
        </div>
      </div>
    )
  }
  return (
    <div className={cn('mb-3 flex items-center justify-between')}>
      <Title className='h-[41px]' />
      <div
        className={cn(
          'flex cursor-pointer items-center rounded-xl border-l-[0.5px] border-t border-effects-highlight bg-background-default-dodge p-2 shadow-xs hover:border-effects-highlight-lightmode-off hover:bg-background-default-lighter',
          controlShowPopup && 'border-effects-highlight-lightmode-off bg-background-default-lighter',
        )}
        onClick={showPopup}
      >
        {!inUseTracingProvider && (
          <>
            <TracingIcon size='md' />
            <div className='system-sm-semibold mx-2 text-text-secondary'>{t(`${I18N_PREFIX}.title`)}</div>
            <div className='flex items-center' onClick={e => e.stopPropagation()}>
              <ConfigButton
                appId={appId}
                readOnly={readOnly}
                hasConfigured={false}
                enabled={enabled}
                onStatusChange={handleTracingEnabledChange}
                chosenProvider={inUseTracingProvider}
                onChooseProvider={handleChooseProvider}
                langSmithConfig={langSmithConfig}
                langFuseConfig={langFuseConfig}
                opikConfig={opikConfig}
                weaveConfig={weaveConfig}
                onConfigUpdated={handleTracingConfigUpdated}
                onConfigRemoved={handleTracingConfigRemoved}
                controlShowPopup={controlShowPopup}
              />
            </div>
            <Divider type='vertical' className='h-3.5' />
            <div className='rounded-md p-1'>
              <RiArrowDownDoubleLine className='h-4 w-4 text-text-tertiary' />
            </div>
          </>
        )}
        {hasConfiguredTracing && (
          <>
            <div className='ml-4 mr-1 flex items-center'>
              <Indicator color={enabled ? 'green' : 'gray'} />
              <div className='system-xs-semibold-uppercase ml-1.5 text-text-tertiary'>
                {t(`${I18N_PREFIX}.${enabled ? 'enabled' : 'disabled'}`)}
              </div>
            </div>
            {InUseProviderIcon && <InUseProviderIcon className='ml-1 h-4' />}
            <Divider type='vertical' className='h-3.5' />
            <div className='flex items-center' onClick={e => e.stopPropagation()}>
              <ConfigButton
                appId={appId}
                readOnly={readOnly}
                hasConfigured
                className='ml-2'
                enabled={enabled}
                onStatusChange={handleTracingEnabledChange}
                chosenProvider={inUseTracingProvider}
                onChooseProvider={handleChooseProvider}
                langSmithConfig={langSmithConfig}
                langFuseConfig={langFuseConfig}
                opikConfig={opikConfig}
                weaveConfig={weaveConfig}
                onConfigUpdated={handleTracingConfigUpdated}
                onConfigRemoved={handleTracingConfigRemoved}
                controlShowPopup={controlShowPopup}
              />
            </div>
          </>
        )}
      </div >
    </div >
  )
}
export default React.memo(Panel)
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-config-modal.tsx
New file
@@ -0,0 +1,390 @@
'use client'
import type { FC } from 'react'
import React, { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import Field from './field'
import type { LangFuseConfig, LangSmithConfig, OpikConfig, WeaveConfig } from './type'
import { TracingProvider } from './type'
import { docURL } from './config'
import {
  PortalToFollowElem,
  PortalToFollowElemContent,
} from '@/app/components/base/portal-to-follow-elem'
import { Lock01 } from '@/app/components/base/icons/src/vender/solid/security'
import Button from '@/app/components/base/button'
import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general'
import Confirm from '@/app/components/base/confirm'
import { addTracingConfig, removeTracingConfig, updateTracingConfig } from '@/service/apps'
import Toast from '@/app/components/base/toast'
import Divider from '@/app/components/base/divider'
type Props = {
  appId: string
  type: TracingProvider
  payload?: LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig | null
  onRemoved: () => void
  onCancel: () => void
  onSaved: (payload: LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig) => void
  onChosen: (provider: TracingProvider) => void
}
const I18N_PREFIX = 'app.tracing.configProvider'
const langSmithConfigTemplate = {
  api_key: '',
  project: '',
  endpoint: '',
}
const langFuseConfigTemplate = {
  public_key: '',
  secret_key: '',
  host: '',
}
const opikConfigTemplate = {
  api_key: '',
  project: '',
  url: '',
  workspace: '',
}
const weaveConfigTemplate = {
  api_key: '',
  entity: '',
  project: '',
  endpoint: '',
}
const ProviderConfigModal: FC<Props> = ({
  appId,
  type,
  payload,
  onRemoved,
  onCancel,
  onSaved,
  onChosen,
}) => {
  const { t } = useTranslation()
  const isEdit = !!payload
  const isAdd = !isEdit
  const [isSaving, setIsSaving] = useState(false)
  const [config, setConfig] = useState<LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig>((() => {
    if (isEdit)
      return payload
    if (type === TracingProvider.langSmith)
      return langSmithConfigTemplate
    else if (type === TracingProvider.langfuse)
      return langFuseConfigTemplate
    else if (type === TracingProvider.opik)
      return opikConfigTemplate
    return weaveConfigTemplate
  })())
  const [isShowRemoveConfirm, {
    setTrue: showRemoveConfirm,
    setFalse: hideRemoveConfirm,
  }] = useBoolean(false)
  const handleRemove = useCallback(async () => {
    await removeTracingConfig({
      appId,
      provider: type,
    })
    Toast.notify({
      type: 'success',
      message: t('common.api.remove'),
    })
    onRemoved()
    hideRemoveConfirm()
  }, [hideRemoveConfirm, appId, type, t, onRemoved])
  const handleConfigChange = useCallback((key: string) => {
    return (value: string) => {
      setConfig({
        ...config,
        [key]: value,
      })
    }
  }, [config])
  const checkValid = useCallback(() => {
    let errorMessage = ''
    if (type === TracingProvider.langSmith) {
      const postData = config as LangSmithConfig
      if (!postData.api_key)
        errorMessage = t('common.errorMsg.fieldRequired', { field: 'API Key' })
      if (!errorMessage && !postData.project)
        errorMessage = t('common.errorMsg.fieldRequired', { field: t(`${I18N_PREFIX}.project`) })
    }
    if (type === TracingProvider.langfuse) {
      const postData = config as LangFuseConfig
      if (!errorMessage && !postData.secret_key)
        errorMessage = t('common.errorMsg.fieldRequired', { field: t(`${I18N_PREFIX}.secretKey`) })
      if (!errorMessage && !postData.public_key)
        errorMessage = t('common.errorMsg.fieldRequired', { field: t(`${I18N_PREFIX}.publicKey`) })
      if (!errorMessage && !postData.host)
        errorMessage = t('common.errorMsg.fieldRequired', { field: 'Host' })
    }
    if (type === TracingProvider.opik) {
      // todo: check field validity
      // const postData = config as OpikConfig
    }
    if (type === TracingProvider.weave) {
      const postData = config as WeaveConfig
      if (!errorMessage && !postData.api_key)
        errorMessage = t('common.errorMsg.fieldRequired', { field: 'API Key' })
      if (!errorMessage && !postData.project)
        errorMessage = t('common.errorMsg.fieldRequired', { field: t(`${I18N_PREFIX}.project`) })
    }
    return errorMessage
  }, [config, t, type])
  const handleSave = useCallback(async () => {
    if (isSaving)
      return
    const errorMessage = checkValid()
    if (errorMessage) {
      Toast.notify({
        type: 'error',
        message: errorMessage,
      })
      return
    }
    const action = isEdit ? updateTracingConfig : addTracingConfig
    try {
      await action({
        appId,
        body: {
          tracing_provider: type,
          tracing_config: config,
        },
      })
      Toast.notify({
        type: 'success',
        message: t('common.api.success'),
      })
      onSaved(config)
      if (isAdd)
        onChosen(type)
    }
    finally {
      setIsSaving(false)
    }
  }, [appId, checkValid, config, isAdd, isEdit, isSaving, onChosen, onSaved, t, type])
  return (
    <>
      {!isShowRemoveConfirm
        ? (
          <PortalToFollowElem open>
            <PortalToFollowElemContent className='z-[60] h-full w-full'>
              <div className='fixed inset-0 flex items-center justify-center bg-background-overlay'>
                <div className='mx-2 max-h-[calc(100vh-120px)] w-[640px] overflow-y-auto rounded-2xl bg-components-panel-bg shadow-xl'>
                  <div className='px-8 pt-8'>
                    <div className='mb-4 flex items-center justify-between'>
                      <div className='title-2xl-semi-bold text-text-primary'>{t(`${I18N_PREFIX}.title`)}{t(`app.tracing.${type}.title`)}</div>
                    </div>
                    <div className='space-y-4'>
                      {type === TracingProvider.weave && (
                        <>
                          <Field
                            label='API Key'
                            labelClassName='!text-sm'
                            isRequired
                            value={(config as WeaveConfig).api_key}
                            onChange={handleConfigChange('api_key')}
                            placeholder={t(`${I18N_PREFIX}.placeholder`, { key: 'API Key' })!}
                          />
                          <Field
                            label={t(`${I18N_PREFIX}.project`)!}
                            labelClassName='!text-sm'
                            isRequired
                            value={(config as WeaveConfig).project}
                            onChange={handleConfigChange('project')}
                            placeholder={t(`${I18N_PREFIX}.placeholder`, { key: t(`${I18N_PREFIX}.project`) })!}
                          />
                          <Field
                            label='Entity'
                            labelClassName='!text-sm'
                            value={(config as WeaveConfig).entity}
                            onChange={handleConfigChange('entity')}
                            placeholder={t(`${I18N_PREFIX}.placeholder`, { key: 'Entity' })!}
                          />
                          <Field
                            label='Endpoint'
                            labelClassName='!text-sm'
                            value={(config as WeaveConfig).endpoint}
                            onChange={handleConfigChange('endpoint')}
                            placeholder={'https://trace.wandb.ai/'}
                          />
                        </>
                      )}
                      {type === TracingProvider.langSmith && (
                        <>
                          <Field
                            label='API Key'
                            labelClassName='!text-sm'
                            isRequired
                            value={(config as LangSmithConfig).api_key}
                            onChange={handleConfigChange('api_key')}
                            placeholder={t(`${I18N_PREFIX}.placeholder`, { key: 'API Key' })!}
                          />
                          <Field
                            label={t(`${I18N_PREFIX}.project`)!}
                            labelClassName='!text-sm'
                            isRequired
                            value={(config as LangSmithConfig).project}
                            onChange={handleConfigChange('project')}
                            placeholder={t(`${I18N_PREFIX}.placeholder`, { key: t(`${I18N_PREFIX}.project`) })!}
                          />
                          <Field
                            label='Endpoint'
                            labelClassName='!text-sm'
                            value={(config as LangSmithConfig).endpoint}
                            onChange={handleConfigChange('endpoint')}
                            placeholder={'https://api.smith.langchain.com'}
                          />
                        </>
                      )}
                      {type === TracingProvider.langfuse && (
                        <>
                          <Field
                            label={t(`${I18N_PREFIX}.secretKey`)!}
                            labelClassName='!text-sm'
                            value={(config as LangFuseConfig).secret_key}
                            isRequired
                            onChange={handleConfigChange('secret_key')}
                            placeholder={t(`${I18N_PREFIX}.placeholder`, { key: t(`${I18N_PREFIX}.secretKey`) })!}
                          />
                          <Field
                            label={t(`${I18N_PREFIX}.publicKey`)!}
                            labelClassName='!text-sm'
                            isRequired
                            value={(config as LangFuseConfig).public_key}
                            onChange={handleConfigChange('public_key')}
                            placeholder={t(`${I18N_PREFIX}.placeholder`, { key: t(`${I18N_PREFIX}.publicKey`) })!}
                          />
                          <Field
                            label='Host'
                            labelClassName='!text-sm'
                            isRequired
                            value={(config as LangFuseConfig).host}
                            onChange={handleConfigChange('host')}
                            placeholder='https://cloud.langfuse.com'
                          />
                        </>
                      )}
                      {type === TracingProvider.opik && (
                        <>
                          <Field
                            label='API Key'
                            labelClassName='!text-sm'
                            value={(config as OpikConfig).api_key}
                            onChange={handleConfigChange('api_key')}
                            placeholder={t(`${I18N_PREFIX}.placeholder`, { key: 'API Key' })!}
                          />
                          <Field
                            label={t(`${I18N_PREFIX}.project`)!}
                            labelClassName='!text-sm'
                            value={(config as OpikConfig).project}
                            onChange={handleConfigChange('project')}
                            placeholder={t(`${I18N_PREFIX}.placeholder`, { key: t(`${I18N_PREFIX}.project`) })!}
                          />
                          <Field
                            label='Workspace'
                            labelClassName='!text-sm'
                            value={(config as OpikConfig).workspace}
                            onChange={handleConfigChange('workspace')}
                            placeholder={'default'}
                          />
                          <Field
                            label='Url'
                            labelClassName='!text-sm'
                            value={(config as OpikConfig).url}
                            onChange={handleConfigChange('url')}
                            placeholder={'https://www.comet.com/opik/api/'}
                          />
                        </>
                      )}
                    </div>
                    <div className='my-8 flex h-8 items-center justify-between'>
                      <a
                        className='flex items-center space-x-1 text-xs font-normal leading-[18px] text-[#155EEF]'
                        target='_blank'
                        href={docURL[type]}
                      >
                        <span>{t(`${I18N_PREFIX}.viewDocsLink`, { key: t(`app.tracing.${type}.title`) })}</span>
                        <LinkExternal02 className='h-3 w-3' />
                      </a>
                      <div className='flex items-center'>
                        {isEdit && (
                          <>
                            <Button
                              className='h-9 text-sm font-medium text-text-secondary'
                              onClick={showRemoveConfirm}
                            >
                              <span className='text-[#D92D20]'>{t('common.operation.remove')}</span>
                            </Button>
                            <Divider className='mx-3 h-[18px]' />
                          </>
                        )}
                        <Button
                          className='mr-2 h-9 text-sm font-medium text-text-secondary'
                          onClick={onCancel}
                        >
                          {t('common.operation.cancel')}
                        </Button>
                        <Button
                          className='h-9 text-sm font-medium'
                          variant='primary'
                          onClick={handleSave}
                          loading={isSaving}
                        >
                          {t(`common.operation.${isAdd ? 'saveAndEnable' : 'save'}`)}
                        </Button>
                      </div>
                    </div>
                  </div>
                  <div className='border-t-[0.5px] border-divider-regular'>
                    <div className='flex items-center justify-center bg-background-section-burn py-3 text-xs text-text-tertiary'>
                      <Lock01 className='mr-1 h-3 w-3 text-text-tertiary' />
                      {t('common.modelProvider.encrypted.front')}
                      <a
                        className='mx-1 text-primary-600'
                        target='_blank' rel='noopener noreferrer'
                        href='https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html'
                      >
                        PKCS1_OAEP
                      </a>
                      {t('common.modelProvider.encrypted.back')}
                    </div>
                  </div>
                </div>
              </div>
            </PortalToFollowElemContent>
          </PortalToFollowElem>
        )
        : (
          <Confirm
            isShow
            type='warning'
            title={t(`${I18N_PREFIX}.removeConfirmTitle`, { key: t(`app.tracing.${type}.title`) })!}
            content={t(`${I18N_PREFIX}.removeConfirmContent`)}
            onConfirm={handleRemove}
            onCancel={hideRemoveConfirm}
          />
        )}
    </>
  )
}
export default React.memo(ProviderConfigModal)
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-panel.tsx
New file
@@ -0,0 +1,104 @@
'use client'
import type { FC } from 'react'
import React, { useCallback } from 'react'
import {
  RiEqualizer2Line,
} from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { TracingProvider } from './type'
import cn from '@/utils/classnames'
import { LangfuseIconBig, LangsmithIconBig, OpikIconBig, WeaveIconBig } from '@/app/components/base/icons/src/public/tracing'
import { Eye as View } from '@/app/components/base/icons/src/vender/solid/general'
const I18N_PREFIX = 'app.tracing'
type Props = {
  type: TracingProvider
  readOnly: boolean
  isChosen: boolean
  config: any
  onChoose: () => void
  hasConfigured: boolean
  onConfig: () => void
}
const getIcon = (type: TracingProvider) => {
  return ({
    [TracingProvider.langSmith]: LangsmithIconBig,
    [TracingProvider.langfuse]: LangfuseIconBig,
    [TracingProvider.opik]: OpikIconBig,
    [TracingProvider.weave]: WeaveIconBig,
  })[type]
}
const ProviderPanel: FC<Props> = ({
  type,
  readOnly,
  isChosen,
  config,
  onChoose,
  hasConfigured,
  onConfig,
}) => {
  const { t } = useTranslation()
  const Icon = getIcon(type)
  const handleConfigBtnClick = useCallback((e: React.MouseEvent) => {
    e.stopPropagation()
    onConfig()
  }, [onConfig])
  const viewBtnClick = useCallback((e: React.MouseEvent) => {
    e.preventDefault()
    e.stopPropagation()
    const url = config?.project_url
    if (url)
      window.open(url, '_blank', 'noopener,noreferrer')
  }, [config?.project_url])
  const handleChosen = useCallback((e: React.MouseEvent) => {
    e.stopPropagation()
    if (isChosen || !hasConfigured || readOnly)
      return
    onChoose()
  }, [hasConfigured, isChosen, onChoose, readOnly])
  return (
    <div
      className={cn(
        'rounded-xl border-[1.5px] bg-background-section-burn px-4 py-3',
        isChosen ? 'border-components-option-card-option-selected-border bg-background-section' : 'border-transparent',
        !isChosen && hasConfigured && !readOnly && 'cursor-pointer',
      )}
      onClick={handleChosen}
    >
      <div className={'flex items-center justify-between space-x-1'}>
        <div className='flex items-center'>
          <Icon className='h-6' />
          {isChosen && <div className='system-2xs-medium-uppercase ml-1 flex h-4 items-center rounded-[4px] border border-text-accent-secondary px-1 text-text-accent-secondary'>{t(`${I18N_PREFIX}.inUse`)}</div>}
        </div>
        {!readOnly && (
          <div className={'flex items-center justify-between space-x-1'}>
            {hasConfigured && (
              <div className='flex h-6 cursor-pointer items-center space-x-1 rounded-md border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-2 text-text-secondary shadow-xs' onClick={viewBtnClick} >
                <View className='h-3 w-3' />
                <div className='text-xs font-medium'>{t(`${I18N_PREFIX}.view`)}</div>
              </div>
            )}
            <div
              className='flex h-6 cursor-pointer items-center space-x-1 rounded-md border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-2 text-text-secondary shadow-xs'
              onClick={handleConfigBtnClick}
            >
              <RiEqualizer2Line className='h-3 w-3' />
              <div className='text-xs font-medium'>{t(`${I18N_PREFIX}.config`)}</div>
            </div>
          </div>
        )}
      </div>
      <div className='system-xs-regular mt-2 text-text-tertiary'>
        {t(`${I18N_PREFIX}.${type}.description`)}
      </div>
    </div>
  )
}
export default React.memo(ProviderPanel)
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/tracing-icon.tsx
New file
@@ -0,0 +1,28 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import cn from '@/utils/classnames'
import { TracingIcon as Icon } from '@/app/components/base/icons/src/public/tracing'
type Props = {
  className?: string
  size: 'lg' | 'md'
}
const sizeClassMap = {
  lg: 'w-9 h-9 p-2 rounded-[10px]',
  md: 'w-6 h-6 p-1 rounded-lg',
}
const TracingIcon: FC<Props> = ({
  className,
  size,
}) => {
  const sizeClass = sizeClassMap[size]
  return (
    <div className={cn(className, sizeClass, 'bg-primary-500 shadow-md')}>
      <Icon className='h-full w-full' />
    </div>
  )
}
export default React.memo(TracingIcon)
app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/type.ts
New file
@@ -0,0 +1,32 @@
export enum TracingProvider {
  langSmith = 'langsmith',
  langfuse = 'langfuse',
  opik = 'opik',
  weave = 'weave',
}
export type LangSmithConfig = {
  api_key: string
  project: string
  endpoint: string
}
export type LangFuseConfig = {
  public_key: string
  secret_key: string
  host: string
}
export type OpikConfig = {
  api_key: string
  project: string
  workspace: string
  url: string
}
export type WeaveConfig = {
  api_key: string
  entity: string
  project: string
  endpoint: string
}
app/(commonLayout)/app/(appDetailLayout)/[appId]/style.module.css
New file
@@ -0,0 +1,6 @@
.app {
    flex-grow: 1;
    height: 0;
    border-radius: 16px 16px 0px 0px;
    box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.05), 0px 0px 2px -1px rgba(0, 0, 0, 0.03);
}
app/(commonLayout)/app/(appDetailLayout)/[appId]/workflow/page.tsx
New file
@@ -0,0 +1,12 @@
'use client'
import WorkflowApp from '@/app/components/workflow-app'
const Page = () => {
  return (
    <div className='h-full w-full overflow-x-auto'>
      <WorkflowApp />
    </div>
  )
}
export default Page
app/(commonLayout)/app/(appDetailLayout)/layout.tsx
New file
@@ -0,0 +1,28 @@
'use client'
import type { FC } from 'react'
import React, { useEffect } from 'react'
import { useRouter } from 'next/navigation'
import { useAppContext } from '@/context/app-context'
export type IAppDetail = {
  children: React.ReactNode
}
const AppDetail: FC<IAppDetail> = ({ children }) => {
  const router = useRouter()
  const { isCurrentWorkspaceDatasetOperator } = useAppContext()
  useEffect(() => {
    if (isCurrentWorkspaceDatasetOperator)
      return router.replace('/datasets')
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isCurrentWorkspaceDatasetOperator])
  return (
    <>
      {children}
    </>
  )
}
export default React.memo(AppDetail)
app/(commonLayout)/apps/AppCard.tsx
New file
@@ -0,0 +1,426 @@
'use client'
import { useContext, useContextSelector } from 'use-context-selector'
import { useRouter } from 'next/navigation'
import { useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiMoreFill } from '@remixicon/react'
import type { App } from '@/types/app'
import Confirm from '@/app/components/base/confirm'
import Toast, { ToastContext } from '@/app/components/base/toast'
import { copyApp, deleteApp, exportAppConfig, updateAppInfo } from '@/service/apps'
import DuplicateAppModal from '@/app/components/app/duplicate-modal'
import type { DuplicateAppModalProps } from '@/app/components/app/duplicate-modal'
import AppIcon from '@/app/components/base/app-icon'
import AppsContext, { useAppContext } from '@/context/app-context'
import type { HtmlContentProps } from '@/app/components/base/popover'
import CustomPopover from '@/app/components/base/popover'
import Divider from '@/app/components/base/divider'
import { WEB_PREFIX } from '@/config'
import { getRedirection } from '@/utils/app-redirection'
import { useProviderContext } from '@/context/provider-context'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import type { CreateAppModalProps } from '@/app/components/explore/create-app-modal'
import EditAppModal from '@/app/components/explore/create-app-modal'
import SwitchAppModal from '@/app/components/app/switch-app-modal'
import type { Tag } from '@/app/components/base/tag-management/constant'
import TagSelector from '@/app/components/base/tag-management/selector'
import type { EnvironmentVariable } from '@/app/components/workflow/types'
import DSLExportConfirmModal from '@/app/components/workflow/dsl-export-confirm-modal'
import { fetchWorkflowDraft } from '@/service/workflow'
import { fetchInstalledAppList } from '@/service/explore'
import { AppTypeIcon } from '@/app/components/app/type-selector'
import cn from '@/utils/classnames'
export type AppCardProps = {
  app: App
  onRefresh?: () => void
}
const AppCard = ({ app, onRefresh }: AppCardProps) => {
  const { t } = useTranslation()
  const { notify } = useContext(ToastContext)
  const { isCurrentWorkspaceEditor } = useAppContext()
  const { onPlanInfoChanged } = useProviderContext()
  const { push } = useRouter()
  const mutateApps = useContextSelector(
    AppsContext,
    state => state.mutateApps,
  )
  const [showEditModal, setShowEditModal] = useState(false)
  const [showDuplicateModal, setShowDuplicateModal] = useState(false)
  const [showSwitchModal, setShowSwitchModal] = useState<boolean>(false)
  const [showConfirmDelete, setShowConfirmDelete] = useState(false)
  const [secretEnvList, setSecretEnvList] = useState<EnvironmentVariable[]>([])
  const onConfirmDelete = useCallback(async () => {
    try {
      await deleteApp(app.id)
      notify({ type: 'success', message: t('app.appDeleted') })
      if (onRefresh)
        onRefresh()
      mutateApps()
      onPlanInfoChanged()
    }
    catch (e: any) {
      notify({
        type: 'error',
        message: `${t('app.appDeleteFailed')}${'message' in e ? `: ${e.message}` : ''}`,
      })
    }
    setShowConfirmDelete(false)
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [app.id])
  const onEdit: CreateAppModalProps['onConfirm'] = useCallback(async ({
    name,
    icon_type,
    icon,
    icon_background,
    description,
    use_icon_as_answer_icon,
  }) => {
    try {
      await updateAppInfo({
        appID: app.id,
        name,
        icon_type,
        icon,
        icon_background,
        description,
        use_icon_as_answer_icon,
      })
      setShowEditModal(false)
      notify({
        type: 'success',
        message: t('app.editDone'),
      })
      if (onRefresh)
        onRefresh()
      mutateApps()
    }
    catch {
      notify({ type: 'error', message: t('app.editFailed') })
    }
  }, [app.id, mutateApps, notify, onRefresh, t])
  const onCopy: DuplicateAppModalProps['onConfirm'] = async ({ name, icon_type, icon, icon_background }) => {
    try {
      const newApp = await copyApp({
        appID: app.id,
        name,
        icon_type,
        icon,
        icon_background,
        mode: app.mode,
      })
      setShowDuplicateModal(false)
      notify({
        type: 'success',
        message: t('app.newApp.appCreated'),
      })
      localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
      if (onRefresh)
        onRefresh()
      mutateApps()
      onPlanInfoChanged()
      getRedirection(isCurrentWorkspaceEditor, newApp, push)
    }
    catch {
      notify({ type: 'error', message: t('app.newApp.appCreateFailed') })
    }
  }
  const onExport = async (include = false) => {
    try {
      const { data } = await exportAppConfig({
        appID: app.id,
        include,
      })
      const a = document.createElement('a')
      const file = new Blob([data], { type: 'application/yaml' })
      a.href = URL.createObjectURL(file)
      a.download = `${app.name}.yml`
      a.click()
    }
    catch {
      notify({ type: 'error', message: t('app.exportFailed') })
    }
  }
  const exportCheck = async () => {
    if (app.mode !== 'workflow' && app.mode !== 'advanced-chat') {
      onExport()
      return
    }
    try {
      const workflowDraft = await fetchWorkflowDraft(`/apps/${app.id}/workflows/draft`)
      const list = (workflowDraft.environment_variables || []).filter(env => env.value_type === 'secret')
      if (list.length === 0) {
        onExport()
        return
      }
      setSecretEnvList(list)
    }
    catch {
      notify({ type: 'error', message: t('app.exportFailed') })
    }
  }
  const onSwitch = () => {
    if (onRefresh)
      onRefresh()
    mutateApps()
    setShowSwitchModal(false)
  }
  const Operations = (props: HtmlContentProps) => {
    const onMouseLeave = async () => {
      props.onClose?.()
    }
    const onClickSettings = async (e: React.MouseEvent<HTMLButtonElement>) => {
      e.stopPropagation()
      props.onClick?.()
      e.preventDefault()
      setShowEditModal(true)
    }
    const onClickDuplicate = async (e: React.MouseEvent<HTMLButtonElement>) => {
      e.stopPropagation()
      props.onClick?.()
      e.preventDefault()
      setShowDuplicateModal(true)
    }
    const onClickExport = async (e: React.MouseEvent<HTMLButtonElement>) => {
      e.stopPropagation()
      props.onClick?.()
      e.preventDefault()
      exportCheck()
    }
    const onClickSwitch = async (e: React.MouseEvent<HTMLDivElement>) => {
      e.stopPropagation()
      props.onClick?.()
      e.preventDefault()
      setShowSwitchModal(true)
    }
    const onClickDelete = async (e: React.MouseEvent<HTMLDivElement>) => {
      e.stopPropagation()
      props.onClick?.()
      e.preventDefault()
      setShowConfirmDelete(true)
    }
    const onClickInstalledApp = async (e: React.MouseEvent<HTMLButtonElement>) => {
      e.stopPropagation()
      props.onClick?.()
      e.preventDefault()
      try {
        const { installed_apps }: any = await fetchInstalledAppList(app.id) || {}
        if (installed_apps?.length > 0)
          window.open(`${WEB_PREFIX}/explore/installed/${installed_apps[0].id}`, '_blank')
        else
          throw new Error('No app found in Explore')
      }
      catch (e: any) {
        Toast.notify({ type: 'error', message: `${e.message || e}` })
      }
    }
    return (
      <div className="relative w-full py-1" onMouseLeave={onMouseLeave}>
        <button className='mx-1 flex h-8 w-[calc(100%_-_8px)] cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-state-base-hover' onClick={onClickSettings}>
          <span className='system-sm-regular text-text-secondary'>{t('app.editApp')}</span>
        </button>
        <Divider className="!my-1" />
        <button className='mx-1 flex h-8 w-[calc(100%_-_8px)] cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-state-base-hover' onClick={onClickDuplicate}>
          <span className='system-sm-regular text-text-secondary'>{t('app.duplicate')}</span>
        </button>
        <button className='mx-1 flex h-8 w-[calc(100%_-_8px)] cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-state-base-hover' onClick={onClickExport}>
          <span className='system-sm-regular text-text-secondary'>{t('app.export')}</span>
        </button>
        {(app.mode === 'completion' || app.mode === 'chat') && (
          <>
            <Divider className="!my-1" />
            <div
              className='mx-1 flex h-9 cursor-pointer items-center rounded-lg px-3 py-2 hover:bg-state-base-hover'
              onClick={onClickSwitch}
            >
              <span className='text-sm leading-5 text-text-secondary'>{t('app.switch')}</span>
            </div>
          </>
        )}
        <Divider className="!my-1" />
        <button className='mx-1 flex h-8 w-[calc(100%_-_8px)] cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-state-base-hover' onClick={onClickInstalledApp}>
          <span className='system-sm-regular text-text-secondary'>{t('app.openInExplore')}</span>
        </button>
        <Divider className="!my-1" />
        <div
          className='group mx-1 flex h-8 w-[calc(100%_-_8px)] cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-state-destructive-hover'
          onClick={onClickDelete}
        >
          <span className='system-sm-regular text-text-secondary group-hover:text-text-destructive'>
            {t('common.operation.delete')}
          </span>
        </div>
      </div>
    )
  }
  const [tags, setTags] = useState<Tag[]>(app.tags)
  useEffect(() => {
    setTags(app.tags)
  }, [app.tags])
  return (
    <>
      <div
        onClick={(e) => {
          e.preventDefault()
          getRedirection(isCurrentWorkspaceEditor, app, push)
        }}
        className='group relative col-span-1 inline-flex h-[160px] cursor-pointer flex-col rounded-xl border-[1px] border-solid border-components-card-border bg-components-card-bg shadow-sm transition-all duration-200 ease-in-out hover:shadow-lg'
      >
        <div className='flex h-[66px] shrink-0 grow-0 items-center gap-3 px-[14px] pb-3 pt-[14px]'>
          <div className='relative shrink-0'>
            <AppIcon
              size="large"
              iconType={app.icon_type}
              icon={app.icon}
              background={app.icon_background}
              imageUrl={app.icon_url}
            />
            <AppTypeIcon type={app.mode} wrapperClassName='absolute -bottom-0.5 -right-0.5 w-4 h-4 shadow-sm' className='h-3 w-3' />
          </div>
          <div className='w-0 grow py-[1px]'>
            <div className='flex items-center text-sm font-semibold leading-5 text-text-secondary'>
              <div className='truncate' title={app.name}>{app.name}</div>
            </div>
            <div className='flex items-center text-[10px] font-medium leading-[18px] text-text-tertiary'>
              {app.mode === 'advanced-chat' && <div className='truncate'>{t('app.types.advanced').toUpperCase()}</div>}
              {app.mode === 'chat' && <div className='truncate'>{t('app.types.chatbot').toUpperCase()}</div>}
              {app.mode === 'agent-chat' && <div className='truncate'>{t('app.types.agent').toUpperCase()}</div>}
              {app.mode === 'workflow' && <div className='truncate'>{t('app.types.workflow').toUpperCase()}</div>}
              {app.mode === 'completion' && <div className='truncate'>{t('app.types.completion').toUpperCase()}</div>}
            </div>
          </div>
        </div>
        <div className='title-wrapper h-[90px] px-[14px] text-xs leading-normal text-text-tertiary'>
          <div
            className={cn(tags.length ? 'line-clamp-2' : 'line-clamp-4', 'group-hover:line-clamp-2')}
            title={app.description}
          >
            {app.description}
          </div>
        </div>
        <div className={cn(
          'absolute bottom-1 left-0 right-0 h-[42px] shrink-0 items-center pb-[6px] pl-[14px] pr-[6px] pt-1',
          tags.length ? 'flex' : '!hidden group-hover:!flex',
        )}>
          {isCurrentWorkspaceEditor && (
            <>
              <div className={cn('flex w-0 grow items-center gap-1')} onClick={(e) => {
                e.stopPropagation()
                e.preventDefault()
              }}>
                <div className={cn(
                  'mr-[41px] w-full grow group-hover:!mr-0 group-hover:!block',
                  tags.length ? '!block' : '!hidden',
                )}>
                  <TagSelector
                    position='bl'
                    type='app'
                    targetID={app.id}
                    value={tags.map(tag => tag.id)}
                    selectedTags={tags}
                    onCacheUpdate={setTags}
                    onChange={onRefresh}
                  />
                </div>
              </div>
              <div className='mx-1 !hidden h-[14px] w-[1px] shrink-0 group-hover:!flex' />
              <div className='!hidden shrink-0 group-hover:!flex'>
                <CustomPopover
                  htmlContent={<Operations />}
                  position="br"
                  trigger="click"
                  btnElement={
                    <div
                      className='flex h-8 w-8 cursor-pointer items-center justify-center rounded-md'
                    >
                      <RiMoreFill className='h-4 w-4 text-text-tertiary' />
                    </div>
                  }
                  btnClassName={open =>
                    cn(
                      open ? '!bg-black/5 !shadow-none' : '!bg-transparent',
                      'h-8 w-8 rounded-md border-none !p-2 hover:!bg-black/5',
                    )
                  }
                  popupClassName={
                    (app.mode === 'completion' || app.mode === 'chat')
                      ? '!w-[256px] translate-x-[-224px]'
                      : '!w-[160px] translate-x-[-128px]'
                  }
                  className={'!z-20 h-fit'}
                />
              </div>
            </>
          )}
        </div>
      </div>
      {showEditModal && (
        <EditAppModal
          isEditModal
          appName={app.name}
          appIconType={app.icon_type}
          appIcon={app.icon}
          appIconBackground={app.icon_background}
          appIconUrl={app.icon_url}
          appDescription={app.description}
          appMode={app.mode}
          appUseIconAsAnswerIcon={app.use_icon_as_answer_icon}
          show={showEditModal}
          onConfirm={onEdit}
          onHide={() => setShowEditModal(false)}
        />
      )}
      {showDuplicateModal && (
        <DuplicateAppModal
          appName={app.name}
          icon_type={app.icon_type}
          icon={app.icon}
          icon_background={app.icon_background}
          icon_url={app.icon_url}
          show={showDuplicateModal}
          onConfirm={onCopy}
          onHide={() => setShowDuplicateModal(false)}
        />
      )}
      {showSwitchModal && (
        <SwitchAppModal
          show={showSwitchModal}
          appDetail={app}
          onClose={() => setShowSwitchModal(false)}
          onSuccess={onSwitch}
        />
      )}
      {showConfirmDelete && (
        <Confirm
          title={t('app.deleteAppConfirmTitle')}
          content={t('app.deleteAppConfirmContent')}
          isShow={showConfirmDelete}
          onConfirm={onConfirmDelete}
          onCancel={() => setShowConfirmDelete(false)}
        />
      )}
      {secretEnvList.length > 0 && (
        <DSLExportConfirmModal
          envList={secretEnvList}
          onConfirm={onExport}
          onClose={() => setSecretEnvList([])}
        />
      )}
    </>
  )
}
export default AppCard
app/(commonLayout)/apps/Apps.tsx
New file
@@ -0,0 +1,219 @@
'use client'
import { useCallback, useEffect, useRef, useState } from 'react'
import {
  useRouter,
} from 'next/navigation'
import useSWRInfinite from 'swr/infinite'
import { useTranslation } from 'react-i18next'
import { useDebounceFn } from 'ahooks'
import {
  RiApps2Line,
  RiExchange2Line,
  RiFile4Line,
  RiMessage3Line,
  RiRobot3Line,
} from '@remixicon/react'
import AppCard from './AppCard'
import NewAppCard from './NewAppCard'
import useAppsQueryState from './hooks/useAppsQueryState'
import type { AppListResponse } from '@/models/app'
import { fetchAppList } from '@/service/apps'
import { useAppContext } from '@/context/app-context'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import { CheckModal } from '@/hooks/use-pay'
import TabSliderNew from '@/app/components/base/tab-slider-new'
import { useTabSearchParams } from '@/hooks/use-tab-searchparams'
import Input from '@/app/components/base/input'
import { useStore as useTagStore } from '@/app/components/base/tag-management/store'
import TagManagementModal from '@/app/components/base/tag-management'
import TagFilter from '@/app/components/base/tag-management/filter'
import CheckboxWithLabel from '@/app/components/datasets/create/website/base/checkbox-with-label'
const getKey = (
  pageIndex: number,
  previousPageData: AppListResponse,
  activeTab: string,
  isCreatedByMe: boolean,
  tags: string[],
  keywords: string,
) => {
  if (!pageIndex || previousPageData.has_more) {
    const params: any = { url: 'apps', params: { page: pageIndex + 1, limit: 30, name: keywords, is_created_by_me: isCreatedByMe } }
    if (activeTab !== 'all')
      params.params.mode = activeTab
    else
      delete params.params.mode
    if (tags.length)
      params.params.tag_ids = tags
    return params
  }
  return null
}
const Apps = () => {
  const { t } = useTranslation()
  const router = useRouter()
  const { isCurrentWorkspaceEditor, isCurrentWorkspaceDatasetOperator } = useAppContext()
  const showTagManagementModal = useTagStore(s => s.showTagManagementModal)
  const [activeTab, setActiveTab] = useTabSearchParams({
    defaultTab: 'all',
  })
  const { query: { tagIDs = [], keywords = '', isCreatedByMe: queryIsCreatedByMe = false }, setQuery } = useAppsQueryState()
  const [isCreatedByMe, setIsCreatedByMe] = useState(queryIsCreatedByMe)
  const [tagFilterValue, setTagFilterValue] = useState<string[]>(tagIDs)
  const [searchKeywords, setSearchKeywords] = useState(keywords)
  const newAppCardRef = useRef<HTMLDivElement>(null)
  const setKeywords = useCallback((keywords: string) => {
    setQuery(prev => ({ ...prev, keywords }))
  }, [setQuery])
  const setTagIDs = useCallback((tagIDs: string[]) => {
    setQuery(prev => ({ ...prev, tagIDs }))
  }, [setQuery])
  const { data, isLoading, error, setSize, mutate } = useSWRInfinite(
    (pageIndex: number, previousPageData: AppListResponse) => getKey(pageIndex, previousPageData, activeTab, isCreatedByMe, tagIDs, searchKeywords),
    fetchAppList,
    {
      revalidateFirstPage: true,
      shouldRetryOnError: false,
      dedupingInterval: 500,
      errorRetryCount: 3,
    },
  )
  const anchorRef = useRef<HTMLDivElement>(null)
  const options = [
    { value: 'all', text: t('app.types.all'), icon: <RiApps2Line className='mr-1 h-[14px] w-[14px]' /> },
    { value: 'chat', text: t('app.types.chatbot'), icon: <RiMessage3Line className='mr-1 h-[14px] w-[14px]' /> },
    { value: 'agent-chat', text: t('app.types.agent'), icon: <RiRobot3Line className='mr-1 h-[14px] w-[14px]' /> },
    { value: 'completion', text: t('app.types.completion'), icon: <RiFile4Line className='mr-1 h-[14px] w-[14px]' /> },
    { value: 'advanced-chat', text: t('app.types.advanced'), icon: <RiMessage3Line className='mr-1 h-[14px] w-[14px]' /> },
    { value: 'workflow', text: t('app.types.workflow'), icon: <RiExchange2Line className='mr-1 h-[14px] w-[14px]' /> },
  ]
  useEffect(() => {
    document.title = `${t('common.menus.apps')} - Dify`
    if (localStorage.getItem(NEED_REFRESH_APP_LIST_KEY) === '1') {
      localStorage.removeItem(NEED_REFRESH_APP_LIST_KEY)
      mutate()
    }
  }, [mutate, t])
  useEffect(() => {
    if (isCurrentWorkspaceDatasetOperator)
      return router.replace('/datasets')
  }, [router, isCurrentWorkspaceDatasetOperator])
  useEffect(() => {
    const hasMore = data?.at(-1)?.has_more ?? true
    let observer: IntersectionObserver | undefined
    if (error) {
      if (observer)
        observer.disconnect()
      return
    }
    if (anchorRef.current) {
      observer = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting && !isLoading && !error && hasMore)
          setSize((size: number) => size + 1)
      }, { rootMargin: '100px' })
      observer.observe(anchorRef.current)
    }
    return () => observer?.disconnect()
  }, [isLoading, setSize, anchorRef, mutate, data, error])
  const { run: handleSearch } = useDebounceFn(() => {
    setSearchKeywords(keywords)
  }, { wait: 500 })
  const handleKeywordsChange = (value: string) => {
    setKeywords(value)
    handleSearch()
  }
  const { run: handleTagsUpdate } = useDebounceFn(() => {
    setTagIDs(tagFilterValue)
  }, { wait: 500 })
  const handleTagsChange = (value: string[]) => {
    setTagFilterValue(value)
    handleTagsUpdate()
  }
  const handleCreatedByMeChange = useCallback(() => {
    const newValue = !isCreatedByMe
    setIsCreatedByMe(newValue)
    setQuery(prev => ({ ...prev, isCreatedByMe: newValue }))
  }, [isCreatedByMe, setQuery])
  return (
    <>
      <div className='sticky top-0 z-10 flex flex-wrap items-center justify-between gap-y-2 bg-background-body px-12 pb-2 pt-4 leading-[56px]'>
        <TabSliderNew
          value={activeTab}
          onChange={setActiveTab}
          options={options}
        />
        <div className='flex items-center gap-2'>
          <CheckboxWithLabel
            className='mr-2'
            label={t('app.showMyCreatedAppsOnly')}
            isChecked={isCreatedByMe}
            onChange={handleCreatedByMeChange}
          />
          <TagFilter type='app' value={tagFilterValue} onChange={handleTagsChange} />
          <Input
            showLeftIcon
            showClearIcon
            wrapperClassName='w-[200px]'
            value={keywords}
            onChange={e => handleKeywordsChange(e.target.value)}
            onClear={() => handleKeywordsChange('')}
          />
        </div>
      </div>
      {(data && data[0].total > 0)
        ? <div className='relative grid grow grid-cols-1 content-start gap-4 px-12 pt-2 sm:grid-cols-1 md:grid-cols-2 xl:grid-cols-4 2xl:grid-cols-5 2k:grid-cols-6'>
          {isCurrentWorkspaceEditor
            && <NewAppCard ref={newAppCardRef} onSuccess={mutate} />}
          {data.map(({ data: apps }) => apps.map(app => (
            <AppCard key={app.id} app={app} onRefresh={mutate} />
          )))}
        </div>
        : <div className='relative grid grow grid-cols-1 content-start gap-4 overflow-hidden px-12 pt-2 sm:grid-cols-1 md:grid-cols-2 xl:grid-cols-4 2xl:grid-cols-5 2k:grid-cols-6'>
          {isCurrentWorkspaceEditor
            && <NewAppCard ref={newAppCardRef} className='z-10' onSuccess={mutate} />}
          <NoAppsFound />
        </div>}
      <CheckModal />
      <div ref={anchorRef} className='h-0'> </div>
      {showTagManagementModal && (
        <TagManagementModal type='app' show={showTagManagementModal} />
      )}
    </>
  )
}
export default Apps
function NoAppsFound() {
  const { t } = useTranslation()
  function renderDefaultCard() {
    const defaultCards = Array.from({ length: 36 }, (_, index) => (
      <div key={index} className='inline-flex h-[160px] rounded-xl bg-background-default-lighter'></div>
    ))
    return defaultCards
  }
  return (
    <>
      {renderDefaultCard()}
      <div className='absolute bottom-0 left-0 right-0 top-0 flex items-center justify-center bg-gradient-to-t from-background-body to-transparent'>
        <span className='system-md-medium text-text-tertiary'>{t('app.newApp.noAppsFound')}</span>
      </div>
    </>
  )
}
app/(commonLayout)/apps/NewAppCard.tsx
New file
@@ -0,0 +1,118 @@
'use client'
import { useMemo, useState } from 'react'
import {
  useRouter,
  useSearchParams,
} from 'next/navigation'
import { useTranslation } from 'react-i18next'
import CreateAppTemplateDialog from '@/app/components/app/create-app-dialog'
import CreateAppModal from '@/app/components/app/create-app-modal'
import CreateFromDSLModal, { CreateFromDSLModalTab } from '@/app/components/app/create-from-dsl-modal'
import { useProviderContext } from '@/context/provider-context'
import { FileArrow01, FilePlus01, FilePlus02 } from '@/app/components/base/icons/src/vender/line/files'
import cn from '@/utils/classnames'
export type CreateAppCardProps = {
  className?: string
  onSuccess?: () => void
}
const CreateAppCard = (
  {
    ref,
    className,
    onSuccess,
  }: CreateAppCardProps & {
    ref: React.RefObject<HTMLDivElement>;
  },
) => {
  const { t } = useTranslation()
  const { onPlanInfoChanged } = useProviderContext()
  const searchParams = useSearchParams()
  const { replace } = useRouter()
  const dslUrl = searchParams.get('remoteInstallUrl') || undefined
  const [showNewAppTemplateDialog, setShowNewAppTemplateDialog] = useState(false)
  const [showNewAppModal, setShowNewAppModal] = useState(false)
  const [showCreateFromDSLModal, setShowCreateFromDSLModal] = useState(!!dslUrl)
  const activeTab = useMemo(() => {
    if (dslUrl)
      return CreateFromDSLModalTab.FROM_URL
    return undefined
  }, [dslUrl])
  return (
    <div
      ref={ref}
      className={cn('relative col-span-1 inline-flex h-[160px] flex-col justify-between rounded-xl border-[0.5px] border-components-card-border bg-components-card-bg', className)}
    >
      <div className='grow rounded-t-xl p-2'>
        <div className='px-6 pb-1 pt-2 text-xs font-medium leading-[18px] text-text-tertiary'>{t('app.createApp')}</div>
        <button className='mb-1 flex w-full cursor-pointer items-center rounded-lg px-6 py-[7px] text-[13px] font-medium leading-[18px] text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary' onClick={() => setShowNewAppModal(true)}>
          <FilePlus01 className='mr-2 h-4 w-4 shrink-0' />
          {t('app.newApp.startFromBlank')}
        </button>
        <button className='flex w-full cursor-pointer items-center rounded-lg px-6 py-[7px] text-[13px] font-medium leading-[18px] text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary' onClick={() => setShowNewAppTemplateDialog(true)}>
          <FilePlus02 className='mr-2 h-4 w-4 shrink-0' />
          {t('app.newApp.startFromTemplate')}
        </button>
        <button
          onClick={() => setShowCreateFromDSLModal(true)}
          className='flex w-full cursor-pointer items-center rounded-lg px-6 py-[7px] text-[13px] font-medium leading-[18px] text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary'>
          <FileArrow01 className='mr-2 h-4 w-4 shrink-0' />
          {t('app.importDSL')}
        </button>
      </div>
      <CreateAppModal
        show={showNewAppModal}
        onClose={() => setShowNewAppModal(false)}
        onSuccess={() => {
          onPlanInfoChanged()
          if (onSuccess)
            onSuccess()
        }}
        onCreateFromTemplate={() => {
          setShowNewAppTemplateDialog(true)
          setShowNewAppModal(false)
        }}
      />
      <CreateAppTemplateDialog
        show={showNewAppTemplateDialog}
        onClose={() => setShowNewAppTemplateDialog(false)}
        onSuccess={() => {
          onPlanInfoChanged()
          if (onSuccess)
            onSuccess()
        }}
        onCreateFromBlank={() => {
          setShowNewAppModal(true)
          setShowNewAppTemplateDialog(false)
        }}
      />
      <CreateFromDSLModal
        show={showCreateFromDSLModal}
        onClose={() => {
          setShowCreateFromDSLModal(false)
          if (dslUrl)
            replace('/')
        }}
        activeTab={activeTab}
        dslUrl={dslUrl}
        onSuccess={() => {
          onPlanInfoChanged()
          if (onSuccess)
            onSuccess()
        }}
      />
    </div>
  )
}
CreateAppCard.displayName = 'CreateAppCard'
export default CreateAppCard
export { CreateAppCard }
app/(commonLayout)/apps/assets/add.svg
New file
@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 4V8M8 8V12M8 8H12M8 8H4" stroke="#6B7280" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
app/(commonLayout)/apps/assets/chat-solid.svg
New file
@@ -0,0 +1,4 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.631586 8.25C0.631586 6.46656 2.04586 5 3.8158 5C5.58573 5 7.00001 6.46656 7.00001 8.25C7.00001 10.0334 5.58573 11.5 3.8158 11.5C3.45197 11.5 3.10149 11.4375 2.77474 11.3222C2.72073 11.3031 2.68723 11.2913 2.66266 11.2832C2.65821 11.2817 2.65456 11.2806 2.65164 11.2796L2.64892 11.2799C2.63177 11.2818 2.60839 11.285 2.56507 11.2909L1.06766 11.4954C0.905637 11.5175 0.743029 11.459 0.632239 11.3387C0.521449 11.2185 0.476481 11.0516 0.511825 10.8919L0.817497 9.51109C0.828118 9.46311 0.833802 9.43722 0.837453 9.41817C0.83766 9.4171 0.838022 9.41517 0.838022 9.41517C0.837114 9.412 0.835963 9.40808 0.834525 9.40332C0.826292 9.37605 0.814183 9.33888 0.794499 9.27863C0.688657 8.95463 0.631586 8.60857 0.631586 8.25Z" fill="#98A2B3"/>
<path d="M2.57377 4.1863C2.96256 4.06535 3.37698 4 3.80894 4C6.16566 4 8.00006 5.94534 8.00006 8.24999C8.00006 8.65682 7.9429 9.05245 7.8358 9.42816C8.10681 9.37948 8.36964 9.30678 8.6219 9.21229C8.65748 9.19897 8.69298 9.18534 8.72893 9.17304C8.75795 9.17641 8.78684 9.18093 8.81574 9.18517L10.4222 9.42065C10.498 9.43179 10.5841 9.44444 10.6591 9.4487C10.7422 9.45343 10.8713 9.45292 11.0081 9.39408C11.1789 9.32061 11.3164 9.18628 11.3938 9.01716C11.4558 8.88174 11.4593 8.75269 11.4564 8.66955C11.4539 8.59442 11.4433 8.5081 11.4339 8.43202L11.2309 6.78307C11.2256 6.7402 11.2229 6.71768 11.2213 6.70118C11.23 6.66505 11.2466 6.6301 11.2598 6.59546C11.4492 6.09896 11.5526 5.56093 11.5526 5C11.5526 2.51163 9.52304 0.5 7.02632 0.5C4.80843 0.5 2.95915 2.08742 2.57377 4.1863Z" fill="#98A2B3"/>
</svg>
app/(commonLayout)/apps/assets/chat.svg
New file
@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.1667 6.66634H15.8333C16.2754 6.66634 16.6993 6.84194 17.0118 7.1545C17.3244 7.46706 17.5 7.89098 17.5 8.33301V13.333C17.5 13.775 17.3244 14.199 17.0118 14.5115C16.6993 14.8241 16.2754 14.9997 15.8333 14.9997H14.1667V18.333L10.8333 14.9997H7.5C7.28111 14.9999 7.06433 14.9569 6.86211 14.8731C6.6599 14.7893 6.47623 14.6663 6.32167 14.5113M6.32167 14.5113L9.16667 11.6663H12.5C12.942 11.6663 13.366 11.4907 13.6785 11.1782C13.9911 10.8656 14.1667 10.4417 14.1667 9.99967V4.99967C14.1667 4.55765 13.9911 4.13372 13.6785 3.82116C13.366 3.5086 12.942 3.33301 12.5 3.33301H4.16667C3.72464 3.33301 3.30072 3.5086 2.98816 3.82116C2.67559 4.13372 2.5 4.55765 2.5 4.99967V9.99967C2.5 10.4417 2.67559 10.8656 2.98816 11.1782C3.30072 11.4907 3.72464 11.6663 4.16667 11.6663H5.83333V14.9997L6.32167 14.5113Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
app/(commonLayout)/apps/assets/completion-solid.svg
New file
@@ -0,0 +1,4 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.5 1.00779C6.5 0.994638 6.5 0.988062 6.49943 0.976137C6.48764 0.729248 6.27052 0.51224 6.02363 0.50056C6.01171 0.499996 6.0078 0.499998 6.00001 0.5H4.37933C3.97686 0.499995 3.64468 0.49999 3.37409 0.522098C3.09304 0.545061 2.83469 0.594343 2.59202 0.717989C2.2157 0.909735 1.90973 1.2157 1.71799 1.59202C1.59434 1.83469 1.54506 2.09304 1.5221 2.37409C1.49999 2.64468 1.49999 2.97686 1.5 3.37934V8.62066C1.49999 9.02313 1.49999 9.35532 1.5221 9.62591C1.54506 9.90696 1.59434 10.1653 1.71799 10.408C1.90973 10.7843 2.2157 11.0903 2.59202 11.282C2.83469 11.4057 3.09304 11.4549 3.37409 11.4779C3.64468 11.5 3.97686 11.5 4.37934 11.5H7.62066C8.02314 11.5 8.35532 11.5 8.62591 11.4779C8.90696 11.4549 9.16531 11.4057 9.40798 11.282C9.78431 11.0903 10.0903 10.7843 10.282 10.408C10.4057 10.1653 10.4549 9.90696 10.4779 9.62591C10.5 9.35532 10.5 9.02314 10.5 8.62066V4.99997C10.5 4.9922 10.5 4.98832 10.4994 4.97641C10.4878 4.72949 10.2707 4.51236 10.0238 4.50057C10.0119 4.50001 10.0054 4.50001 9.99225 4.50001L7.78404 4.50001C7.65786 4.50002 7.53496 4.50004 7.43089 4.49153C7.31659 4.48219 7.18172 4.46016 7.04601 4.39101C6.85785 4.29514 6.70487 4.14216 6.609 3.954C6.53985 3.81828 6.51781 3.68342 6.50848 3.56912C6.49997 3.46504 6.49999 3.34215 6.5 3.21596L6.5 1.00779ZM4 6.5C3.72386 6.5 3.5 6.72386 3.5 7C3.5 7.27614 3.72386 7.5 4 7.5H8C8.27614 7.5 8.5 7.27614 8.5 7C8.5 6.72386 8.27614 6.5 8 6.5H4ZM4 8.5C3.72386 8.5 3.5 8.72386 3.5 9C3.5 9.27614 3.72386 9.5 4 9.5H7C7.27614 9.5 7.5 9.27614 7.5 9C7.5 8.72386 7.27614 8.5 7 8.5H4Z" fill="#98A2B3"/>
<path d="M9.45398 3.5C9.60079 3.5 9.67419 3.5 9.73432 3.46314C9.81925 3.41107 9.87002 3.28842 9.84674 3.19157C9.83025 3.12299 9.78238 3.07516 9.68665 2.97952L8.02049 1.31336C7.92484 1.21762 7.87701 1.16975 7.80843 1.15326C7.71158 1.12998 7.58893 1.18075 7.53687 1.26567C7.5 1.3258 7.5 1.39921 7.5 1.54602L7.5 3.09998C7.5 3.23999 7.5 3.30999 7.52725 3.36347C7.55122 3.41051 7.58946 3.44876 7.6365 3.47272C7.68998 3.49997 7.75998 3.49997 7.9 3.49998L9.45398 3.5Z" fill="#98A2B3"/>
</svg>
app/(commonLayout)/apps/assets/completion.svg
New file
@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.25 11.875V9.6875C16.25 8.1342 14.9908 6.875 13.4375 6.875H12.1875C11.6697 6.875 11.25 6.45527 11.25 5.9375V4.6875C11.25 3.1342 9.9908 1.875 8.4375 1.875H6.875M6.875 12.5H13.125M6.875 15H10M8.75 1.875H4.6875C4.16973 1.875 3.75 2.29473 3.75 2.8125V17.1875C3.75 17.7053 4.16973 18.125 4.6875 18.125H15.3125C15.8303 18.125 16.25 17.7053 16.25 17.1875V9.375C16.25 5.23286 12.8921 1.875 8.75 1.875Z" stroke="#1F2A37" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
app/(commonLayout)/apps/assets/discord.svg
New file
@@ -0,0 +1,3 @@
<svg width="26" height="26" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.0101 4.50191C20.3529 3.74154 18.5759 3.18133 16.7179 2.86048C16.6841 2.85428 16.6503 2.86976 16.6328 2.90071C16.4043 3.30719 16.1511 3.83748 15.9738 4.25429C13.9754 3.95511 11.9873 3.95511 10.0298 4.25429C9.85253 3.82822 9.59019 3.30719 9.36062 2.90071C9.34319 2.87079 9.30939 2.85532 9.27555 2.86048C7.41857 3.18031 5.64152 3.74051 3.98335 4.50191C3.96899 4.5081 3.95669 4.51843 3.94852 4.53183C0.577841 9.56755 -0.345529 14.4795 0.107445 19.3306C0.109495 19.3543 0.122817 19.377 0.141265 19.3914C2.36514 21.0246 4.51935 22.0161 6.63355 22.6732C6.66739 22.6836 6.70324 22.6712 6.72477 22.6433C7.22489 21.9604 7.6707 21.2402 8.05293 20.4829C8.07549 20.4386 8.05396 20.386 8.00785 20.3684C7.30073 20.1002 6.6274 19.7731 5.97971 19.4017C5.92848 19.3718 5.92437 19.2985 5.9715 19.2635C6.1078 19.1613 6.24414 19.0551 6.37428 18.9478C6.39783 18.9282 6.43064 18.924 6.45833 18.9364C10.7134 20.8791 15.32 20.8791 19.5249 18.9364C19.5525 18.923 19.5854 18.9272 19.6099 18.9467C19.7401 19.054 19.8764 19.1613 20.0137 19.2635C20.0609 19.2985 20.0578 19.3718 20.0066 19.4017C19.3589 19.7804 18.6855 20.1002 17.9774 20.3674C17.9313 20.3849 17.9108 20.4386 17.9333 20.4829C18.3238 21.2392 18.7696 21.9593 19.2605 22.6423C19.281 22.6712 19.3179 22.6836 19.3517 22.6732C21.4761 22.0161 23.6303 21.0246 25.8542 19.3914C25.8737 19.377 25.886 19.3553 25.8881 19.3316C26.4302 13.7232 24.98 8.85156 22.0439 4.53286C22.0367 4.51843 22.0245 4.5081 22.0101 4.50191ZM8.68836 16.3768C7.40729 16.3768 6.35173 15.2007 6.35173 13.7563C6.35173 12.3119 7.38682 11.1358 8.68836 11.1358C10.0001 11.1358 11.0455 12.3222 11.025 13.7563C11.025 15.2007 9.98986 16.3768 8.68836 16.3768ZM17.3276 16.3768C16.0466 16.3768 14.991 15.2007 14.991 13.7563C14.991 12.3119 16.0261 11.1358 17.3276 11.1358C18.6394 11.1358 19.6847 12.3222 19.6643 13.7563C19.6643 15.2007 18.6394 16.3768 17.3276 16.3768Z" fill="#5865F2"/>
</svg>
app/(commonLayout)/apps/assets/github.svg
New file
@@ -0,0 +1,17 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_131_1011)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0003 0.5C9.15149 0.501478 6.39613 1.51046 4.22687 3.34652C2.05761 5.18259 0.615903 7.72601 0.159545 10.522C-0.296814 13.318 0.261927 16.1842 1.73587 18.6082C3.20981 21.0321 5.50284 22.8558 8.20493 23.753C8.80105 23.8636 9.0256 23.4941 9.0256 23.18C9.0256 22.8658 9.01367 21.955 9.0097 20.9592C5.6714 21.6804 4.96599 19.5505 4.96599 19.5505C4.42152 18.1674 3.63464 17.8039 3.63464 17.8039C2.54571 17.065 3.71611 17.0788 3.71611 17.0788C4.92227 17.1637 5.55616 18.3097 5.55616 18.3097C6.62521 20.1333 8.36389 19.6058 9.04745 19.2976C9.15475 18.5251 9.46673 17.9995 9.8105 17.7012C7.14383 17.4008 4.34204 16.3774 4.34204 11.8054C4.32551 10.6197 4.76802 9.47305 5.57801 8.60268C5.45481 8.30236 5.04348 7.08923 5.69524 5.44143C5.69524 5.44143 6.7027 5.12135 8.9958 6.66444C10.9627 6.12962 13.0379 6.12962 15.0047 6.66444C17.2958 5.12135 18.3013 5.44143 18.3013 5.44143C18.9551 7.08528 18.5437 8.29841 18.4205 8.60268C19.2331 9.47319 19.6765 10.6218 19.6585 11.8094C19.6585 16.3912 16.8507 17.4008 14.1801 17.6952C14.6093 18.0667 14.9928 18.7918 14.9928 19.9061C14.9928 21.5026 14.9789 22.7868 14.9789 23.18C14.9789 23.4981 15.1955 23.8695 15.8035 23.753C18.5059 22.8557 20.7992 21.0317 22.2731 18.6073C23.747 16.183 24.3055 13.3163 23.8486 10.5201C23.3917 7.7238 21.9493 5.18035 19.7793 3.34461C17.6093 1.50886 14.8533 0.500541 12.0042 0.5H12.0003Z" fill="#191717"/>
<path d="M4.54444 17.6321C4.5186 17.6914 4.42322 17.7092 4.34573 17.6677C4.26823 17.6262 4.21061 17.5491 4.23843 17.4879C4.26625 17.4266 4.35964 17.4108 4.43714 17.4523C4.51463 17.4938 4.57424 17.5729 4.54444 17.6321Z" fill="#191717"/>
<path d="M5.03123 18.1714C4.99008 18.192 4.943 18.1978 4.89805 18.1877C4.8531 18.1776 4.81308 18.1523 4.78483 18.1161C4.70734 18.0331 4.69143 17.9185 4.75104 17.8671C4.81066 17.8157 4.91797 17.8395 4.99546 17.9224C5.07296 18.0054 5.09084 18.12 5.03123 18.1714Z" fill="#191717"/>
<path d="M5.50425 18.857C5.43072 18.9084 5.30553 18.857 5.23598 18.7543C5.21675 18.7359 5.20146 18.7138 5.19101 18.6893C5.18056 18.6649 5.17517 18.6386 5.17517 18.612C5.17517 18.5855 5.18056 18.5592 5.19101 18.5347C5.20146 18.5103 5.21675 18.4882 5.23598 18.4698C5.3095 18.4204 5.4347 18.4698 5.50425 18.5705C5.57379 18.6713 5.57578 18.8057 5.50425 18.857V18.857Z" fill="#191717"/>
<path d="M6.14612 19.5207C6.08054 19.5939 5.94741 19.5741 5.83812 19.4753C5.72883 19.3765 5.70299 19.2422 5.76857 19.171C5.83414 19.0999 5.96727 19.1197 6.08054 19.2165C6.1938 19.3133 6.21566 19.4496 6.14612 19.5207V19.5207Z" fill="#191717"/>
<path d="M7.04617 19.9081C7.01637 20.001 6.88124 20.0425 6.74612 20.003C6.611 19.9635 6.52158 19.8528 6.54741 19.758C6.57325 19.6631 6.71036 19.6197 6.84747 19.6631C6.98457 19.7066 7.07201 19.8113 7.04617 19.9081Z" fill="#191717"/>
<path d="M8.02783 19.9752C8.02783 20.072 7.91656 20.155 7.77349 20.1569C7.63042 20.1589 7.51318 20.0799 7.51318 19.9831C7.51318 19.8863 7.62445 19.8033 7.76752 19.8013C7.91059 19.7993 8.02783 19.8764 8.02783 19.9752Z" fill="#191717"/>
<path d="M8.9419 19.8232C8.95978 19.92 8.86042 20.0207 8.71735 20.0445C8.57428 20.0682 8.4491 20.0109 8.43121 19.916C8.41333 19.8212 8.51666 19.7185 8.65576 19.6928C8.79485 19.6671 8.92401 19.7264 8.9419 19.8232Z" fill="#191717"/>
</g>
<defs>
<clipPath id="clip0_131_1011">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>
app/(commonLayout)/apps/assets/link-gray.svg
New file
@@ -0,0 +1,3 @@
<svg width="13" height="14" viewBox="0 0 13 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.41663 3.75033H3.24996C2.96264 3.75033 2.68709 3.86446 2.48393 4.06763C2.28076 4.27079 2.16663 4.54634 2.16663 4.83366V10.2503C2.16663 10.5376 2.28076 10.8132 2.48393 11.0164C2.68709 11.2195 2.96264 11.3337 3.24996 11.3337H8.66663C8.95394 11.3337 9.22949 11.2195 9.43266 11.0164C9.63582 10.8132 9.74996 10.5376 9.74996 10.2503V8.08366M7.58329 2.66699H10.8333M10.8333 2.66699V5.91699M10.8333 2.66699L5.41663 8.08366" stroke="#9CA3AF" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
app/(commonLayout)/apps/assets/link.svg
New file
@@ -0,0 +1,3 @@
<svg width="13" height="14" viewBox="0 0 13 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.41663 3.75008H3.24996C2.96264 3.75008 2.68709 3.86422 2.48393 4.06738C2.28076 4.27055 2.16663 4.5461 2.16663 4.83341V10.2501C2.16663 10.5374 2.28076 10.8129 2.48393 11.0161C2.68709 11.2193 2.96264 11.3334 3.24996 11.3334H8.66663C8.95394 11.3334 9.22949 11.2193 9.43266 11.0161C9.63582 10.8129 9.74996 10.5374 9.74996 10.2501V8.08341M7.58329 2.66675H10.8333M10.8333 2.66675V5.91675M10.8333 2.66675L5.41663 8.08341" stroke="#1C64F2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
app/(commonLayout)/apps/assets/right-arrow.svg
New file
@@ -0,0 +1,3 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 2.5L10.5 6M10.5 6L7 9.5M10.5 6H1.5" stroke="#1C64F2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
app/(commonLayout)/apps/hooks/useAppsQueryState.ts
New file
@@ -0,0 +1,60 @@
import { type ReadonlyURLSearchParams, usePathname, useRouter, useSearchParams } from 'next/navigation'
import { useCallback, useEffect, useMemo, useState } from 'react'
type AppsQuery = {
  tagIDs?: string[]
  keywords?: string
  isCreatedByMe?: boolean
}
// Parse the query parameters from the URL search string.
function parseParams(params: ReadonlyURLSearchParams): AppsQuery {
  const tagIDs = params.get('tagIDs')?.split(';')
  const keywords = params.get('keywords') || undefined
  const isCreatedByMe = params.get('isCreatedByMe') === 'true'
  return { tagIDs, keywords, isCreatedByMe }
}
// Update the URL search string with the given query parameters.
function updateSearchParams(query: AppsQuery, current: URLSearchParams) {
  const { tagIDs, keywords, isCreatedByMe } = query || {}
  if (tagIDs && tagIDs.length > 0)
    current.set('tagIDs', tagIDs.join(';'))
  else
    current.delete('tagIDs')
  if (keywords)
    current.set('keywords', keywords)
  else
    current.delete('keywords')
  if (isCreatedByMe)
    current.set('isCreatedByMe', 'true')
  else
    current.delete('isCreatedByMe')
}
function useAppsQueryState() {
  const searchParams = useSearchParams()
  const [query, setQuery] = useState<AppsQuery>(() => parseParams(searchParams))
  const router = useRouter()
  const pathname = usePathname()
  const syncSearchParams = useCallback((params: URLSearchParams) => {
    const search = params.toString()
    const query = search ? `?${search}` : ''
    router.push(`${pathname}${query}`, { scroll: false })
  }, [router, pathname])
  // Update the URL search string whenever the query changes.
  useEffect(() => {
    const params = new URLSearchParams(searchParams)
    updateSearchParams(query, params)
    syncSearchParams(params)
  }, [query, searchParams, syncSearchParams])
  return useMemo(() => ({ query, setQuery }), [query])
}
export default useAppsQueryState
app/(commonLayout)/apps/page.tsx
New file
@@ -0,0 +1,37 @@
'use client'
import { useContextSelector } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import { RiDiscordFill, RiGithubFill } from '@remixicon/react'
import Link from 'next/link'
import style from '../list.module.css'
import Apps from './Apps'
import AppContext from '@/context/app-context'
import { LicenseStatus } from '@/types/feature'
import { useEducationInit } from '@/app/education-apply/hooks'
const AppList = () => {
  const { t } = useTranslation()
  useEducationInit()
  const systemFeatures = useContextSelector(AppContext, v => v.systemFeatures)
  return (
    <div className='relative flex h-0 shrink-0 grow flex-col overflow-y-auto bg-background-body'>
      <Apps />
      {systemFeatures.license.status === LicenseStatus.NONE && <footer className='shrink-0 grow-0 px-12 py-6'>
        <h3 className='text-gradient text-xl font-semibold leading-tight'>{t('app.join')}</h3>
        <p className='system-sm-regular mt-1 text-text-tertiary'>{t('app.communityIntro')}</p>
        <div className='mt-3 flex items-center gap-2'>
          <Link className={style.socialMediaLink} target='_blank' rel='noopener noreferrer' href='https://github.com/langgenius/dify'>
            <RiGithubFill className='h-5 w-5 text-text-tertiary' />
          </Link>
          <Link className={style.socialMediaLink} target='_blank' rel='noopener noreferrer' href='https://discord.gg/FngNHpbcY7'>
            <RiDiscordFill className='h-5 w-5 text-text-tertiary' />
          </Link>
        </div>
      </footer>}
    </div >
  )
}
export default AppList
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/api/page.tsx
New file
@@ -0,0 +1,9 @@
import React from 'react'
const page = () => {
  return (
    <div>dataset detail api</div>
  )
}
export default page
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/documents/[documentId]/page.tsx
New file
@@ -0,0 +1,21 @@
import React from 'react'
import MainDetail from '@/app/components/datasets/documents/detail'
export type IDocumentDetailProps = {
  params: Promise<{ datasetId: string; documentId: string }>
}
const DocumentDetail = async (props: IDocumentDetailProps) => {
  const params = await props.params
  const {
    datasetId,
    documentId,
  } = params
  return (
    <MainDetail datasetId={datasetId} documentId={documentId} />
  )
}
export default DocumentDetail
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/documents/[documentId]/settings/page.tsx
New file
@@ -0,0 +1,21 @@
import React from 'react'
import Settings from '@/app/components/datasets/documents/detail/settings'
export type IProps = {
  params: Promise<{ datasetId: string; documentId: string }>
}
const DocumentSettings = async (props: IProps) => {
  const params = await props.params
  const {
    datasetId,
    documentId,
  } = params
  return (
    <Settings datasetId={datasetId} documentId={documentId} />
  )
}
export default DocumentSettings
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/documents/create/page.tsx
New file
@@ -0,0 +1,20 @@
import React from 'react'
import DatasetUpdateForm from '@/app/components/datasets/create'
export type IProps = {
  params: Promise<{ datasetId: string }>
}
const Create = async (props: IProps) => {
  const params = await props.params
  const {
    datasetId,
  } = params
  return (
    <DatasetUpdateForm datasetId={datasetId} />
  )
}
export default Create
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/documents/page.tsx
New file
@@ -0,0 +1,20 @@
import React from 'react'
import Main from '@/app/components/datasets/documents'
export type IProps = {
  params: Promise<{ datasetId: string }>
}
const Documents = async (props: IProps) => {
  const params = await props.params
  const {
    datasetId,
  } = params
  return (
    <Main datasetId={datasetId} />
  )
}
export default Documents
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/documents/style.module.css
New file
@@ -0,0 +1,9 @@
.logTable td {
  padding: 7px 8px;
  box-sizing: border-box;
  max-width: 200px;
}
.pagination li {
  list-style: none;
}
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/hitTesting/page.tsx
New file
@@ -0,0 +1,20 @@
import React from 'react'
import Main from '@/app/components/datasets/hit-testing'
type Props = {
  params: Promise<{ datasetId: string }>
}
const HitTesting = async (props: Props) => {
  const params = await props.params
  const {
    datasetId,
  } = params
  return (
    <Main datasetId={datasetId} />
  )
}
export default HitTesting
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout-main.tsx
New file
@@ -0,0 +1,199 @@
'use client'
import type { FC } from 'react'
import React, { useEffect, useMemo } from 'react'
import { usePathname } from 'next/navigation'
import useSWR from 'swr'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import {
  RiEqualizer2Fill,
  RiEqualizer2Line,
  RiFileTextFill,
  RiFileTextLine,
  RiFocus2Fill,
  RiFocus2Line,
} from '@remixicon/react'
import {
  PaperClipIcon,
} from '@heroicons/react/24/outline'
import { RiApps2AddLine, RiBookOpenLine, RiInformation2Line } from '@remixicon/react'
import classNames from '@/utils/classnames'
import { fetchDatasetDetail, fetchDatasetRelatedApps } from '@/service/datasets'
import type { RelatedAppResponse } from '@/models/datasets'
import AppSideBar from '@/app/components/app-sidebar'
import Loading from '@/app/components/base/loading'
import DatasetDetailContext from '@/context/dataset-detail'
import { DataSourceType } from '@/models/datasets'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import { LanguagesSupported } from '@/i18n/language'
import { useStore } from '@/app/components/app/store'
import { getLocaleOnClient } from '@/i18n'
import { useAppContext } from '@/context/app-context'
import Tooltip from '@/app/components/base/tooltip'
import LinkedAppsPanel from '@/app/components/base/linked-apps-panel'
export type IAppDetailLayoutProps = {
  children: React.ReactNode
  params: { datasetId: string }
}
type IExtraInfoProps = {
  isMobile: boolean
  relatedApps?: RelatedAppResponse
  expand: boolean
}
const ExtraInfo = ({ isMobile, relatedApps, expand }: IExtraInfoProps) => {
  const locale = getLocaleOnClient()
  const [isShowTips, { toggle: toggleTips, set: setShowTips }] = useBoolean(!isMobile)
  const { t } = useTranslation()
  const hasRelatedApps = relatedApps?.data && relatedApps?.data?.length > 0
  const relatedAppsTotal = relatedApps?.data?.length || 0
  useEffect(() => {
    setShowTips(!isMobile)
  }, [isMobile, setShowTips])
  return <div>
    {hasRelatedApps && (
      <>
        {!isMobile && (
          <Tooltip
            position='right'
            noDecoration
            needsDelay
            popupContent={
              <LinkedAppsPanel
                relatedApps={relatedApps.data}
                isMobile={isMobile}
              />
            }
          >
            <div className='system-xs-medium-uppercase inline-flex cursor-pointer items-center space-x-1 text-text-secondary'>
              <span>{relatedAppsTotal || '--'} {t('common.datasetMenus.relatedApp')}</span>
              <RiInformation2Line className='h-4 w-4' />
            </div>
          </Tooltip>
        )}
        {isMobile && <div className={classNames('uppercase text-xs text-text-tertiary font-medium pb-2 pt-4', 'flex items-center justify-center !px-0 gap-1')}>
          {relatedAppsTotal || '--'}
          <PaperClipIcon className='h-4 w-4 text-text-secondary' />
        </div>}
      </>
    )}
    {!hasRelatedApps && !expand && (
      <Tooltip
        position='right'
        noDecoration
        needsDelay
        popupContent={
          <div className='w-[240px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-4'>
            <div className='inline-flex rounded-lg border-[0.5px] border-components-panel-border-subtle bg-background-default-subtle p-2'>
              <RiApps2AddLine className='h-4 w-4 text-text-tertiary' />
            </div>
            <div className='my-2 text-xs text-text-tertiary'>{t('common.datasetMenus.emptyTip')}</div>
            <a
              className='mt-2 inline-flex cursor-pointer items-center text-xs text-text-accent'
              href={
                locale === LanguagesSupported[1]
                  ? 'https://docs.dify.ai/zh-hans/guides/knowledge-base/integrate-knowledge-within-application'
                  : 'https://docs.dify.ai/guides/knowledge-base/integrate-knowledge-within-application'
              }
              target='_blank' rel='noopener noreferrer'
            >
              <RiBookOpenLine className='mr-1 text-text-accent' />
              {t('common.datasetMenus.viewDoc')}
            </a>
          </div>
        }
      >
        <div className='system-xs-medium-uppercase inline-flex cursor-pointer items-center space-x-1 text-text-secondary'>
          <span>{t('common.datasetMenus.noRelatedApp')}</span>
          <RiInformation2Line className='h-4 w-4' />
        </div>
      </Tooltip>
    )}
  </div>
}
const DatasetDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
  const {
    children,
    params: { datasetId },
  } = props
  const pathname = usePathname()
  const hideSideBar = /documents\/create$/.test(pathname)
  const { t } = useTranslation()
  const { isCurrentWorkspaceDatasetOperator } = useAppContext()
  const media = useBreakpoints()
  const isMobile = media === MediaType.mobile
  const { data: datasetRes, error, mutate: mutateDatasetRes } = useSWR({
    url: 'fetchDatasetDetail',
    datasetId,
  }, apiParams => fetchDatasetDetail(apiParams.datasetId))
  const { data: relatedApps } = useSWR({
    action: 'fetchDatasetRelatedApps',
    datasetId,
  }, apiParams => fetchDatasetRelatedApps(apiParams.datasetId))
  const navigation = useMemo(() => {
    const baseNavigation = [
      { name: t('common.datasetMenus.hitTesting'), href: `/datasets/${datasetId}/hitTesting`, icon: RiFocus2Line, selectedIcon: RiFocus2Fill },
      { name: t('common.datasetMenus.settings'), href: `/datasets/${datasetId}/settings`, icon: RiEqualizer2Line, selectedIcon: RiEqualizer2Fill },
    ]
    if (datasetRes?.provider !== 'external') {
      baseNavigation.unshift({
        name: t('common.datasetMenus.documents'),
        href: `/datasets/${datasetId}/documents`,
        icon: RiFileTextLine,
        selectedIcon: RiFileTextFill,
      })
    }
    return baseNavigation
  }, [datasetRes?.provider, datasetId, t])
  useEffect(() => {
    if (datasetRes)
      document.title = `${datasetRes.name || 'Dataset'} - Dify`
  }, [datasetRes])
  const setAppSiderbarExpand = useStore(state => state.setAppSiderbarExpand)
  useEffect(() => {
    const localeMode = localStorage.getItem('app-detail-collapse-or-expand') || 'expand'
    const mode = isMobile ? 'collapse' : 'expand'
    setAppSiderbarExpand(isMobile ? mode : localeMode)
  }, [isMobile, setAppSiderbarExpand])
  if (!datasetRes && !error)
    return <Loading type='app' />
  return (
    <div className='flex grow overflow-hidden'>
      {!hideSideBar && <AppSideBar
        title={datasetRes?.name || '--'}
        icon={datasetRes?.icon || 'https://static.dify.ai/images/dataset-default-icon.png'}
        icon_background={datasetRes?.icon_background || '#F5F5F5'}
        desc={datasetRes?.description || '--'}
        isExternal={datasetRes?.provider === 'external'}
        navigation={navigation}
        extraInfo={!isCurrentWorkspaceDatasetOperator ? mode => <ExtraInfo isMobile={mode === 'collapse'} relatedApps={relatedApps} expand={mode === 'collapse'} /> : undefined}
        iconType={datasetRes?.data_source_type === DataSourceType.NOTION ? 'notion' : 'dataset'}
      />}
      <DatasetDetailContext.Provider value={{
        indexingTechnique: datasetRes?.indexing_technique,
        dataset: datasetRes,
        mutateDatasetRes: () => mutateDatasetRes(),
      }}>
        <div className="grow overflow-hidden bg-background-default-subtle">{children}</div>
      </DatasetDetailContext.Provider>
    </div>
  )
}
export default React.memo(DatasetDetailLayout)
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout.tsx
New file
@@ -0,0 +1,17 @@
import Main from './layout-main'
const DatasetDetailLayout = async (
  props: {
    children: React.ReactNode
    params: Promise<{ datasetId: string }>
  },
) => {
  const params = await props.params
  const {
    children,
  } = props
  return <Main params={(await params)}>{children}</Main>
}
export default DatasetDetailLayout
app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/settings/page.tsx
New file
@@ -0,0 +1,20 @@
import React from 'react'
import { getLocaleOnServer, useTranslation as translate } from '@/i18n/server'
import Form from '@/app/components/datasets/settings/form'
const Settings = async () => {
  const locale = await getLocaleOnServer()
  const { t } = await translate(locale, 'dataset-settings')
  return (
    <div className='h-full overflow-y-auto'>
      <div className='px-6 py-3'>
        <div className='system-xl-semibold mb-1 text-text-primary'>{t('title')}</div>
        <div className='system-sm-regular text-text-tertiary'>{t('desc')}</div>
      </div>
      <Form />
    </div>
  )
}
export default Settings
app/(commonLayout)/datasets/(datasetDetailLayout)/layout.tsx
New file
@@ -0,0 +1,16 @@
import type { FC } from 'react'
import React from 'react'
export type IDatasetDetail = {
  children: React.ReactNode
}
const AppDetail: FC<IDatasetDetail> = ({ children }) => {
  return (
    <>
      {children}
    </>
  )
}
export default React.memo(AppDetail)
app/(commonLayout)/datasets/Container.tsx
New file
@@ -0,0 +1,141 @@
'use client'
// Libraries
import { useEffect, useMemo, useRef, useState } from 'react'
import { useRouter } from 'next/navigation'
import { useTranslation } from 'react-i18next'
import { useBoolean, useDebounceFn } from 'ahooks'
import { useQuery } from '@tanstack/react-query'
// Components
import ExternalAPIPanel from '../../components/datasets/external-api/external-api-panel'
import Datasets from './Datasets'
import DatasetFooter from './DatasetFooter'
import ApiServer from '../../components/develop/ApiServer'
import Doc from './Doc'
import TabSliderNew from '@/app/components/base/tab-slider-new'
import TagManagementModal from '@/app/components/base/tag-management'
import TagFilter from '@/app/components/base/tag-management/filter'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import { ApiConnectionMod } from '@/app/components/base/icons/src/vender/solid/development'
import CheckboxWithLabel from '@/app/components/datasets/create/website/base/checkbox-with-label'
// Services
import { fetchDatasetApiBaseUrl } from '@/service/datasets'
// Hooks
import { useTabSearchParams } from '@/hooks/use-tab-searchparams'
import { useStore as useTagStore } from '@/app/components/base/tag-management/store'
import { useAppContext } from '@/context/app-context'
import { useExternalApiPanel } from '@/context/external-api-panel-context'
const Container = () => {
  const { t } = useTranslation()
  const router = useRouter()
  const { currentWorkspace, isCurrentWorkspaceOwner } = useAppContext()
  const showTagManagementModal = useTagStore(s => s.showTagManagementModal)
  const { showExternalApiPanel, setShowExternalApiPanel } = useExternalApiPanel()
  const [includeAll, { toggle: toggleIncludeAll }] = useBoolean(false)
  document.title = `${t('dataset.knowledge')} - Dify`
  const options = useMemo(() => {
    return [
      { value: 'dataset', text: t('dataset.datasets') },
      ...(currentWorkspace.role === 'dataset_operator' ? [] : [{ value: 'api', text: t('dataset.datasetsApi') }]),
    ]
  }, [currentWorkspace.role, t])
  const [activeTab, setActiveTab] = useTabSearchParams({
    defaultTab: 'dataset',
  })
  const containerRef = useRef<HTMLDivElement>(null)
  const { data } = useQuery(
    {
      queryKey: ['datasetApiBaseInfo'],
      queryFn: () => fetchDatasetApiBaseUrl('/datasets/api-base-info'),
      enabled: activeTab !== 'dataset',
    },
  )
  const [keywords, setKeywords] = useState('')
  const [searchKeywords, setSearchKeywords] = useState('')
  const { run: handleSearch } = useDebounceFn(() => {
    setSearchKeywords(keywords)
  }, { wait: 500 })
  const handleKeywordsChange = (value: string) => {
    setKeywords(value)
    handleSearch()
  }
  const [tagFilterValue, setTagFilterValue] = useState<string[]>([])
  const [tagIDs, setTagIDs] = useState<string[]>([])
  const { run: handleTagsUpdate } = useDebounceFn(() => {
    setTagIDs(tagFilterValue)
  }, { wait: 500 })
  const handleTagsChange = (value: string[]) => {
    setTagFilterValue(value)
    handleTagsUpdate()
  }
  useEffect(() => {
    if (currentWorkspace.role === 'normal')
      return router.replace('/apps')
  }, [currentWorkspace, router])
  return (
    <div ref={containerRef} className='scroll-container relative flex grow flex-col overflow-y-auto bg-background-body'>
      <div className='sticky top-0 z-10 flex flex-wrap items-center justify-between gap-y-2 bg-background-body px-12 pb-2 pt-4 leading-[56px]'>
        <TabSliderNew
          value={activeTab}
          onChange={newActiveTab => setActiveTab(newActiveTab)}
          options={options}
        />
        {activeTab === 'dataset' && (
          <div className='flex items-center justify-center gap-2'>
            {isCurrentWorkspaceOwner && <CheckboxWithLabel
              isChecked={includeAll}
              onChange={toggleIncludeAll}
              label={t('dataset.allKnowledge')}
              labelClassName='system-md-regular text-text-secondary'
              className='mr-2'
              tooltip={t('dataset.allKnowledgeDescription') as string}
            />}
            <TagFilter type='knowledge' value={tagFilterValue} onChange={handleTagsChange} />
            <Input
              showLeftIcon
              showClearIcon
              wrapperClassName='w-[200px]'
              value={keywords}
              onChange={e => handleKeywordsChange(e.target.value)}
              onClear={() => handleKeywordsChange('')}
            />
            <div className="h-4 w-[1px] bg-divider-regular" />
            <Button
              className='shadows-shadow-xs gap-0.5'
              onClick={() => setShowExternalApiPanel(true)}
            >
              <ApiConnectionMod className='h-4 w-4 text-components-button-secondary-text' />
              <div className='system-sm-medium flex items-center justify-center gap-1 px-0.5 text-components-button-secondary-text'>{t('dataset.externalAPIPanelTitle')}</div>
            </Button>
          </div>
        )}
        {activeTab === 'api' && data && <ApiServer apiBaseUrl={data.api_base_url || ''} />}
      </div>
      {activeTab === 'dataset' && (
        <>
          <Datasets containerRef={containerRef} tags={tagIDs} keywords={searchKeywords} includeAll={includeAll} />
          <DatasetFooter />
          {showTagManagementModal && (
            <TagManagementModal type='knowledge' show={showTagManagementModal} />
          )}
        </>
      )}
      {activeTab === 'api' && data && <Doc apiBaseUrl={data.api_base_url || ''} />}
      {showExternalApiPanel && <ExternalAPIPanel onClose={() => setShowExternalApiPanel(false)} />}
    </div>
  )
}
export default Container
app/(commonLayout)/datasets/DatasetCard.tsx
New file
@@ -0,0 +1,240 @@
'use client'
import { useContext } from 'use-context-selector'
import { useRouter } from 'next/navigation'
import { useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiMoreFill } from '@remixicon/react'
import cn from '@/utils/classnames'
import Confirm from '@/app/components/base/confirm'
import { ToastContext } from '@/app/components/base/toast'
import { checkIsUsedInApp, deleteDataset } from '@/service/datasets'
import type { DataSet } from '@/models/datasets'
import Tooltip from '@/app/components/base/tooltip'
import { Folder } from '@/app/components/base/icons/src/vender/solid/files'
import type { HtmlContentProps } from '@/app/components/base/popover'
import CustomPopover from '@/app/components/base/popover'
import Divider from '@/app/components/base/divider'
import RenameDatasetModal from '@/app/components/datasets/rename-modal'
import type { Tag } from '@/app/components/base/tag-management/constant'
import TagSelector from '@/app/components/base/tag-management/selector'
import CornerLabel from '@/app/components/base/corner-label'
import { useAppContext } from '@/context/app-context'
export type DatasetCardProps = {
  dataset: DataSet
  onSuccess?: () => void
}
const DatasetCard = ({
  dataset,
  onSuccess,
}: DatasetCardProps) => {
  const { t } = useTranslation()
  const { notify } = useContext(ToastContext)
  const { push } = useRouter()
  const EXTERNAL_PROVIDER = 'external' as const
  const { isCurrentWorkspaceDatasetOperator } = useAppContext()
  const [tags, setTags] = useState<Tag[]>(dataset.tags)
  const [showRenameModal, setShowRenameModal] = useState(false)
  const [showConfirmDelete, setShowConfirmDelete] = useState(false)
  const [confirmMessage, setConfirmMessage] = useState<string>('')
  const isExternalProvider = (provider: string): boolean => provider === EXTERNAL_PROVIDER
  const detectIsUsedByApp = useCallback(async () => {
    try {
      const { is_using: isUsedByApp } = await checkIsUsedInApp(dataset.id)
      setConfirmMessage(isUsedByApp ? t('dataset.datasetUsedByApp')! : t('dataset.deleteDatasetConfirmContent')!)
    }
    catch (e: any) {
      const res = await e.json()
      notify({ type: 'error', message: res?.message || 'Unknown error' })
    }
    setShowConfirmDelete(true)
  }, [dataset.id, notify, t])
  const onConfirmDelete = useCallback(async () => {
    try {
      await deleteDataset(dataset.id)
      notify({ type: 'success', message: t('dataset.datasetDeleted') })
      if (onSuccess)
        onSuccess()
    }
    catch {
    }
    setShowConfirmDelete(false)
  }, [dataset.id, notify, onSuccess, t])
  const Operations = (props: HtmlContentProps & { showDelete: boolean }) => {
    const onMouseLeave = async () => {
      props.onClose?.()
    }
    const onClickRename = async (e: React.MouseEvent<HTMLDivElement>) => {
      e.stopPropagation()
      props.onClick?.()
      e.preventDefault()
      setShowRenameModal(true)
    }
    const onClickDelete = async (e: React.MouseEvent<HTMLDivElement>) => {
      e.stopPropagation()
      props.onClick?.()
      e.preventDefault()
      detectIsUsedByApp()
    }
    return (
      <div className="relative w-full py-1" onMouseLeave={onMouseLeave}>
        <div className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-state-base-hover' onClick={onClickRename}>
          <span className='text-sm text-text-secondary'>{t('common.operation.settings')}</span>
        </div>
        {props.showDelete && (
          <>
            <Divider className="!my-1" />
            <div
              className='group mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-state-destructive-hover'
              onClick={onClickDelete}
            >
              <span className={cn('text-sm text-text-secondary', 'group-hover:text-text-destructive')}>
                {t('common.operation.delete')}
              </span>
            </div>
          </>
        )}
      </div>
    )
  }
  useEffect(() => {
    setTags(dataset.tags)
  }, [dataset])
  return (
    <>
      <div
        className='group relative col-span-1 flex min-h-[160px] cursor-pointer flex-col rounded-xl border-[0.5px] border-solid border-components-card-border bg-components-card-bg shadow-sm transition-all duration-200 ease-in-out hover:shadow-lg'
        data-disable-nprogress={true}
        onClick={(e) => {
          e.preventDefault()
          isExternalProvider(dataset.provider)
            ? push(`/datasets/${dataset.id}/hitTesting`)
            : push(`/datasets/${dataset.id}/documents`)
        }}
      >
        {isExternalProvider(dataset.provider) && <CornerLabel label='External' className='absolute right-0' labelClassName='rounded-tr-xl' />}
        <div className='flex h-[66px] shrink-0 grow-0 items-center gap-3 px-[14px] pb-3 pt-[14px]'>
          <div className={cn(
            'flex shrink-0 items-center justify-center rounded-md border-[0.5px] border-[#E0EAFF] bg-[#F5F8FF] p-2.5',
            !dataset.embedding_available && 'opacity-50 hover:opacity-100',
          )}>
            <Folder className='h-5 w-5 text-[#444CE7]' />
          </div>
          <div className='w-0 grow py-[1px]'>
            <div className='flex items-center text-sm font-semibold leading-5 text-text-secondary'>
              <div className={cn('truncate', !dataset.embedding_available && 'text-text-tertiary opacity-50 hover:opacity-100')} title={dataset.name}>{dataset.name}</div>
              {!dataset.embedding_available && (
                <Tooltip
                  popupContent={t('dataset.unavailableTip')}
                >
                  <span className='ml-1 inline-flex w-max shrink-0 rounded-md border border-divider-regular px-1 text-xs font-normal leading-[18px] text-text-tertiary'>{t('dataset.unavailable')}</span>
                </Tooltip>
              )}
            </div>
            <div className='mt-[1px] flex items-center text-xs leading-[18px] text-text-tertiary'>
              <div
                className={cn('truncate', (!dataset.embedding_available || !dataset.document_count) && 'opacity-50')}
                title={dataset.provider === 'external' ? `${dataset.app_count}${t('dataset.appCount')}` : `${dataset.document_count}${t('dataset.documentCount')} · ${Math.round(dataset.word_count / 1000)}${t('dataset.wordCount')} · ${dataset.app_count}${t('dataset.appCount')}`}
              >
                {dataset.provider === 'external'
                  ? <>
                    <span>{dataset.app_count}{t('dataset.appCount')}</span>
                  </>
                  : <>
                    <span>{dataset.document_count}{t('dataset.documentCount')}</span>
                    <span className='mx-0.5 w-1 shrink-0 text-text-tertiary'>·</span>
                    <span>{Math.round(dataset.word_count / 1000)}{t('dataset.wordCount')}</span>
                    <span className='mx-0.5 w-1 shrink-0 text-text-tertiary'>·</span>
                    <span>{dataset.app_count}{t('dataset.appCount')}</span>
                  </>
                }
              </div>
            </div>
          </div>
        </div>
        <div
          className={cn(
            'mb-2 max-h-[72px] grow px-[14px] text-xs leading-normal text-text-tertiary group-hover:line-clamp-2 group-hover:max-h-[36px]',
            tags.length ? 'line-clamp-2' : 'line-clamp-4',
            !dataset.embedding_available && 'opacity-50 hover:opacity-100',
          )}
          title={dataset.description}>
          {dataset.description}
        </div>
        <div className={cn(
          'mt-4 h-[42px] shrink-0 items-center pb-[6px] pl-[14px] pr-[6px] pt-1',
          tags.length ? 'flex' : '!hidden group-hover:!flex',
        )}>
          <div className={cn('flex w-0 grow items-center gap-1', !dataset.embedding_available && 'opacity-50 hover:opacity-100')} onClick={(e) => {
            e.stopPropagation()
            e.preventDefault()
          }}>
            <div className={cn(
              'mr-[41px] w-full grow group-hover:!mr-0 group-hover:!block',
              tags.length ? '!block' : '!hidden',
            )}>
              <TagSelector
                position='bl'
                type='knowledge'
                targetID={dataset.id}
                value={tags.map(tag => tag.id)}
                selectedTags={tags}
                onCacheUpdate={setTags}
                onChange={onSuccess}
              />
            </div>
          </div>
          <div className='mx-1 !hidden h-[14px] w-[1px] shrink-0 bg-divider-regular group-hover:!flex' />
          <div className='!hidden shrink-0 group-hover:!flex'>
            <CustomPopover
              htmlContent={<Operations showDelete={!isCurrentWorkspaceDatasetOperator} />}
              position="br"
              trigger="click"
              btnElement={
                <div
                  className='flex h-8 w-8 cursor-pointer items-center justify-center rounded-md'
                >
                  <RiMoreFill className='h-4 w-4 text-text-secondary' />
                </div>
              }
              btnClassName={open =>
                cn(
                  open ? '!bg-black/5 !shadow-none' : '!bg-transparent',
                  'h-8 w-8 rounded-md border-none !p-2 hover:!bg-black/5',
                )
              }
              className={'!z-20 h-fit !w-[128px]'}
            />
          </div>
        </div>
      </div>
      {showRenameModal && (
        <RenameDatasetModal
          show={showRenameModal}
          dataset={dataset}
          onClose={() => setShowRenameModal(false)}
          onSuccess={onSuccess}
        />
      )}
      {showConfirmDelete && (
        <Confirm
          title={t('dataset.deleteDatasetConfirmTitle')}
          content={confirmMessage}
          isShow={showConfirmDelete}
          onConfirm={onConfirmDelete}
          onCancel={() => setShowConfirmDelete(false)}
        />
      )}
    </>
  )
}
export default DatasetCard
app/(commonLayout)/datasets/DatasetFooter.tsx
New file
@@ -0,0 +1,19 @@
'use client'
import { useTranslation } from 'react-i18next'
const DatasetFooter = () => {
  const { t } = useTranslation()
  return (
    <footer className='shrink-0 grow-0 px-12 py-6'>
      <h3 className='text-gradient text-xl font-semibold leading-tight'>{t('dataset.didYouKnow')}</h3>
      <p className='mt-1 text-sm font-normal leading-tight text-text-secondary'>
        {t('dataset.intro1')}<span className='inline-flex items-center gap-1 text-text-accent'>{t('dataset.intro2')}</span>{t('dataset.intro3')}<br />
        {t('dataset.intro4')}<span className='inline-flex items-center gap-1 text-text-accent'>{t('dataset.intro5')}</span>{t('dataset.intro6')}
      </p>
    </footer>
  )
}
export default DatasetFooter
app/(commonLayout)/datasets/Datasets.tsx
New file
@@ -0,0 +1,98 @@
'use client'
import { useCallback, useEffect, useRef } from 'react'
import useSWRInfinite from 'swr/infinite'
import { debounce } from 'lodash-es'
import { useTranslation } from 'react-i18next'
import NewDatasetCard from './NewDatasetCard'
import DatasetCard from './DatasetCard'
import type { DataSetListResponse, FetchDatasetsParams } from '@/models/datasets'
import { fetchDatasets } from '@/service/datasets'
import { useAppContext } from '@/context/app-context'
const getKey = (
  pageIndex: number,
  previousPageData: DataSetListResponse,
  tags: string[],
  keyword: string,
  includeAll: boolean,
) => {
  if (!pageIndex || previousPageData.has_more) {
    const params: FetchDatasetsParams = {
      url: 'datasets',
      params: {
        page: pageIndex + 1,
        limit: 30,
        include_all: includeAll,
      },
    }
    if (tags.length)
      params.params.tag_ids = tags
    if (keyword)
      params.params.keyword = keyword
    return params
  }
  return null
}
type Props = {
  containerRef: React.RefObject<HTMLDivElement>
  tags: string[]
  keywords: string
  includeAll: boolean
}
const Datasets = ({
  containerRef,
  tags,
  keywords,
  includeAll,
}: Props) => {
  const { isCurrentWorkspaceEditor } = useAppContext()
  const { data, isLoading, setSize, mutate } = useSWRInfinite(
    (pageIndex: number, previousPageData: DataSetListResponse) => getKey(pageIndex, previousPageData, tags, keywords, includeAll),
    fetchDatasets,
    { revalidateFirstPage: false, revalidateAll: true },
  )
  const loadingStateRef = useRef(false)
  const anchorRef = useRef<HTMLAnchorElement>(null)
  const { t } = useTranslation()
  useEffect(() => {
    loadingStateRef.current = isLoading
    document.title = `${t('dataset.knowledge')} - Dify`
  }, [isLoading, t])
  const onScroll = useCallback(
    debounce(() => {
      if (!loadingStateRef.current && containerRef.current && anchorRef.current) {
        const { scrollTop, clientHeight } = containerRef.current
        const anchorOffset = anchorRef.current.offsetTop
        if (anchorOffset - scrollTop - clientHeight < 100)
          setSize(size => size + 1)
      }
    }, 50),
    [setSize],
  )
  useEffect(() => {
    const currentContainer = containerRef.current
    currentContainer?.addEventListener('scroll', onScroll)
    return () => {
      currentContainer?.removeEventListener('scroll', onScroll)
      onScroll.cancel()
    }
  }, [onScroll])
  return (
    <nav className='grid shrink-0 grow grid-cols-1 content-start gap-4 px-12 pt-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4'>
      { isCurrentWorkspaceEditor && <NewDatasetCard ref={anchorRef} /> }
      {data?.map(({ data: datasets }) => datasets.map(dataset => (
        <DatasetCard key={dataset.id} dataset={dataset} onSuccess={mutate} />),
      ))}
    </nav>
  )
}
export default Datasets
app/(commonLayout)/datasets/Doc.tsx
New file
@@ -0,0 +1,131 @@
'use client'
import { useEffect, useMemo, useState } from 'react'
import { useContext } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import { RiListUnordered } from '@remixicon/react'
import TemplateEn from './template/template.en.mdx'
import TemplateZh from './template/template.zh.mdx'
import TemplateJa from './template/template.ja.mdx'
import I18n from '@/context/i18n'
import { LanguagesSupported } from '@/i18n/language'
import useTheme from '@/hooks/use-theme'
import { Theme } from '@/types/app'
import cn from '@/utils/classnames'
type DocProps = {
  apiBaseUrl: string
}
const Doc = ({ apiBaseUrl }: DocProps) => {
  const { locale } = useContext(I18n)
  const { t } = useTranslation()
  const [toc, setToc] = useState<Array<{ href: string; text: string }>>([])
  const [isTocExpanded, setIsTocExpanded] = useState(false)
  const { theme } = useTheme()
  // Set initial TOC expanded state based on screen width
  useEffect(() => {
    const mediaQuery = window.matchMedia('(min-width: 1280px)')
    setIsTocExpanded(mediaQuery.matches)
  }, [])
  // Extract TOC from article content
  useEffect(() => {
    const extractTOC = () => {
      const article = document.querySelector('article')
      if (article) {
        const headings = article.querySelectorAll('h2')
        const tocItems = Array.from(headings).map((heading) => {
          const anchor = heading.querySelector('a')
          if (anchor) {
            return {
              href: anchor.getAttribute('href') || '',
              text: anchor.textContent || '',
            }
          }
          return null
        }).filter((item): item is { href: string; text: string } => item !== null)
        setToc(tocItems)
      }
    }
    setTimeout(extractTOC, 0)
  }, [locale])
  // Handle TOC item click
  const handleTocClick = (e: React.MouseEvent<HTMLAnchorElement>, item: { href: string; text: string }) => {
    e.preventDefault()
    const targetId = item.href.replace('#', '')
    const element = document.getElementById(targetId)
    if (element) {
      const scrollContainer = document.querySelector('.scroll-container')
      if (scrollContainer) {
        const headerOffset = -40
        const elementTop = element.offsetTop - headerOffset
        scrollContainer.scrollTo({
          top: elementTop,
          behavior: 'smooth',
        })
      }
    }
  }
  const Template = useMemo(() => {
    switch (locale) {
      case LanguagesSupported[1]:
        return <TemplateZh apiBaseUrl={apiBaseUrl} />
      case LanguagesSupported[7]:
        return <TemplateJa apiBaseUrl={apiBaseUrl} />
      default:
        return <TemplateEn apiBaseUrl={apiBaseUrl} />
    }
  }, [apiBaseUrl, locale])
  return (
    <div className="flex">
      <div className={`fixed right-20 top-32 z-10 transition-all ${isTocExpanded ? 'w-64' : 'w-10'}`}>
        {isTocExpanded
          ? (
            <nav className="toc max-h-[calc(100vh-150px)] w-full overflow-y-auto rounded-lg bg-components-panel-bg p-4 shadow-md">
              <div className="mb-4 flex items-center justify-between">
                <h3 className="text-lg font-semibold text-text-primary">{t('appApi.develop.toc')}</h3>
                <button
                  onClick={() => setIsTocExpanded(false)}
                  className="text-text-tertiary hover:text-text-secondary"
                >
                  ✕
                </button>
              </div>
              <ul className="space-y-2">
                {toc.map((item, index) => (
                  <li key={index}>
                    <a
                      href={item.href}
                      className="text-text-secondary transition-colors duration-200 hover:text-text-primary hover:underline"
                      onClick={e => handleTocClick(e, item)}
                    >
                      {item.text}
                    </a>
                  </li>
                ))}
              </ul>
            </nav>
          )
          : (
            <button
              onClick={() => setIsTocExpanded(true)}
              className="flex h-10 w-10 items-center justify-center rounded-full bg-components-button-secondary-bg shadow-md transition-colors duration-200 hover:bg-components-button-secondary-bg-hover"
            >
              <RiListUnordered className="h-6 w-6 text-components-button-secondary-text" />
            </button>
          )}
      </div>
      <article className={cn('prose-xl prose mx-1 rounded-t-xl bg-background-default px-4 pt-16 sm:mx-12', theme === Theme.dark && 'prose-invert')}>
        {Template}
      </article>
    </div>
  )
}
export default Doc
app/(commonLayout)/datasets/NewDatasetCard.tsx
New file
@@ -0,0 +1,42 @@
'use client'
import { useTranslation } from 'react-i18next'
import Link from 'next/link'
import {
  RiAddLine,
  RiArrowRightLine,
} from '@remixicon/react'
const CreateAppCard = (
  {
    ref,
    ..._
  },
) => {
  const { t } = useTranslation()
  return (
    <div className='bg-background-default-dimm flex min-h-[160px] flex-col rounded-xl border-[0.5px]
      border-components-panel-border transition-all duration-200 ease-in-out'
    >
      <Link ref={ref} className='group flex grow cursor-pointer items-start p-4' href={'/datasets/create'}>
        <div className='flex items-center gap-3'>
          <div className='flex h-10 w-10 items-center justify-center rounded-lg border border-dashed border-divider-regular bg-background-default-lighter
            p-2 group-hover:border-solid group-hover:border-effects-highlight group-hover:bg-background-default-dodge'
          >
            <RiAddLine className='h-4 w-4 text-text-tertiary group-hover:text-text-accent'/>
          </div>
          <div className='system-md-semibold text-text-secondary group-hover:text-text-accent'>{t('dataset.createDataset')}</div>
        </div>
      </Link>
      <div className='system-xs-regular p-4 pt-0 text-text-tertiary'>{t('dataset.createDatasetIntro')}</div>
      <Link className='group flex cursor-pointer items-center gap-1 rounded-b-xl border-t-[0.5px] border-divider-subtle p-4' href={'datasets/connect'}>
        <div className='system-xs-medium text-text-tertiary group-hover:text-text-accent'>{t('dataset.connectDataset')}</div>
        <RiArrowRightLine className='h-3.5 w-3.5 text-text-tertiary group-hover:text-text-accent' />
      </Link>
    </div>
  )
}
CreateAppCard.displayName = 'CreateAppCard'
export default CreateAppCard
app/(commonLayout)/datasets/connect/page.tsx
New file
@@ -0,0 +1,8 @@
import React from 'react'
import ExternalKnowledgeBaseConnector from '@/app/components/datasets/external-knowledge-base/connector'
const ExternalKnowledgeBaseCreation = () => {
  return <ExternalKnowledgeBaseConnector />
}
export default ExternalKnowledgeBaseCreation
app/(commonLayout)/datasets/create/page.tsx
New file
@@ -0,0 +1,12 @@
import React from 'react'
import DatasetUpdateForm from '@/app/components/datasets/create'
type Props = {}
const DatasetCreation = async (props: Props) => {
  return (
    <DatasetUpdateForm />
  )
}
export default DatasetCreation
app/(commonLayout)/datasets/layout.tsx
New file
@@ -0,0 +1,14 @@
'use client'
import { ExternalApiPanelProvider } from '@/context/external-api-panel-context'
import { ExternalKnowledgeApiProvider } from '@/context/external-knowledge-api-context'
export default function DatasetsLayout({ children }: { children: React.ReactNode }) {
  return (
    <ExternalKnowledgeApiProvider>
      <ExternalApiPanelProvider>
        {children}
      </ExternalApiPanelProvider>
    </ExternalKnowledgeApiProvider>
  )
}
app/(commonLayout)/datasets/page.tsx
New file
@@ -0,0 +1,7 @@
import Container from './Container'
const AppList = async () => {
  return <Container />
}
export default AppList
app/(commonLayout)/datasets/store.ts
New file
@@ -0,0 +1,11 @@
import { create } from 'zustand'
type DatasetStore = {
  showExternalApiPanel: boolean
  setShowExternalApiPanel: (show: boolean) => void
}
export const useDatasetStore = create<DatasetStore>(set => ({
  showExternalApiPanel: false,
  setShowExternalApiPanel: show => set({ showExternalApiPanel: show }),
}))
app/(commonLayout)/datasets/template/template.en.mdx
New file
@@ -0,0 +1,2352 @@
{/**
  * @typedef Props
  * @property {string} apiBaseUrl
  */}
import { CodeGroup } from '@/app/components/develop/code.tsx'
import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstruction, Paragraph } from '@/app/components/develop/md.tsx'
# Knowledge API
<div>
  ### Authentication
  Service API of Dify authenticates using an `API-Key`.
  It is suggested that developers store the `API-Key` in the backend instead of sharing or storing it in the client side to avoid the leakage of the `API-Key`, which may lead to property loss.
  All API requests should include your `API-Key` in the **`Authorization`** HTTP Header, as shown below:
  <CodeGroup title="Code">
    ```javascript
      Authorization: Bearer {API_KEY}
    ```
  </CodeGroup>
</div>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/document/create-by-text'
  method='POST'
  title='Create a Document from Text'
  name='#create-by-text'
/>
<Row>
  <Col>
    This API is based on an existing knowledge and creates a new document through text based on this knowledge.
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='name' type='string' key='name'>
        Document name
      </Property>
      <Property name='text' type='string' key='text'>
        Document content
      </Property>
      <Property name='indexing_technique' type='string' key='indexing_technique'>
        Index mode
          - <code>high_quality</code> High quality: embedding using embedding model, built as vector database index
          - <code>economy</code> Economy: Build using inverted index of keyword table index
      </Property>
      <Property name='doc_form' type='string' key='doc_form'>
        Format of indexed content
          - <code>text_model</code> Text documents are directly embedded; `economy` mode defaults to using this form
          - <code>hierarchical_model</code> Parent-child mode
          - <code>qa_model</code> Q&A Mode: Generates Q&A pairs for segmented documents and then embeds the questions
      </Property>
      <Property name='doc_language' type='string' key='doc_language'>
        In Q&A mode, specify the language of the document, for example: <code>English</code>, <code>Chinese</code>
      </Property>
      <Property name='process_rule' type='object' key='process_rule'>
        Processing rules
          - <code>mode</code> (string) Cleaning, segmentation mode, automatic / custom
          - <code>rules</code> (object) Custom rules (in automatic mode, this field is empty)
            - <code>pre_processing_rules</code> (array[object]) Preprocessing rules
              - <code>id</code> (string) Unique identifier for the preprocessing rule
                - enumerate
                  - <code>remove_extra_spaces</code> Replace consecutive spaces, newlines, tabs
                  - <code>remove_urls_emails</code> Delete URL, email address
              - <code>enabled</code> (bool) Whether to select this rule or not. If no document ID is passed in, it represents the default value.
            - <code>segmentation</code> (object) Segmentation rules
              - <code>separator</code> Custom segment identifier, currently only allows one delimiter to be set. Default is \n
              - <code>max_tokens</code> Maximum length (token) defaults to 1000
            - <code>parent_mode</code> Retrieval mode of parent chunks: <code>full-doc</code> full text retrieval / <code>paragraph</code> paragraph retrieval
            - <code>subchunk_segmentation</code> (object) Child chunk rules
              - <code>separator</code> Segmentation identifier. Currently, only one delimiter is allowed. The default is <code>***</code>
              - <code>max_tokens</code> The maximum length (tokens) must be validated to be shorter than the length of the parent chunk
              - <code>chunk_overlap</code> Define the overlap between adjacent chunks (optional)
      </Property>
      <PropertyInstruction>When no parameters are set for the knowledge base, the first upload requires the following parameters to be provided; if not provided, the default parameters will be used.</PropertyInstruction>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        Retrieval model
          - <code>search_method</code> (string) Search method
            - <code>hybrid_search</code> Hybrid search
            - <code>semantic_search</code> Semantic search
            - <code>full_text_search</code> Full-text search
          - <code>reranking_enable</code> (bool) Whether to enable reranking
          - <code>reranking_mode</code> (object) Rerank model configuration
            - <code>reranking_provider_name</code> (string) Rerank model provider
            - <code>reranking_model_name</code> (string) Rerank model name
          - <code>top_k</code> (int) Number of results to return
          - <code>score_threshold_enabled</code> (bool) Whether to enable score threshold
          - <code>score_threshold</code> (float) Score threshold
      </Property>
      <Property name='embedding_model' type='string' key='embedding_model'>
        Embedding model name
      </Property>
      <Property name='embedding_model_provider' type='string' key='embedding_model_provider'>
        Embedding model provider
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/document/create-by-text"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/document/create-by-text' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"name": "text","text": "text","indexing_technique": "high_quality","process_rule": {"mode": "automatic"}}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/document/create-by-text' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "name": "text",
        "text": "text",
        "indexing_technique": "high_quality",
        "process_rule": {
            "mode": "automatic"
        }
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "document": {
        "id": "",
        "position": 1,
        "data_source_type": "upload_file",
        "data_source_info": {
            "upload_file_id": ""
        },
        "dataset_process_rule_id": "",
        "name": "text.txt",
        "created_from": "api",
        "created_by": "",
        "created_at": 1695690280,
        "tokens": 0,
        "indexing_status": "waiting",
        "error": null,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "archived": false,
        "display_status": "queuing",
        "word_count": 0,
        "hit_count": 0,
        "doc_form": "text_model"
      },
      "batch": ""
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/document/create-by-file'
  method='POST'
  title='Create a Document from a File'
  name='#create-by-file'
/>
<Row>
  <Col>
    This API is based on an existing knowledge and creates a new document through a file based on this knowledge.
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='data' type='multipart/form-data json string' key='data'>
        - <code>original_document_id</code> Source document ID (optional)
          - Used to re-upload the document or modify the document cleaning and segmentation configuration. The missing information is copied from the source document
          - The source document cannot be an archived document
          - When original_document_id is passed in, the update operation is performed on behalf of the document. process_rule is a fillable item. If not filled in, the segmentation method of the source document will be used by default
          - When original_document_id is not passed in, the new operation is performed on behalf of the document, and process_rule is required
        - <code>indexing_technique</code> Index mode
          - <code>high_quality</code> High quality: embedding using embedding model, built as vector database index
          - <code>economy</code> Economy: Build using inverted index of keyword table index
        - <code>doc_form</code> Format of indexed content
          - <code>text_model</code> Text documents are directly embedded; `economy` mode defaults to using this form
          - <code>hierarchical_model</code> Parent-child mode
          - <code>qa_model</code> Q&A Mode: Generates Q&A pairs for segmented documents and then embeds the questions
        - <code>doc_language</code> In Q&A mode, specify the language of the document, for example: <code>English</code>, <code>Chinese</code>
        - <code>process_rule</code> Processing rules
          - <code>mode</code> (string) Cleaning, segmentation mode, automatic / custom
          - <code>rules</code> (object) Custom rules (in automatic mode, this field is empty)
            - <code>pre_processing_rules</code> (array[object]) Preprocessing rules
              - <code>id</code> (string) Unique identifier for the preprocessing rule
                - enumerate
                  - <code>remove_extra_spaces</code> Replace consecutive spaces, newlines, tabs
                  - <code>remove_urls_emails</code> Delete URL, email address
              - <code>enabled</code> (bool) Whether to select this rule or not. If no document ID is passed in, it represents the default value.
            - <code>segmentation</code> (object) Segmentation rules
              - <code>separator</code> Custom segment identifier, currently only allows one delimiter to be set. Default is \n
              - <code>max_tokens</code> Maximum length (token) defaults to 1000
            - <code>parent_mode</code> Retrieval mode of parent chunks: <code>full-doc</code> full text retrieval / <code>paragraph</code> paragraph retrieval
            - <code>subchunk_segmentation</code> (object) Child chunk rules
              - <code>separator</code> Segmentation identifier. Currently, only one delimiter is allowed. The default is <code>***</code>
              - <code>max_tokens</code> The maximum length (tokens) must be validated to be shorter than the length of the parent chunk
              - <code>chunk_overlap</code> Define the overlap between adjacent chunks (optional)
      </Property>
      <Property name='file' type='multipart/form-data' key='file'>
        Files that need to be uploaded.
      </Property>
      <PropertyInstruction>When no parameters are set for the knowledge base, the first upload requires the following parameters to be provided; if not provided, the default parameters will be used.</PropertyInstruction>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        Retrieval model
          - <code>search_method</code> (string) Search method
            - <code>hybrid_search</code> Hybrid search
            - <code>semantic_search</code> Semantic search
            - <code>full_text_search</code> Full-text search
          - <code>reranking_enable</code> (bool) Whether to enable reranking
          - <code>reranking_mode</code> (object) Rerank model configuration
            - <code>reranking_provider_name</code> (string) Rerank model provider
            - <code>reranking_model_name</code> (string) Rerank model name
          - <code>top_k</code> (int) Number of results to return
          - <code>score_threshold_enabled</code> (bool) Whether to enable score threshold
          - <code>score_threshold</code> (float) Score threshold
      </Property>
      <Property name='embedding_model' type='string' key='embedding_model'>
        Embedding model name
      </Property>
      <Property name='embedding_model_provider' type='string' key='embedding_model_provider'>
        Embedding model provider
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/document/create-by-file"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/document/create-by-file' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'data="{"indexing_technique":"high_quality","process_rule":{"rules":{"pre_processing_rules":[{"id":"remove_extra_spaces","enabled":true},{"id":"remove_urls_emails","enabled":true}],"segmentation":{"separator":"###","max_tokens":500}},"mode":"custom"}}";type=text/plain' \\\n--form 'file=@"/path/to/file"'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/document/create-by-file' \
    --header 'Authorization: Bearer {api_key}' \
    --form 'data="{\"name\":\"Dify\",\"indexing_technique\":\"high_quality\",\"process_rule\":{\"rules\":{\"pre_processing_rules\":[{\"id\":\"remove_extra_spaces\",\"enabled\":true},{\"id\":\"remove_urls_emails\",\"enabled\":true}],\"segmentation\":{\"separator\":\"###\",\"max_tokens\":500}},\"mode\":\"custom\"}}";type=text/plain' \
    --form 'file=@"/path/to/file"'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "document": {
        "id": "",
        "position": 1,
        "data_source_type": "upload_file",
        "data_source_info": {
          "upload_file_id": ""
        },
        "dataset_process_rule_id": "",
        "name": "Dify.txt",
        "created_from": "api",
        "created_by": "",
        "created_at": 1695308667,
        "tokens": 0,
        "indexing_status": "waiting",
        "error": null,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "archived": false,
        "display_status": "queuing",
        "word_count": 0,
        "hit_count": 0,
        "doc_form": "text_model"
      },
      "batch": ""
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets'
  method='POST'
  title='Create an Empty Knowledge Base'
  name='#create_empty_dataset'
/>
<Row>
  <Col>
    ### Request Body
    <Properties>
      <Property name='name' type='string' key='name'>
        Knowledge name
      </Property>
      <Property name='description' type='string' key='description'>
        Knowledge description (optional)
      </Property>
      <Property name='indexing_technique' type='string' key='indexing_technique'>
        Index technique (optional)
        If this is not set, embedding_model, embedding_model_provider and retrieval_model will be set to null
          - <code>high_quality</code> High quality
          - <code>economy</code> Economy
      </Property>
      <Property name='permission' type='string' key='permission'>
        Permission
          - <code>only_me</code> Only me
          - <code>all_team_members</code> All team members
          - <code>partial_members</code> Partial members
      </Property>
      <Property name='provider' type='string' key='provider'>
        Provider (optional, default: vendor)
          - <code>vendor</code> Vendor
          - <code>external</code> External knowledge
      </Property>
      <Property name='external_knowledge_api_id' type='str' key='external_knowledge_api_id'>
        External knowledge API ID (optional)
      </Property>
      <Property name='external_knowledge_id' type='str' key='external_knowledge_id'>
        External knowledge ID (optional)
      </Property>
      <Property name='embedding_model' type='str' key='embedding_model'>
        Embedding model name (optional)
      </Property>
      <Property name='embedding_model_provider' type='str' key='embedding_model_provider'>
        Embedding model provider name (optional)
      </Property>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        Retrieval model (optional)
          - <code>search_method</code> (string) Search method
            - <code>hybrid_search</code> Hybrid search
            - <code>semantic_search</code> Semantic search
            - <code>full_text_search</code> Full-text search
          - <code>reranking_enable</code> (bool) Whether to enable reranking
          - <code>reranking_model</code> (object) Rerank model configuration
              - <code>reranking_provider_name</code> (string) Rerank model provider
              - <code>reranking_model_name</code> (string) Rerank model name
          - <code>top_k</code> (int) Number of results to return
          - <code>score_threshold_enabled</code> (bool) Whether to enable score threshold
          - <code>score_threshold</code> (float) Score threshold
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"name": "name", "permission": "only_me"}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${apiBaseUrl}/v1/datasets' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "name": "name",
      "permission": "only_me"
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "",
      "name": "name",
      "description": null,
      "provider": "vendor",
      "permission": "only_me",
      "data_source_type": null,
      "indexing_technique": null,
      "app_count": 0,
      "document_count": 0,
      "word_count": 0,
      "created_by": "",
      "created_at": 1695636173,
      "updated_by": "",
      "updated_at": 1695636173,
      "embedding_model": null,
      "embedding_model_provider": null,
      "embedding_available": null
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets'
  method='GET'
  title='Get Knowledge Base List'
  name='#dataset_list'
/>
<Row>
  <Col>
    ### Query
    <Properties>
      <Property name='keyword' type='string' key='keyword'>
        Search keyword, optional
      </Property>
      <Property name='tag_ids' type='array[string]' key='tag_ids'>
        Tag ID list, optional
      </Property>
      <Property name='page' type='string' key='page'>
        Page number, optional, default 1
      </Property>
      <Property name='limit' type='string' key='limit'>
        Number of items returned, optional, default 20, range 1-100
      </Property>
      <Property name='include_all' type='boolean' key='include_all'>
        Whether to include all datasets (only effective for owners), optional, defaults to false
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets?page=1&limit=20' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets?page=1&limit=20' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": [
        {
          "id": "",
          "name": "name",
          "description": "desc",
          "permission": "only_me",
          "data_source_type": "upload_file",
          "indexing_technique": "",
          "app_count": 2,
          "document_count": 10,
          "word_count": 1200,
          "created_by": "",
          "created_at": "",
          "updated_by": "",
          "updated_at": ""
        },
        ...
      ],
      "has_more": true,
      "limit": 20,
      "total": 50,
      "page": 1
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}'
  method='GET'
  title='Get knowledge base details by knowledge base ID'
  name='#view_dataset'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge Base ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "eaedb485-95ac-4ffd-ab1e-18da6d676a2f",
      "name": "Test Knowledge Base",
      "description": "",
      "provider": "vendor",
      "permission": "only_me",
      "data_source_type": null,
      "indexing_technique": null,
      "app_count": 0,
      "document_count": 0,
      "word_count": 0,
      "created_by": "e99a1635-f725-4951-a99a-1daaaa76cfc6",
      "created_at": 1735620612,
      "updated_by": "e99a1635-f725-4951-a99a-1daaaa76cfc6",
      "updated_at": 1735620612,
      "embedding_model": null,
      "embedding_model_provider": null,
      "embedding_available": true,
      "retrieval_model_dict": {
        "search_method": "semantic_search",
        "reranking_enable": false,
        "reranking_mode": null,
        "reranking_model": {
          "reranking_provider_name": "",
          "reranking_model_name": ""
        },
        "weights": null,
        "top_k": 2,
        "score_threshold_enabled": false,
        "score_threshold": null
      },
      "tags": [],
      "doc_form": null,
      "external_knowledge_info": {
        "external_knowledge_id": null,
        "external_knowledge_api_id": null,
        "external_knowledge_api_name": null,
        "external_knowledge_api_endpoint": null
      },
      "external_retrieval_model": {
        "top_k": 2,
        "score_threshold": 0.0,
        "score_threshold_enabled": null
      }
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}'
  method='PATCH'
  title='Update knowledge base'
  name='#update_dataset'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge Base ID
      </Property>
      <Property name='indexing_technique' type='string' key='indexing_technique'>
        Index technique (optional)
          - <code>high_quality</code> High quality
          - <code>economy</code> Economy
      </Property>
      <Property name='permission' type='string' key='permission'>
        Permission
          - <code>only_me</code> Only me
          - <code>all_team_members</code> All team members
          - <code>partial_members</code> Partial members
      </Property>
      <Property name='embedding_model_provider' type='string' key='embedding_model_provider'>
        Specified embedding model provider, must be set up in the system first, corresponding to the provider field(Optional)
      </Property>
      <Property name='embedding_model' type='string' key='embedding_model'>
        Specified embedding model, corresponding to the model field(Optional)
      </Property>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        Retrieval model (optional, if not filled, it will be recalled according to the default method)
        - <code>search_method</code> (text) Search method: One of the following four keywords is required
          - <code>keyword_search</code> Keyword search
          - <code>semantic_search</code> Semantic search
          - <code>full_text_search</code> Full-text search
          - <code>hybrid_search</code> Hybrid search
        - <code>reranking_enable</code> (bool) Whether to enable reranking, required if the search mode is semantic_search or hybrid_search (optional)
        - <code>reranking_mode</code> (object) Rerank model configuration, required if reranking is enabled
            - <code>reranking_provider_name</code> (string) Rerank model provider
            - <code>reranking_model_name</code> (string) Rerank model name
        - <code>weights</code> (float) Semantic search weight setting in hybrid search mode
        - <code>top_k</code> (integer) Number of results to return (optional)
        - <code>score_threshold_enabled</code> (bool) Whether to enable score threshold
        - <code>score_threshold</code> (float) Score threshold
      </Property>
      <Property name='partial_member_list' type='array' key='partial_member_list'>
        Partial member list(Optional)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="PATCH"
      label="/datasets/{dataset_id}"
      targetCode={`curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{
        "name": "Test Knowledge Base",
        "indexing_technique": "high_quality",
        "permission": "only_me",
        "embedding_model_provider": "zhipuai",
        "embedding_model": "embedding-3",
        "retrieval_model": {
          "search_method": "keyword_search",
          "reranking_enable": false,
          "reranking_mode": null,
          "reranking_model": {
              "reranking_provider_name": "",
              "reranking_model_name": ""
          },
          "weights": null,
          "top_k": 1,
          "score_threshold_enabled": false,
          "score_threshold": null
        },
        "partial_member_list": []
      }'
    `}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "name": "Test Knowledge Base",
      "indexing_technique": "high_quality",
      "permission": "only_me",
      "embedding_model_provider": "zhipuai",
      "embedding_model": "embedding-3",
      "retrieval_model": {
        "search_method": "keyword_search",
        "reranking_enable": false,
        "reranking_mode": null,
        "reranking_model": {
            "reranking_provider_name": "",
            "reranking_model_name": ""
        },
        "weights": null,
        "top_k": 1,
        "score_threshold_enabled": false,
        "score_threshold": null
      },
      "partial_member_list": []
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "eaedb485-95ac-4ffd-ab1e-18da6d676a2f",
      "name": "Test Knowledge Base",
      "description": "",
      "provider": "vendor",
      "permission": "only_me",
      "data_source_type": null,
      "indexing_technique": "high_quality",
      "app_count": 0,
      "document_count": 0,
      "word_count": 0,
      "created_by": "e99a1635-f725-4951-a99a-1daaaa76cfc6",
      "created_at": 1735620612,
      "updated_by": "e99a1635-f725-4951-a99a-1daaaa76cfc6",
      "updated_at": 1735622679,
      "embedding_model": "embedding-3",
      "embedding_model_provider": "zhipuai",
      "embedding_available": null,
      "retrieval_model_dict": {
          "search_method": "semantic_search",
          "reranking_enable": false,
          "reranking_mode": null,
          "reranking_model": {
              "reranking_provider_name": "",
              "reranking_model_name": ""
          },
          "weights": null,
          "top_k": 2,
          "score_threshold_enabled": false,
          "score_threshold": null
      },
      "tags": [],
      "doc_form": null,
      "external_knowledge_info": {
          "external_knowledge_id": null,
          "external_knowledge_api_id": null,
          "external_knowledge_api_name": null,
          "external_knowledge_api_endpoint": null
      },
      "external_retrieval_model": {
          "top_k": 2,
          "score_threshold": 0.0,
          "score_threshold_enabled": null
      },
      "partial_member_list": []
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}'
  method='DELETE'
  title='Delete a Knowledge Base'
  name='#delete_dataset'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="DELETE"
      label="/datasets/{dataset_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```text {{ title: 'Response' }}
    204 No Content
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/update-by-text'
  method='POST'
  title='Update a Document with Text'
  name='#update-by-text'
/>
<Row>
  <Col>
    This API is based on an existing knowledge and updates the document through text based on this knowledge.
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        Document ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='name' type='string' key='name'>
        Document name (optional)
      </Property>
      <Property name='text' type='string' key='text'>
        Document content (optional)
      </Property>
      <Property name='process_rule' type='object' key='process_rule'>
        Processing rules
          - <code>mode</code> (string) Cleaning, segmentation mode, automatic / custom
          - <code>rules</code> (object) Custom rules (in automatic mode, this field is empty)
            - <code>pre_processing_rules</code> (array[object]) Preprocessing rules
              - <code>id</code> (string) Unique identifier for the preprocessing rule
                - enumerate
                  - <code>remove_extra_spaces</code> Replace consecutive spaces, newlines, tabs
                  - <code>remove_urls_emails</code> Delete URL, email address
              - <code>enabled</code> (bool) Whether to select this rule or not. If no document ID is passed in, it represents the default value.
            - <code>segmentation</code> (object) Segmentation rules
              - <code>separator</code> Custom segment identifier, currently only allows one delimiter to be set. Default is \n
              - <code>max_tokens</code> Maximum length (token) defaults to 1000
            - <code>parent_mode</code> Retrieval mode of parent chunks: <code>full-doc</code> full text retrieval / <code>paragraph</code> paragraph retrieval
            - <code>subchunk_segmentation</code> (object) Child chunk rules
              - <code>separator</code> Segmentation identifier. Currently, only one delimiter is allowed. The default is <code>***</code>
              - <code>max_tokens</code> The maximum length (tokens) must be validated to be shorter than the length of the parent chunk
              - <code>chunk_overlap</code> Define the overlap between adjacent chunks (optional)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/update-by-text"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/update-by-text' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"name": "name","text": "text"}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/update-by-text' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "name": "name",
        "text": "text"
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "document": {
        "id": "",
        "position": 1,
        "data_source_type": "upload_file",
        "data_source_info": {
          "upload_file_id": ""
        },
        "dataset_process_rule_id": "",
        "name": "name.txt",
        "created_from": "api",
        "created_by": "",
        "created_at": 1695308667,
        "tokens": 0,
        "indexing_status": "waiting",
        "error": null,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "archived": false,
        "display_status": "queuing",
        "word_count": 0,
        "hit_count": 0,
        "doc_form": "text_model"
      },
      "batch": ""
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/update-by-file'
  method='POST'
  title='Update a Document with a File'
  name='#update-by-file'
/>
<Row>
  <Col>
    This API is based on an existing knowledge, and updates documents through files based on this knowledge
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        Document ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='name' type='string' key='name'>
        Document name (optional)
      </Property>
      <Property name='file' type='multipart/form-data' key='file'>
        Files to be uploaded
      </Property>
      <Property name='process_rule' type='object' key='process_rule'>
        Processing rules
          - <code>mode</code> (string) Cleaning, segmentation mode, automatic / custom
          - <code>rules</code> (object) Custom rules (in automatic mode, this field is empty)
            - <code>pre_processing_rules</code> (array[object]) Preprocessing rules
              - <code>id</code> (string) Unique identifier for the preprocessing rule
                - enumerate
                  - <code>remove_extra_spaces</code> Replace consecutive spaces, newlines, tabs
                  - <code>remove_urls_emails</code> Delete URL, email address
              - <code>enabled</code> (bool) Whether to select this rule or not. If no document ID is passed in, it represents the default value.
            - <code>segmentation</code> (object) Segmentation rules
              - <code>separator</code> Custom segment identifier, currently only allows one delimiter to be set. Default is \n
              - <code>max_tokens</code> Maximum length (token) defaults to 1000
            - <code>parent_mode</code> Retrieval mode of parent chunks: <code>full-doc</code> full text retrieval / <code>paragraph</code> paragraph retrieval
            - <code>subchunk_segmentation</code> (object) Child chunk rules
              - <code>separator</code> Segmentation identifier. Currently, only one delimiter is allowed. The default is <code>***</code>
              - <code>max_tokens</code> The maximum length (tokens) must be validated to be shorter than the length of the parent chunk
              - <code>chunk_overlap</code> Define the overlap between adjacent chunks (optional)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/update-by-file"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/update-by-file' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'data="{"name":"Dify","indexing_technique":"high_quality","process_rule":{"rules":{"pre_processing_rules":[{"id":"remove_extra_spaces","enabled":true},{"id":"remove_urls_emails","enabled":true}],"segmentation":{"separator":"###","max_tokens":500}},"mode":"custom"}}";type=text/plain' \\\n--form 'file=@"/path/to/file"'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/update-by-file' \
    --header 'Authorization: Bearer {api_key}' \
    --form 'data="{\"name\":\"Dify\",\"indexing_technique\":\"high_quality\",\"process_rule\":{\"rules\":{\"pre_processing_rules\":[{\"id\":\"remove_extra_spaces\",\"enabled\":true},{\"id\":\"remove_urls_emails\",\"enabled\":true}],\"segmentation\":{\"separator\":\"###\",\"max_tokens\":500}},\"mode\":\"custom\"}}";type=text/plain' \
    --form 'file=@"/path/to/file"'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "document": {
        "id": "",
        "position": 1,
        "data_source_type": "upload_file",
        "data_source_info": {
          "upload_file_id": ""
        },
        "dataset_process_rule_id": "",
        "name": "Dify.txt",
        "created_from": "api",
        "created_by": "",
        "created_at": 1695308667,
        "tokens": 0,
        "indexing_status": "waiting",
        "error": null,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "archived": false,
        "display_status": "queuing",
        "word_count": 0,
        "hit_count": 0,
        "doc_form": "text_model"
      },
      "batch": "20230921150427533684"
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{batch}/indexing-status'
  method='GET'
  title='Get Document Embedding Status (Progress)'
  name='#indexing_status'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='batch' type='string' key='batch'>
        Batch number of uploaded documents
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}/documents/{batch}/indexing-status"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{batch}/indexing-status' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{batch}/indexing-status' \
    --header 'Authorization: Bearer {api_key}' \
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data":[{
        "id": "",
        "indexing_status": "indexing",
        "processing_started_at": 1681623462.0,
        "parsing_completed_at": 1681623462.0,
        "cleaning_completed_at": 1681623462.0,
        "splitting_completed_at": 1681623462.0,
        "completed_at": null,
        "paused_at": null,
        "error": null,
        "stopped_at": null,
        "completed_segments": 24,
        "total_segments": 100
      }]
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}'
  method='DELETE'
  title='Delete a Document'
  name='#delete_document'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        Document ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="DELETE"
      label="/datasets/{dataset_id}/documents/{document_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}' \
    --header 'Authorization: Bearer {api_key}' \
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```text {{ title: 'Response' }}
    204 No Content
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents'
  method='GET'
  title='Get the Document List of a Knowledge Base'
  name='#dataset_document_list'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
    </Properties>
    ### Query
    <Properties>
      <Property name='keyword' type='string' key='keyword'>
        Search keywords, currently only search document names (optional)
      </Property>
      <Property name='page' type='string' key='page'>
        Page number (optional)
      </Property>
      <Property name='limit' type='string' key='limit'>
        Number of items returned, default 20, range 1-100 (optional)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}/documents"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents' \
    --header 'Authorization: Bearer {api_key}' \
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": [
        {
          "id": "",
          "position": 1,
          "data_source_type": "file_upload",
          "data_source_info": null,
          "dataset_process_rule_id": null,
          "name": "dify",
          "created_from": "",
          "created_by": "",
          "created_at": 1681623639,
          "tokens": 0,
          "indexing_status": "waiting",
          "error": null,
          "enabled": true,
          "disabled_at": null,
          "disabled_by": null,
          "archived": false
        },
      ],
      "has_more": false,
      "limit": 20,
      "total": 9,
      "page": 1
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments'
  method='POST'
  title='Add Chunks to a Document'
  name='#create_new_segment'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        Document ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='segments' type='object list' key='segments'>
        - <code>content</code> (text) Text content / question content, required
        - <code>answer</code> (text) Answer content, if the mode of the knowledge is Q&A mode, pass the value (optional)
        - <code>keywords</code> (list) Keywords (optional)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/segments"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"segments": [{"content": "1","answer": "1","keywords": ["a"]}]}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "segments": [
        {
          "content": "1",
          "answer": "1",
          "keywords": ["a"]
        }
      ]
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": [{
        "id": "",
        "position": 1,
        "document_id": "",
        "content": "1",
        "answer": "1",
        "word_count": 25,
        "tokens": 0,
        "keywords": [
          "a"
        ],
        "index_node_id": "",
        "index_node_hash": "",
        "hit_count": 0,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }],
      "doc_form": "text_model"
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments'
  method='GET'
  title='Get Chunks from a Document'
  name='#get_segment'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        Document ID
      </Property>
    </Properties>
     ### Query
    <Properties>
      <Property name='keyword' type='string' key='keyword'>
        Keyword (optional)
      </Property>
      <Property name='status' type='string' key='status'>
        Search status, completed
      </Property>
      <Property name='page' type='string' key='page'>
        Page number (optional)
      </Property>
      <Property name='limit' type='string' key='limit'>
        Number of items returned, default 20, range 1-100 (optional)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}/documents/{document_id}/segments"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": [{
        "id": "",
        "position": 1,
        "document_id": "",
        "content": "1",
        "answer": "1",
        "word_count": 25,
        "tokens": 0,
        "keywords": [
            "a"
        ],
        "index_node_id": "",
        "index_node_hash": "",
        "hit_count": 0,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }],
      "doc_form": "text_model",
      "has_more": false,
      "limit": 20,
      "total": 9,
      "page": 1
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}'
  method='DELETE'
  title='Delete a Chunk in a Document'
  name='#delete_segment'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        Document ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        Document Segment ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="DELETE"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```text {{ title: 'Response' }}
    204 No Content
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}'
  method='POST'
  title='Update a Chunk in a Document'
  name='#update_segment'
/>
<Row>
  <Col>
    ### POST
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        Document ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        Document Segment ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='segment' type='object' key='segment'>
        - <code>content</code> (text) Text content / question content, required
        - <code>answer</code> (text) Answer content, passed if the knowledge is in Q&A mode (optional)
        - <code>keywords</code> (list) Keyword (optional)
        - <code>enabled</code> (bool) False / true (optional)
        - <code>regenerate_child_chunks</code> (bool) Whether to regenerate child chunks (optional)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'\\\n--data-raw '{\"segment\": {\"content\": \"1\",\"answer\": \"1\", \"keywords\": [\"a\"], \"enabled\": false}}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "segment": {
          "content": "1",
          "answer": "1",
          "keywords": ["a"],
          "enabled": false
      }
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": {
        "id": "",
        "position": 1,
        "document_id": "",
        "content": "1",
        "answer": "1",
        "word_count": 25,
        "tokens": 0,
        "keywords": [
            "a"
        ],
        "index_node_id": "",
        "index_node_hash": "",
        "hit_count": 0,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      },
      "doc_form": "text_model"
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks'
  method='POST'
  title='Create Child Chunk'
  name='#create_child_chunk'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        Document ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        Segment ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='content' type='string' key='content'>
        Child chunk content
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"content": "Child chunk content"}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "content": "Child chunk content"
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": {
        "id": "",
        "segment_id": "",
        "content": "Child chunk content",
        "word_count": 25,
        "tokens": 0,
        "index_node_id": "",
        "index_node_hash": "",
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks'
  method='GET'
  title='Get Child Chunks'
  name='#get_child_chunks'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        Document ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        Segment ID
      </Property>
    </Properties>
    ### Query
    <Properties>
      <Property name='keyword' type='string' key='keyword'>
        Search keyword (optional)
      </Property>
      <Property name='page' type='integer' key='page'>
        Page number (optional, default: 1)
      </Property>
      <Property name='limit' type='integer' key='limit'>
        Items per page (optional, default: 20, max: 100)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks?page=1&limit=20' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks?page=1&limit=20' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": [{
        "id": "",
        "segment_id": "",
        "content": "Child chunk content",
        "word_count": 25,
        "tokens": 0,
        "index_node_id": "",
        "index_node_hash": "",
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }],
      "total": 1,
      "total_pages": 1,
      "page": 1,
      "limit": 20
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}'
  method='DELETE'
  title='Delete Child Chunk'
  name='#delete_child_chunk'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        Document ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        Segment ID
      </Property>
      <Property name='child_chunk_id' type='string' key='child_chunk_id'>
        Child Chunk ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="DELETE"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```text {{ title: 'Response' }}
    204 No Content
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}'
  method='PATCH'
  title='Update Child Chunk'
  name='#update_child_chunk'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        Document ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        Segment ID
      </Property>
      <Property name='child_chunk_id' type='string' key='child_chunk_id'>
        Child Chunk ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='content' type='string' key='content'>
        Child chunk content
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="PATCH"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}"
      targetCode={`curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"content": "Updated child chunk content"}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "content": "Updated child chunk content"
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": {
        "id": "",
        "segment_id": "",
        "content": "Updated child chunk content",
        "word_count": 25,
        "tokens": 0,
        "index_node_id": "",
        "index_node_hash": "",
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/upload-file'
  method='GET'
  title='Get Upload File'
  name='#get_upload_file'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        Document ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}/documents/{document_id}/upload-file"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/upload-file' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/upload-file' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "file_id",
      "name": "file_name",
      "size": 1024,
      "extension": "txt",
      "url": "preview_url",
      "download_url": "download_url",
      "mime_type": "text/plain",
      "created_by": "user_id",
      "created_at": 1728734540,
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/retrieve'
  method='POST'
  title='Retrieve Chunks from a Knowledge Base'
  name='#dataset_retrieval'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='query' type='string' key='query'>
        Query keyword
      </Property>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        Retrieval model (optional, if not filled, it will be recalled according to the default method)
        - <code>search_method</code> (text) Search method: One of the following four keywords is required
          - <code>keyword_search</code> Keyword search
          - <code>semantic_search</code> Semantic search
          - <code>full_text_search</code> Full-text search
          - <code>hybrid_search</code> Hybrid search
        - <code>reranking_enable</code> (bool) Whether to enable reranking, required if the search mode is semantic_search or hybrid_search (optional)
        - <code>reranking_mode</code> (object) Rerank model configuration, required if reranking is enabled
            - <code>reranking_provider_name</code> (string) Rerank model provider
            - <code>reranking_model_name</code> (string) Rerank model name
        - <code>weights</code> (float) Semantic search weight setting in hybrid search mode
        - <code>top_k</code> (integer) Number of results to return (optional)
        - <code>score_threshold_enabled</code> (bool) Whether to enable score threshold
        - <code>score_threshold</code> (float) Score threshold
      </Property>
      <Property name='external_retrieval_model' type='object' key='external_retrieval_model'>
          Unused field
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/retrieve"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/retrieve' \\\n--header 'Authorization: Bearer {api_key}'\\\n--header 'Content-Type: application/json'\\\n--data-raw '{
    "query": "test",
    "retrieval_model": {
        "search_method": "keyword_search",
        "reranking_enable": false,
        "reranking_mode": null,
        "reranking_model": {
            "reranking_provider_name": "",
            "reranking_model_name": ""
        },
        "weights": null,
        "top_k": 1,
        "score_threshold_enabled": false,
        "score_threshold": null
    }
}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/retrieve' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "query": "test",
        "retrieval_model": {
            "search_method": "keyword_search",
            "reranking_enable": false,
            "reranking_mode": null,
            "reranking_model": {
                "reranking_provider_name": "",
                "reranking_model_name": ""
            },
            "weights": null,
            "top_k": 2,
            "score_threshold_enabled": false,
            "score_threshold": null
        }
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "query": {
        "content": "test"
      },
      "records": [
        {
          "segment": {
            "id": "7fa6f24f-8679-48b3-bc9d-bdf28d73f218",
            "position": 1,
            "document_id": "a8c6c36f-9f5d-4d7a-8472-f5d7b75d71d2",
            "content": "Operation guide",
            "answer": null,
            "word_count": 847,
            "tokens": 280,
            "keywords": [
              "install",
              "java",
              "base",
              "scripts",
              "jdk",
              "manual",
              "internal",
              "opens",
              "add",
              "vmoptions"
            ],
            "index_node_id": "39dd8443-d960-45a8-bb46-7275ad7fbc8e",
            "index_node_hash": "0189157697b3c6a418ccf8264a09699f25858975578f3467c76d6bfc94df1d73",
            "hit_count": 0,
            "enabled": true,
            "disabled_at": null,
            "disabled_by": null,
            "status": "completed",
            "created_by": "dbcb1ab5-90c8-41a7-8b78-73b235eb6f6f",
            "created_at": 1728734540,
            "indexing_at": 1728734552,
            "completed_at": 1728734584,
            "error": null,
            "stopped_at": null,
            "document": {
              "id": "a8c6c36f-9f5d-4d7a-8472-f5d7b75d71d2",
              "data_source_type": "upload_file",
              "name": "readme.txt",
            }
          },
          "score": 3.730463140527718e-05,
          "tsne_position": null
        }
      ]
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata'
  method='POST'
  title='Create a Knowledge Metadata'
  name='#create_metadata'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='segment' type='object' key='segment'>
        - <code>type</code> (string) Metadata type, required
        - <code>name</code> (string) Metadata name, required
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/metadata"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/metadata' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'\\\n--data-raw '{"type": "string", "name": "test"}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "abc",
      "type": "string",
      "name": "test",
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata/{metadata_id}'
  method='PATCH'
  title='Update a Knowledge Metadata'
  name='#update_metadata'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='metadata_id' type='string' key='metadata_id'>
        Metadata ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='segment' type='object' key='segment'>
        - <code>name</code> (string) Metadata name, required
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="PATCH"
      label="/datasets/{dataset_id}/metadata/{metadata_id}"
      targetCode={`curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}/metadata/{metadata_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'\\\n--data-raw '{"name": "test"}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "abc",
      "type": "string",
      "name": "test",
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata/{metadata_id}'
  method='DELETE'
  title='Delete a Knowledge Metadata'
  name='#delete_metadata'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='metadata_id' type='string' key='metadata_id'>
        Metadata ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="DELETE"
      label="/datasets/{dataset_id}/metadata/{metadata_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/metadata/{metadata_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata/built-in/{action}'
  method='POST'
  title='Disable Or Enable Built-in Metadata'
  name='#toggle_metadata'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
      <Property name='action' type='string' key='action'>
        disable/enable
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/metadata/built-in/{action}"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/metadata/built-in/{action}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/metadata'
  method='POST'
  title='Update Documents Metadata'
  name='#update_documents_metadata'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='operation_data' type='object list' key='segments'>
        - <code>document_id</code> (string) Document ID
        - <code>metadata_list</code> (list) Metadata list
          - <code>id</code> (string) Metadata ID
          - <code>value</code> (string) Metadata value
          - <code>name</code> (string) Metadata name
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/documents/metadata"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/metadata' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'\\\n--data-raw '{"operation_data": [{"document_id": "document_id", "metadata_list": [{"id": "id", "value": "value", "name": "name"}]}]}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata'
  method='GET'
  title='Get Knowledge Metadata List'
  name='#dataset_metadata_list'
/>
<Row>
  <Col>
    ### Params
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        Knowledge ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}/metadata"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/metadata' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "doc_metadata": [
        {
          "id": "",
          "name": "name",
          "type": "string",
          "use_count": 0,
        },
        ...
      ],
      "built_in_field_enabled": true
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
 url='/workspaces/current/models/model-types/text-embedding'
 method='GET'
 title='Get available embedding models'
 name='#model_type_list'
/>
<Row>
   <Col>
     ### Query
     <Properties>
     </Properties>
   </Col>
   <Col sticky>
     <CodeGroup
       title="Request"
       tag="GET"
       label="/datasets/{dataset_id}"
       targetCode={`curl --location --location --request GET '${props.apiBaseUrl}/workspaces/current/models/model-types/text-embedding' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' `}
     >
     ```bash {{ title: 'cURL' }}
     curl --location --request GET '${props.apiBaseUrl}/workspaces/current/models/model-types/text-embedding' \
     --header 'Authorization: Bearer {api_key}' \
     --header 'Content-Type: application/json' \
     ```
     </CodeGroup>
     <CodeGroup title="Response">
     ```json {{ title: 'Response' }}
     {
       "data": [
           {
               "provider": "zhipuai",
               "label": {
                   "zh_Hans": "智谱 AI",
                   "en_US": "ZHIPU AI"
               },
               "icon_small": {
                   "zh_Hans": "http://127.0.0.1:5001/console/api/workspaces/current/model-providers/zhipuai/icon_small/zh_Hans",
                   "en_US": "http://127.0.0.1:5001/console/api/workspaces/current/model-providers/zhipuai/icon_small/en_US"
               },
               "icon_large": {
                   "zh_Hans": "http://127.0.0.1:5001/console/api/workspaces/current/model-providers/zhipuai/icon_large/zh_Hans",
                   "en_US": "http://127.0.0.1:5001/console/api/workspaces/current/model-providers/zhipuai/icon_large/en_US"
               },
               "status": "active",
               "models": [
                   {
                       "model": "embedding-3",
                       "label": {
                           "zh_Hans": "embedding-3",
                           "en_US": "embedding-3"
                       },
                       "model_type": "text-embedding",
                       "features": null,
                       "fetch_from": "predefined-model",
                       "model_properties": {
                           "context_size": 8192
                       },
                       "deprecated": false,
                       "status": "active",
                       "load_balancing_enabled": false
                   },
                   {
                       "model": "embedding-2",
                       "label": {
                           "zh_Hans": "embedding-2",
                           "en_US": "embedding-2"
                       },
                       "model_type": "text-embedding",
                       "features": null,
                       "fetch_from": "predefined-model",
                       "model_properties": {
                           "context_size": 8192
                       },
                       "deprecated": false,
                       "status": "active",
                       "load_balancing_enabled": false
                   },
                   {
                       "model": "text_embedding",
                       "label": {
                           "zh_Hans": "text_embedding",
                           "en_US": "text_embedding"
                       },
                       "model_type": "text-embedding",
                       "features": null,
                       "fetch_from": "predefined-model",
                       "model_properties": {
                           "context_size": 512
                       },
                       "deprecated": false,
                       "status": "active",
                       "load_balancing_enabled": false
                   }
               ]
           }
       ]
     }
     ```
     </CodeGroup>
   </Col>
</Row>
<hr className='ml-0 mr-0' />
<Row>
  <Col>
    ### Error message
    <Properties>
      <Property name='code' type='string' key='code'>
        Error code
      </Property>
    </Properties>
    <Properties>
      <Property name='status' type='number' key='status'>
        Error status
      </Property>
    </Properties>
    <Properties>
      <Property name='message' type='string' key='message'>
        Error message
      </Property>
    </Properties>
  </Col>
  <Col>
    <CodeGroup title="Example">
    ```json {{ title: 'Response' }}
      {
        "code": "no_file_uploaded",
        "message": "Please upload your file.",
        "status": 400
      }
    ```
    </CodeGroup>
  </Col>
</Row>
<table className="max-w-auto border-collapse border border-slate-400" style={{ maxWidth: 'none', width: 'auto' }}>
  <thead style={{ background: '#f9fafc' }}>
    <tr>
      <th className="p-2 border border-slate-300">code</th>
      <th className="p-2 border border-slate-300">status</th>
      <th className="p-2 border border-slate-300">message</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td className="p-2 border border-slate-300">no_file_uploaded</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">Please upload your file.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">too_many_files</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">Only one file is allowed.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">file_too_large</td>
      <td className="p-2 border border-slate-300">413</td>
      <td className="p-2 border border-slate-300">File size exceeded.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">unsupported_file_type</td>
      <td className="p-2 border border-slate-300">415</td>
      <td className="p-2 border border-slate-300">File type not allowed.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">high_quality_dataset_only</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">Current operation only supports 'high-quality' datasets.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">dataset_not_initialized</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">The dataset is still being initialized or indexing. Please wait a moment.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">archived_document_immutable</td>
      <td className="p-2 border border-slate-300">403</td>
      <td className="p-2 border border-slate-300">The archived document is not editable.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">dataset_name_duplicate</td>
      <td className="p-2 border border-slate-300">409</td>
      <td className="p-2 border border-slate-300">The dataset name already exists. Please modify your dataset name.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">invalid_action</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">Invalid action.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">document_already_finished</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">The document has been processed. Please refresh the page or go to the document details.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">document_indexing</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">The document is being processed and cannot be edited.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">invalid_metadata</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">The metadata content is incorrect. Please check and verify.</td>
    </tr>
  </tbody>
</table>
<div className="pb-4" />
app/(commonLayout)/datasets/template/template.ja.mdx
New file
@@ -0,0 +1,2005 @@
{/**
  * @typedef Props
  * @property {string} apiBaseUrl
  */}
import { CodeGroup } from '@/app/components/develop/code.tsx'
import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstruction, Paragraph } from '@/app/components/develop/md.tsx'
# ナレッジ API
<div>
  ### 認証
  Dify のサービス API は `API-Key` を使用して認証します。
  開発者は、`API-Key` をクライアント側で共有または保存するのではなく、バックエンドに保存することを推奨します。これにより、`API-Key` の漏洩による財産損失を防ぐことができます。
  すべての API リクエストには、以下のように **`Authorization`** HTTP ヘッダーに `API-Key` を含める必要があります:
  <CodeGroup title="コード">
    ```javascript
      Authorization: Bearer {API_KEY}
    ```
  </CodeGroup>
</div>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/document/create-by-text'
  method='POST'
  title='テキストからドキュメントを作成'
  name='#create-by-text'
/>
<Row>
  <Col>
    この API は既存のナレッジに基づいており、このナレッジを基にテキストを使用して新しいドキュメントを作成します。
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
    </Properties>
    ### リクエストボディ
    <Properties>
      <Property name='name' type='string' key='name'>
        ドキュメント名
      </Property>
      <Property name='text' type='string' key='text'>
        ドキュメント内容
      </Property>
      <Property name='indexing_technique' type='string' key='indexing_technique'>
        インデックスモード
          - <code>high_quality</code> 高品質: 埋め込みモデルを使用してベクトルデータベースインデックスを構築
          - <code>economy</code> 経済: キーワードテーブルインデックスの反転インデックスを構築
      </Property>
      <Property name='doc_form' type='string' key='doc_form'>
        インデックス化された内容の形式
          - <code>text_model</code> テキストドキュメントは直接埋め込まれます; `economy` モードではこの形式がデフォルト
          - <code>hierarchical_model</code> 親子モード
          - <code>qa_model</code> Q&A モード: 分割されたドキュメントの質問と回答ペアを生成し、質問を埋め込みます
      </Property>
      <Property name='doc_language' type='string' key='doc_language'>
        Q&A モードでは、ドキュメントの言語を指定します。例: <code>English</code>, <code>Chinese</code>
      </Property>
      <Property name='process_rule' type='object' key='process_rule'>
        処理ルール
          - <code>mode</code> (string) クリーニング、セグメンテーションモード、自動 / カスタム
          - <code>rules</code> (object) カスタムルール (自動モードでは、このフィールドは空)
            - <code>pre_processing_rules</code> (array[object]) 前処理ルール
              - <code>id</code> (string) 前処理ルールの一意識別子
                - 列挙
                  - <code>remove_extra_spaces</code> 連続するスペース、改行、タブを置換
                  - <code>remove_urls_emails</code> URL、メールアドレスを削除
              - <code>enabled</code> (bool) このルールを選択するかどうか。ドキュメント ID が渡されない場合、デフォルト値を表します。
            - <code>segmentation</code> (object) セグメンテーションルール
              - <code>separator</code> カスタムセグメント識別子。現在は 1 つの区切り文字のみ設定可能。デフォルトは \n
              - <code>max_tokens</code> 最大長 (トークン) デフォルトは 1000
            - <code>parent_mode</code> 親チャンクの検索モード: <code>full-doc</code> 全文検索 / <code>paragraph</code> 段落検索
            - <code>subchunk_segmentation</code> (object) 子チャンクルール
              - <code>separator</code> セグメンテーション識別子。現在は 1 つの区切り文字のみ許可。デフォルトは <code>***</code>
              - <code>max_tokens</code> 最大長 (トークン) は親チャンクの長さより短いことを検証する必要があります
              - <code>chunk_overlap</code> 隣接するチャンク間の重複を定義 (オプション)
      </Property>
      <PropertyInstruction>ナレッジベースにパラメータが設定されていない場合、最初のアップロードには以下のパラメータを提供する必要があります。提供されない場合、デフォルトパラメータが使用されます。</PropertyInstruction>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        検索モデル
          - <code>search_method</code> (string) 検索方法
            - <code>hybrid_search</code> ハイブリッド検索
            - <code>semantic_search</code> セマンティック検索
            - <code>full_text_search</code> 全文検索
          - <code>reranking_enable</code> (bool) 再ランキングを有効にするかどうか
          - <code>reranking_mode</code> (object) 再ランキングモデル構成
            - <code>reranking_provider_name</code> (string) 再ランキングモデルプロバイダー
            - <code>reranking_model_name</code> (string) 再ランキングモデル名
          - <code>top_k</code> (int) 返される結果の数
          - <code>score_threshold_enabled</code> (bool) スコア閾値を有効にするかどうか
          - <code>score_threshold</code> (float) スコア閾値
      </Property>
      <Property name='embedding_model' type='string' key='embedding_model'>
        埋め込みモデル名
      </Property>
      <Property name='embedding_model_provider' type='string' key='embedding_model_provider'>
        埋め込みモデルプロバイダー
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="POST"
      label="/datasets/{dataset_id}/document/create-by-text"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/document/create-by-text' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"name": "text","text": "text","indexing_technique": "high_quality","process_rule": {"mode": "automatic"}}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/document/create-by-text' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "name": "text",
        "text": "text",
        "indexing_technique": "high_quality",
        "process_rule": {
            "mode": "automatic"
        }
    }'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "document": {
        "id": "",
        "position": 1,
        "data_source_type": "upload_file",
        "data_source_info": {
            "upload_file_id": ""
        },
        "dataset_process_rule_id": "",
        "name": "text.txt",
        "created_from": "api",
        "created_by": "",
        "created_at": 1695690280,
        "tokens": 0,
        "indexing_status": "waiting",
        "error": null,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "archived": false,
        "display_status": "queuing",
        "word_count": 0,
        "hit_count": 0,
        "doc_form": "text_model"
      },
      "batch": ""
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/document/create-by-file'
  method='POST'
  title='ファイルからドキュメントを作成'
  name='#create-by-file'
/>
<Row>
  <Col>
    この API は既存のナレッジに基づいており、このナレッジを基にファイルを使用して新しいドキュメントを作成します。
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
    </Properties>
    ### リクエストボディ
    <Properties>
      <Property name='data' type='multipart/form-data json string' key='data'>
        - <code>original_document_id</code> 元のドキュメント ID (オプション)
          - ドキュメントを再アップロードまたはクリーニングとセグメンテーション構成を変更するために使用されます。欠落している情報は元のドキュメントからコピーされます。
          - 元のドキュメントはアーカイブされたドキュメントであってはなりません。
          - original_document_id が渡された場合、更新操作が実行されます。process_rule は入力可能な項目です。入力されない場合、元のドキュメントのセグメンテーション方法がデフォルトで使用されます。
          - original_document_id が渡されない場合、新しい操作が実行され、process_rule が必要です。
        - <code>indexing_technique</code> インデックスモード
          - <code>high_quality</code> 高品質: 埋め込みモデルを使用してベクトルデータベースインデックスを構築
          - <code>economy</code> 経済: キーワードテーブルインデックスの反転インデックスを構築
        - <code>doc_form</code> インデックス化された内容の形式
          - <code>text_model</code> テキストドキュメントは直接埋め込まれます; `economy` モードではこの形式がデフォルト
          - <code>hierarchical_model</code> 親子モード
          - <code>qa_model</code> Q&A モード: 分割されたドキュメントの質問と回答ペアを生成し、質問を埋め込みます
        - <code>doc_language</code> Q&A モードでは、ドキュメントの言語を指定します。例: <code>English</code>, <code>Chinese</code>
        - <code>process_rule</code> 処理ルール
          - <code>mode</code> (string) クリーニング、セグメンテーションモード、自動 / カスタム
          - <code>rules</code> (object) カスタムルール (自動モードでは、このフィールドは空)
            - <code>pre_processing_rules</code> (array[object]) 前処理ルール
              - <code>id</code> (string) 前処理ルールの一意識別子
                - 列挙
                  - <code>remove_extra_spaces</code> 連続するスペース、改行、タブを置換
                  - <code>remove_urls_emails</code> URL、メールアドレスを削除
              - <code>enabled</code> (bool) このルールを選択するかどうか。ドキュメント ID が渡されない場合、デフォルト値を表します。
            - <code>segmentation</code> (object) セグメンテーションルール
              - <code>separator</code> カスタムセグメント識別子。現在は 1 つの区切り文字のみ設定可能。デフォルトは \n
              - <code>max_tokens</code> 最大長 (トークン) デフォルトは 1000
            - <code>parent_mode</code> 親チャンクの検索モード: <code>full-doc</code> 全文検索 / <code>paragraph</code> 段落検索
            - <code>subchunk_segmentation</code> (object) 子チャンクルール
              - <code>separator</code> セグメンテーション識別子。現在は 1 つの区切り文字のみ許可。デフォルトは <code>***</code>
              - <code>max_tokens</code> 最大長 (トークン) は親チャンクの長さより短いことを検証する必要があります
              - <code>chunk_overlap</code> 隣接するチャンク間の重複を定義 (オプション)
      </Property>
      <Property name='file' type='multipart/form-data' key='file'>
        アップロードする必要があるファイル。
      </Property>
      <PropertyInstruction>ナレッジベースにパラメータが設定されていない場合、最初のアップロードには以下のパラメータを提供する必要があります。提供されない場合、デフォルトパラメータが使用されます。</PropertyInstruction>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        検索モデル
          - <code>search_method</code> (string) 検索方法
            - <code>hybrid_search</code> ハイブリッド検索
            - <code>semantic_search</code> セマンティック検索
            - <code>full_text_search</code> 全文検索
          - <code>reranking_enable</code> (bool) 再ランキングを有効にするかどうか
          - <code>reranking_mode</code> (object) 再ランキングモデル構成
            - <code>reranking_provider_name</code> (string) 再ランキングモデルプロバイダー
            - <code>reranking_model_name</code> (string) 再ランキングモデル名
          - <code>top_k</code> (int) 返される結果の数
          - <code>score_threshold_enabled</code> (bool) スコア閾値を有効にするかどうか
          - <code>score_threshold</code> (float) スコア閾値
      </Property>
      <Property name='embedding_model' type='string' key='embedding_model'>
        埋め込みモデル名
      </Property>
      <Property name='embedding_model_provider' type='string' key='embedding_model_provider'>
        埋め込みモデルプロバイダー
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="POST"
      label="/datasets/{dataset_id}/document/create-by-file"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/document/create-by-file' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'data="{"indexing_technique":"high_quality","process_rule":{"rules":{"pre_processing_rules":[{"id":"remove_extra_spaces","enabled":true},{"id":"remove_urls_emails","enabled":true}],"segmentation":{"separator":"###","max_tokens":500}},"mode":"custom"}}";type=text/plain' \\\n--form 'file=@"/path/to/file"'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/document/create-by-file' \
    --header 'Authorization: Bearer {api_key}' \
    --form 'data="{\"name\":\"Dify\",\"indexing_technique\":\"high_quality\",\"process_rule\":{\"rules\":{\"pre_processing_rules\":[{\"id\":\"remove_extra_spaces\",\"enabled\":true},{\"id\":\"remove_urls_emails\",\"enabled\":true}],\"segmentation\":{\"separator\":\"###\",\"max_tokens\":500}},\"mode\":\"custom\"}}";type=text/plain' \
    --form 'file=@"/path/to/file"'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "document": {
        "id": "",
        "position": 1,
        "data_source_type": "upload_file",
        "data_source_info": {
          "upload_file_id": ""
        },
        "dataset_process_rule_id": "",
        "name": "Dify.txt",
        "created_from": "api",
        "created_by": "",
        "created_at": 1695308667,
        "tokens": 0,
        "indexing_status": "waiting",
        "error": null,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "archived": false,
        "display_status": "queuing",
        "word_count": 0,
        "hit_count": 0,
        "doc_form": "text_model"
      },
      "batch": ""
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets'
  method='POST'
  title='空のナレッジベースを作成'
  name='#create_empty_dataset'
/>
<Row>
  <Col>
    ### リクエストボディ
    <Properties>
      <Property name='name' type='string' key='name'>
        ナレッジ名
      </Property>
      <Property name='description' type='string' key='description'>
        ナレッジの説明 (オプション)
      </Property>
      <Property name='indexing_technique' type='string' key='indexing_technique'>
        インデックス技術 (オプション)
          - <code>high_quality</code> 高品質
          - <code>economy</code> 経済
      </Property>
      <Property name='permission' type='string' key='permission'>
        権限
          - <code>only_me</code> 自分のみ
          - <code>all_team_members</code> すべてのチームメンバー
          - <code>partial_members</code> 一部のメンバー
      </Property>
      <Property name='provider' type='string' key='provider'>
        プロバイダー (オプション、デフォルト: vendor)
          - <code>vendor</code> ベンダー
          - <code>external</code> 外部ナレッジ
      </Property>
      <Property name='external_knowledge_api_id' type='str' key='external_knowledge_api_id'>
        外部ナレッジ API ID (オプション)
      </Property>
      <Property name='external_knowledge_id' type='str' key='external_knowledge_id'>
        外部ナレッジ ID (オプション)
      </Property>
      <Property name='embedding_model' type='str' key='embedding_model'>
        埋め込みモデル名(任意)
      </Property>
      <Property name='embedding_model_provider' type='str' key='embedding_model_provider'>
        埋め込みモデルのプロバイダ名(任意)
      </Property>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        検索モデル(任意)
          - <code>search_method</code> (文字列) 検索方法
            - <code>hybrid_search</code> ハイブリッド検索
            - <code>semantic_search</code> セマンティック検索
            - <code>full_text_search</code> 全文検索
          - <code>reranking_enable</code> (ブール値) リランキングを有効にするかどうか
          - <code>reranking_model</code> (オブジェクト) リランクモデルの設定
              - <code>reranking_provider_name</code> (文字列) リランクモデルのプロバイダ
              - <code>reranking_model_name</code> (文字列) リランクモデル名
          - <code>top_k</code> (整数) 返される結果の数
          - <code>score_threshold_enabled</code> (ブール値) スコア閾値を有効にするかどうか
          - <code>score_threshold</code> (浮動小数点数) スコア閾値
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="POST"
      label="/datasets"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"name": "name", "permission": "only_me"}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${apiBaseUrl}/v1/datasets' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "name": "name",
      "permission": "only_me"
    }'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "id": "",
      "name": "name",
      "description": null,
      "provider": "vendor",
      "permission": "only_me",
      "data_source_type": null,
      "indexing_technique": null,
      "app_count": 0,
      "document_count": 0,
      "word_count": 0,
      "created_by": "",
      "created_at": 1695636173,
      "updated_by": "",
      "updated_at": 1695636173,
      "embedding_model": null,
      "embedding_model_provider": null,
      "embedding_available": null
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets'
  method='GET'
  title='ナレッジベースリストを取得'
  name='#dataset_list'
/>
<Row>
  <Col>
    ### クエリ
    <Properties>
      <Property name='keyword' type='string' key='keyword'>
        検索キーワード、オプション
      </Property>
      <Property name='tag_ids' type='array[string]' key='tag_ids'>
        タグIDリスト、オプション
      </Property>
      <Property name='page' type='string' key='page'>
        ページ番号、オプション、デフォルト1
      </Property>
      <Property name='limit' type='string' key='limit'>
        返されるアイテム数、オプション、デフォルト20、範囲1-100
      </Property>
      <Property name='include_all' type='boolean' key='include_all'>
        すべてのデータセットを含めるかどうか(所有者のみ有効)、オプション、デフォルトはfalse
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="GET"
      label="/datasets"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets?page=1&limit=20' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets?page=1&limit=20' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "data": [
        {
          "id": "",
          "name": "name",
          "description": "desc",
          "permission": "only_me",
          "data_source_type": "upload_file",
          "indexing_technique": "",
          "app_count": 2,
          "document_count": 10,
          "word_count": 1200,
          "created_by": "",
          "created_at": "",
          "updated_by": "",
          "updated_at": ""
        },
        ...
      ],
      "has_more": true,
      "limit": 20,
      "total": 50,
      "page": 1
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}'
  method='DELETE'
  title='ナレッジベースを削除'
  name='#delete_dataset'
/>
<Row>
  <Col>
    ### パラメータ
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="DELETE"
      label="/datasets/{dataset_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```text {{ title: 'レスポンス' }}
    204 No Content
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/update-by-text'
  method='POST'
  title='テキストでドキュメントを更新'
  name='#update-by-text'
/>
<Row>
  <Col>
    この API は既存のナレッジに基づいており、このナレッジを基にテキストを使用してドキュメントを更新します。
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        ドキュメント ID
      </Property>
    </Properties>
    ### リクエストボディ
    <Properties>
      <Property name='name' type='string' key='name'>
        ドキュメント名 (オプション)
      </Property>
      <Property name='text' type='string' key='text'>
        ドキュメント内容 (オプション)
      </Property>
      <Property name='process_rule' type='object' key='process_rule'>
        処理ルール
          - <code>mode</code> (string) クリーニング、セグメンテーションモード、自動 / カスタム
          - <code>rules</code> (object) カスタムルール (自動モードでは、このフィールドは空)
            - <code>pre_processing_rules</code> (array[object]) 前処理ルール
              - <code>id</code> (string) 前処理ルールの一意識別子
                - 列挙
                  - <code>remove_extra_spaces</code> 連続するスペース、改行、タブを置換
                  - <code>remove_urls_emails</code> URL、メールアドレスを削除
              - <code>enabled</code> (bool) このルールを選択するかどうか。ドキュメント ID が渡されない場合、デフォルト値を表します。
            - <code>segmentation</code> (object) セグメンテーションルール
              - <code>separator</code> カスタムセグメント識別子。現在は 1 つの区切り文字のみ設定可能。デフォルトは \n
              - <code>max_tokens</code> 最大長 (トークン) デフォルトは 1000
            - <code>parent_mode</code> 親チャンクの検索モード: <code>full-doc</code> 全文検索 / <code>paragraph</code> 段落検索
            - <code>subchunk_segmentation</code> (object) 子チャンクルール
              - <code>separator</code> セグメンテーション識別子。現在は 1 つの区切り文字のみ許可。デフォルトは <code>***</code>
              - <code>max_tokens</code> 最大長 (トークン) は親チャンクの長さより短いことを検証する必要があります
              - <code>chunk_overlap</code> 隣接するチャンク間の重複を定義 (オプション)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/update-by-text"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/update-by-text' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"name": "name","text": "text"}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/update-by-text' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "name": "name",
        "text": "text"
    }'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "document": {
        "id": "",
        "position": 1,
        "data_source_type": "upload_file",
        "data_source_info": {
          "upload_file_id": ""
        },
        "dataset_process_rule_id": "",
        "name": "name.txt",
        "created_from": "api",
        "created_by": "",
        "created_at": 1695308667,
        "tokens": 0,
        "indexing_status": "waiting",
        "error": null,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "archived": false,
        "display_status": "queuing",
        "word_count": 0,
        "hit_count": 0,
        "doc_form": "text_model"
      },
      "batch": ""
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/update-by-file'
  method='POST'
  title='ファイルでドキュメントを更新'
  name='#update-by-file'
/>
<Row>
  <Col>
    この API は既存のナレッジに基づいており、このナレッジを基にファイルを使用してドキュメントを更新します。
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        ドキュメント ID
      </Property>
    </Properties>
    ### リクエストボディ
    <Properties>
      <Property name='name' type='string' key='name'>
        ドキュメント名 (オプション)
      </Property>
      <Property name='file' type='multipart/form-data' key='file'>
        アップロードするファイル
      </Property>
      <Property name='process_rule' type='object' key='process_rule'>
        処理ルール
          - <code>mode</code> (string) クリーニング、セグメンテーションモード、自動 / カスタム
          - <code>rules</code> (object) カスタムルール (自動モードでは、このフィールドは空)
            - <code>pre_processing_rules</code> (array[object]) 前処理ルール
              - <code>id</code> (string) 前処理ルールの一意識別子
                - 列挙
                  - <code>remove_extra_spaces</code> 連続するスペース、改行、タブを置換
                  - <code>remove_urls_emails</code> URL、メールアドレスを削除
              - <code>enabled</code> (bool) このルールを選択するかどうか。ドキュメント ID が渡されない場合、デフォルト値を表します。
            - <code>segmentation</code> (object) セグメンテーションルール
              - <code>separator</code> カスタムセグメント識別子。現在は 1 つの区切り文字のみ設定可能。デフォルトは \n
              - <code>max_tokens</code> 最大長 (トークン) デフォルトは 1000
            - <code>parent_mode</code> 親チャンクの検索モード: <code>full-doc</code> 全文検索 / <code>paragraph</code> 段落検索
            - <code>subchunk_segmentation</code> (object) 子チャンクルール
              - <code>separator</code> セグメンテーション識別子。現在は 1 つの区切り文字のみ許可。デフォルトは <code>***</code>
              - <code>max_tokens</code> 最大長 (トークン) は親チャンクの長さより短いことを検証する必要があります
              - <code>chunk_overlap</code> 隣接するチャンク間の重複を定義 (オプション)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/update-by-file"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/update-by-file' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'data="{"name":"Dify","indexing_technique":"high_quality","process_rule":{"rules":{"pre_processing_rules":[{"id":"remove_extra_spaces","enabled":true},{"id":"remove_urls_emails","enabled":true}],"segmentation":{"separator":"###","max_tokens":500}},"mode":"custom"}}";type=text/plain' \\\n--form 'file=@"/path/to/file"'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/update-by-file' \
    --header 'Authorization: Bearer {api_key}' \
    --form 'data="{\"name\":\"Dify\",\"indexing_technique\":\"high_quality\",\"process_rule\":{\"rules\":{\"pre_processing_rules\":[{\"id\":\"remove_extra_spaces\",\"enabled\":true},{\"id\":\"remove_urls_emails\",\"enabled\":true}],\"segmentation\":{\"separator\":\"###\",\"max_tokens\":500}},\"mode\":\"custom\"}}";type=text/plain' \
    --form 'file=@"/path/to/file"'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "document": {
        "id": "",
        "position": 1,
        "data_source_type": "upload_file",
        "data_source_info": {
          "upload_file_id": ""
        },
        "dataset_process_rule_id": "",
        "name": "Dify.txt",
        "created_from": "api",
        "created_by": "",
        "created_at": 1695308667,
        "tokens": 0,
        "indexing_status": "waiting",
        "error": null,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "archived": false,
        "display_status": "queuing",
        "word_count": 0,
        "hit_count": 0,
        "doc_form": "text_model"
      },
      "batch": "20230921150427533684"
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{batch}/indexing-status'
  method='GET'
  title='ドキュメントの埋め込みステータス (進行状況) を取得'
  name='#indexing_status'
/>
<Row>
  <Col>
    ### パラメータ
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='batch' type='string' key='batch'>
        アップロードされたドキュメントのバッチ番号
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="GET"
      label="/datasets/{dataset_id}/documents/{batch}/indexing-status"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{batch}/indexing-status' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{batch}/indexing-status' \
    --header 'Authorization: Bearer {api_key}' \
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "data":[{
        "id": "",
        "indexing_status": "indexing",
        "processing_started_at": 1681623462.0,
        "parsing_completed_at": 1681623462.0,
        "cleaning_completed_at": 1681623462.0,
        "splitting_completed_at": 1681623462.0,
        "completed_at": null,
        "paused_at": null,
        "error": null,
        "stopped_at": null,
        "completed_segments": 24,
        "total_segments": 100
      }]
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}'
  method='DELETE'
  title='ドキュメントを削除'
  name='#delete_document'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        ドキュメント ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="DELETE"
      label="/datasets/{dataset_id}/documents/{document_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}' \
    --header 'Authorization: Bearer {api_key}' \
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```text {{ title: 'レスポンス' }}
    204 No Content
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents'
  method='GET'
  title='ナレッジベースのドキュメントリストを取得'
  name='#dataset_document_list'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
    </Properties>
    ### クエリ
    <Properties>
      <Property name='keyword' type='string' key='keyword'>
        検索キーワード、現在はドキュメント名のみ検索 (オプション)
      </Property>
      <Property name='page' type='string' key='page'>
        ページ番号 (オプション)
      </Property>
      <Property name='limit' type='string' key='limit'>
        返されるアイテム数、デフォルトは 20、範囲は 1-100 (オプション)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="GET"
      label="/datasets/{dataset_id}/documents"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents' \
    --header 'Authorization: Bearer {api_key}' \
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "data": [
        {
          "id": "",
          "position": 1,
          "data_source_type": "file_upload",
          "data_source_info": null,
          "dataset_process_rule_id": null,
          "name": "dify",
          "created_from": "",
          "created_by": "",
          "created_at": 1681623639,
          "tokens": 0,
          "indexing_status": "waiting",
          "error": null,
          "enabled": true,
          "disabled_at": null,
          "disabled_by": null,
          "archived": false
        },
      ],
      "has_more": false,
      "limit": 20,
      "total": 9,
      "page": 1
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments'
  method='POST'
  title='ドキュメントにチャンクを追加'
  name='#create_new_segment'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        ドキュメント ID
      </Property>
    </Properties>
    ### リクエストボディ
    <Properties>
      <Property name='segments' type='object list' key='segments'>
        - <code>content</code> (text) テキスト内容 / 質問内容、必須
        - <code>answer</code> (text) 回答内容、ナレッジのモードが Q&A モードの場合に値を渡します (オプション)
        - <code>keywords</code> (list) キーワード (オプション)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/segments"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"segments": [{"content": "1","answer": "1","keywords": ["a"]}]}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "segments": [
        {
          "content": "1",
          "answer": "1",
          "keywords": ["a"]
        }
      ]
    }'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "data": [{
        "id": "",
        "position": 1,
        "document_id": "",
        "content": "1",
        "answer": "1",
        "word_count": 25,
        "tokens": 0,
        "keywords": [
          "a"
        ],
        "index_node_id": "",
        "index_node_hash": "",
        "hit_count": 0,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }],
      "doc_form": "text_model"
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments'
  method='GET'
  title='ドキュメントからチャンクを取得'
  name='#get_segment'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        ドキュメント ID
      </Property>
    </Properties>
     ### クエリ
    <Properties>
      <Property name='keyword' type='string' key='keyword'>
        キーワード (オプション)
      </Property>
      <Property name='status' type='string' key='status'>
        検索ステータス、completed
      </Property>
      <Property name='page' type='string' key='page'>
        ページ番号 (オプション)
      </Property>
      <Property name='limit' type='string' key='limit'>
        返されるアイテム数、デフォルトは 20、範囲は 1-100 (オプション)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="GET"
      label="/datasets/{dataset_id}/documents/{document_id}/segments"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "data": [{
        "id": "",
        "position": 1,
        "document_id": "",
        "content": "1",
        "answer": "1",
        "word_count": 25,
        "tokens": 0,
        "keywords": [
            "a"
        ],
        "index_node_id": "",
        "index_node_hash": "",
        "hit_count": 0,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }],
      "doc_form": "text_model",
      "has_more": false,
      "limit": 20,
      "total": 9,
      "page": 1
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}'
  method='DELETE'
  title='ドキュメント内のチャンクを削除'
  name='#delete_segment'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        ドキュメント ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        ドキュメントセグメント ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="DELETE"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```text {{ title: 'レスポンス' }}
    204 No Content
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}'
  method='POST'
  title='ドキュメント内のチャンクを更新'
  name='#update_segment'
/>
<Row>
  <Col>
    ### POST
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        ドキュメント ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        ドキュメントセグメント ID
      </Property>
    </Properties>
    ### リクエストボディ
    <Properties>
      <Property name='segment' type='object' key='segment'>
        - <code>content</code> (text) テキスト内容 / 質問内容、必須
        - <code>answer</code> (text) 回答内容、ナレッジが Q&A モードの場合に値を渡します (オプション)
        - <code>keywords</code> (list) キーワード (オプション)
        - <code>enabled</code> (bool) False / true (オプション)
        - <code>regenerate_child_chunks</code> (bool) 子チャンクを再生成するかどうか (オプション)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'\\\n--data-raw '{\"segment\": {\"content\": \"1\",\"answer\": \"1\", \"keywords\": [\"a\"], \"enabled\": false}}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "segment": {
          "content": "1",
          "answer": "1",
          "keywords": ["a"],
          "enabled": false
      }
    }'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "data": {
        "id": "",
        "position": 1,
        "document_id": "",
        "content": "1",
        "answer": "1",
        "word_count": 25,
        "tokens": 0,
        "keywords": [
            "a"
        ],
        "index_node_id": "",
        "index_node_hash": "",
        "hit_count": 0,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      },
      "doc_form": "text_model"
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks'
  method='POST'
  title='子チャンクを作成'
  name='#create_child_chunk'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        ドキュメント ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        セグメント ID
      </Property>
    </Properties>
    ### リクエストボディ
    <Properties>
      <Property name='content' type='string' key='content'>
        子チャンクの内容
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"content": "Child chunk content"}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "content": "Child chunk content"
    }'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "data": {
        "id": "",
        "segment_id": "",
        "content": "Child chunk content",
        "word_count": 25,
        "tokens": 0,
        "index_node_id": "",
        "index_node_hash": "",
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks'
  method='GET'
  title='子チャンクを取得'
  name='#get_child_chunks'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        ドキュメント ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        セグメント ID
      </Property>
    </Properties>
    ### クエリ
    <Properties>
      <Property name='keyword' type='string' key='keyword'>
        検索キーワード (オプション)
      </Property>
      <Property name='page' type='integer' key='page'>
        ページ番号 (オプション、デフォルト: 1)
      </Property>
      <Property name='limit' type='integer' key='limit'>
        ページあたりのアイテム数 (オプション、デフォルト: 20、最大: 100)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="GET"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks?page=1&limit=20' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks?page=1&limit=20' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "data": [{
        "id": "",
        "segment_id": "",
        "content": "Child chunk content",
        "word_count": 25,
        "tokens": 0,
        "index_node_id": "",
        "index_node_hash": "",
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }],
      "total": 1,
      "total_pages": 1,
      "page": 1,
      "limit": 20
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}'
  method='DELETE'
  title='子チャンクを削除'
  name='#delete_child_chunk'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        ドキュメント ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        セグメント ID
      </Property>
      <Property name='child_chunk_id' type='string' key='child_chunk_id'>
        子チャンク ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="DELETE"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```text {{ title: 'レスポンス' }}
    204 No Content
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}'
  method='PATCH'
  title='子チャンクを更新'
  name='#update_child_chunk'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        ドキュメント ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        セグメント ID
      </Property>
      <Property name='child_chunk_id' type='string' key='child_chunk_id'>
        子チャンク ID
      </Property>
    </Properties>
    ### リクエストボディ
    <Properties>
      <Property name='content' type='string' key='content'>
        子チャンクの内容
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="PATCH"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}"
      targetCode={`curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"content": "Updated child chunk content"}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "content": "Updated child chunk content"
    }'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "data": {
        "id": "",
        "segment_id": "",
        "content": "Updated child chunk content",
        "word_count": 25,
        "tokens": 0,
        "index_node_id": "",
        "index_node_hash": "",
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/upload-file'
  method='GET'
  title='アップロードファイルを取得'
  name='#get_upload_file'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        ドキュメント ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="GET"
      label="/datasets/{dataset_id}/documents/{document_id}/upload-file"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/upload-file' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/upload-file' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "id": "file_id",
      "name": "file_name",
      "size": 1024,
      "extension": "txt",
      "url": "preview_url",
      "download_url": "download_url",
      "mime_type": "text/plain",
      "created_by": "user_id",
      "created_at": 1728734540,
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/retrieve'
  method='POST'
  title='ナレッジベースからチャンクを取得'
  name='#dataset_retrieval'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
    </Properties>
    ### リクエストボディ
    <Properties>
      <Property name='query' type='string' key='query'>
        クエリキーワード
      </Property>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        検索モデル (オプション、入力されない場合はデフォルトの方法でリコールされます)
        - <code>search_method</code> (text) 検索方法: 以下の 4 つのキーワードのいずれかが必要です
          - <code>keyword_search</code> キーワード検索
          - <code>semantic_search</code> セマンティック検索
          - <code>full_text_search</code> 全文検索
          - <code>hybrid_search</code> ハイブリッド検索
        - <code>reranking_enable</code> (bool) 再ランキングを有効にするかどうか、検索モードが semantic_search または hybrid_search の場合に必須 (オプション)
        - <code>reranking_mode</code> (object) 再ランキングモデル構成、再ランキングが有効な場合に必須
            - <code>reranking_provider_name</code> (string) 再ランキングモデルプロバイダー
            - <code>reranking_model_name</code> (string) 再ランキングモデル名
        - <code>weights</code> (float) ハイブリッド検索モードでのセマンティック検索の重み設定
        - <code>top_k</code> (integer) 返される結果の数 (オプション)
        - <code>score_threshold_enabled</code> (bool) スコア閾値を有効にするかどうか
        - <code>score_threshold</code> (float) スコア閾値
      </Property>
      <Property name='external_retrieval_model' type='object' key='external_retrieval_model'>
          未使用フィールド
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="POST"
      label="/datasets/{dataset_id}/retrieve"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/retrieve' \\\n--header 'Authorization: Bearer {api_key}'\\\n--header 'Content-Type: application/json'\\\n--data-raw '{
    "query": "test",
    "retrieval_model": {
        "search_method": "keyword_search",
        "reranking_enable": false,
        "reranking_mode": null,
        "reranking_model": {
            "reranking_provider_name": "",
            "reranking_model_name": ""
        },
        "weights": null,
        "top_k": 1,
        "score_threshold_enabled": false,
        "score_threshold": null
    }
}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/retrieve' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "query": "test",
        "retrieval_model": {
            "search_method": "keyword_search",
            "reranking_enable": false,
            "reranking_mode": null,
            "reranking_model": {
                "reranking_provider_name": "",
                "reranking_model_name": ""
            },
            "weights": null,
            "top_k": 2,
            "score_threshold_enabled": false,
            "score_threshold": null
        }
    }'
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "query": {
        "content": "test"
      },
      "records": [
        {
          "segment": {
            "id": "7fa6f24f-8679-48b3-bc9d-bdf28d73f218",
            "position": 1,
            "document_id": "a8c6c36f-9f5d-4d7a-8472-f5d7b75d71d2",
            "content": "Operation guide",
            "answer": null,
            "word_count": 847,
            "tokens": 280,
            "keywords": [
              "install",
              "java",
              "base",
              "scripts",
              "jdk",
              "manual",
              "internal",
              "opens",
              "add",
              "vmoptions"
            ],
            "index_node_id": "39dd8443-d960-45a8-bb46-7275ad7fbc8e",
            "index_node_hash": "0189157697b3c6a418ccf8264a09699f25858975578f3467c76d6bfc94df1d73",
            "hit_count": 0,
            "enabled": true,
            "disabled_at": null,
            "disabled_by": null,
            "status": "completed",
            "created_by": "dbcb1ab5-90c8-41a7-8b78-73b235eb6f6f",
            "created_at": 1728734540,
            "indexing_at": 1728734552,
            "completed_at": 1728734584,
            "error": null,
            "stopped_at": null,
            "document": {
              "id": "a8c6c36f-9f5d-4d7a-8472-f5d7b75d71d2",
              "data_source_type": "upload_file",
              "name": "readme.txt",
            }
          },
          "score": 3.730463140527718e-05,
          "tsne_position": null
        }
      ]
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata'
  method='POST'
  title='ナレッジメタデータを作成'
  name='#create_metadata'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
    </Properties>
    ### リクエストボディ
    <Properties>
      <Property name='segment' type='object' key='segment'>
        - <code>type</code> (string) メタデータの種類、必須
        - <code>name</code> (string) メタデータの名前、必須
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="POST"
      label="/datasets/{dataset_id}/metadata"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/metadata' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'\\\n--data-raw '{"type": "string", "name": "test"}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "id": "abc",
      "type": "string",
      "name": "test",
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata/{metadata_id}'
  method='PATCH'
  title='ナレッジメタデータを更新'
  name='#update_metadata'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='metadata_id' type='string' key='metadata_id'>
        メタデータ ID
      </Property>
    </Properties>
    ### リクエストボディ
    <Properties>
      <Property name='segment' type='object' key='segment'>
        - <code>name</code> (string) メタデータの名前、必須
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="PATCH"
      label="/datasets/{dataset_id}/metadata/{metadata_id}"
      targetCode={`curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}/metadata/{metadata_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'\\\n--data-raw '{"name": "test"}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "id": "abc",
      "type": "string",
      "name": "test",
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata/{metadata_id}'
  method='DELETE'
  title='ナレッジメタデータを削除'
  name='#delete_metadata'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='metadata_id' type='string' key='metadata_id'>
        メタデータ ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="DELETE"
      label="/datasets/{dataset_id}/metadata/{metadata_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/metadata/{metadata_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata/built-in/{action}'
  method='POST'
  title='組み込みメタデータを無効化または有効化'
  name='#toggle_metadata'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
      <Property name='action' type='string' key='action'>
        disable/enable
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="POST"
      label="/datasets/{dataset_id}/metadata/built-in/{action}"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/metadata/built-in/{action}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/metadata'
  method='POST'
  title='ドキュメントメタデータを更新'
  name='#update_documents_metadata'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
    </Properties>
    ### リクエストボディ
    <Properties>
      <Property name='operation_data' type='object list' key='segments'>
        - <code>document_id</code> (string) ドキュメント ID
        - <code>metadata_list</code> (list) メタデータリスト
          - <code>id</code> (string) メタデータ ID
          - <code>value</code> (string) メタデータの値
          - <code>name</code> (string) メタデータの名前
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="POST"
      label="/datasets/{dataset_id}/documents/metadata"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/metadata' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'\\\n--data-raw '{"operation_data": [{"document_id": "document_id", "metadata_list": [{"id": "id", "value": "value", "name": "name"}]}]}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata'
  method='GET'
  title='ナレッジメタデータリストを取得'
  name='#dataset_metadata_list'
/>
<Row>
  <Col>
    ### パス
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        ナレッジ ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="リクエスト"
      tag="GET"
      label="/datasets/{dataset_id}/metadata"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/metadata' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
    <CodeGroup title="レスポンス">
    ```json {{ title: 'Response' }}
    {
      "doc_metadata": [
        {
          "id": "",
          "name": "name",
          "type": "string",
          "use_count": 0,
        },
        ...
      ],
      "built_in_field_enabled": true
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Row>
  <Col>
    ### エラーメッセージ
    <Properties>
      <Property name='code' type='string' key='code'>
        エラーコード
      </Property>
    </Properties>
    <Properties>
      <Property name='status' type='number' key='status'>
        エラーステータス
      </Property>
    </Properties>
    <Properties>
      <Property name='message' type='string' key='message'>
        エラーメッセージ
      </Property>
    </Properties>
  </Col>
  <Col>
    <CodeGroup title="例">
    ```json {{ title: 'Response' }}
      {
        "code": "no_file_uploaded",
        "message": "Please upload your file.",
        "status": 400
      }
    ```
    </CodeGroup>
  </Col>
</Row>
<table className="max-w-auto border-collapse border border-slate-400" style={{ maxWidth: 'none', width: 'auto' }}>
  <thead style={{ background: '#f9fafc' }}>
    <tr>
      <th className="p-2 border border-slate-300">code</th>
      <th className="p-2 border border-slate-300">status</th>
      <th className="p-2 border border-slate-300">message</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td className="p-2 border border-slate-300">no_file_uploaded</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">Please upload your file.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">too_many_files</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">Only one file is allowed.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">file_too_large</td>
      <td className="p-2 border border-slate-300">413</td>
      <td className="p-2 border border-slate-300">File size exceeded.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">unsupported_file_type</td>
      <td className="p-2 border border-slate-300">415</td>
      <td className="p-2 border border-slate-300">File type not allowed.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">high_quality_dataset_only</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">Current operation only supports 'high-quality' datasets.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">dataset_not_initialized</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">The dataset is still being initialized or indexing. Please wait a moment.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">archived_document_immutable</td>
      <td className="p-2 border border-slate-300">403</td>
      <td className="p-2 border border-slate-300">The archived document is not editable.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">dataset_name_duplicate</td>
      <td className="p-2 border border-slate-300">409</td>
      <td className="p-2 border border-slate-300">The dataset name already exists. Please modify your dataset name.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">invalid_action</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">Invalid action.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">document_already_finished</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">The document has been processed. Please refresh the page or go to the document details.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">document_indexing</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">The document is being processed and cannot be edited.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">invalid_metadata</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">The metadata content is incorrect. Please check and verify.</td>
    </tr>
  </tbody>
</table>
<div className="pb-4" />
app/(commonLayout)/datasets/template/template.zh.mdx
New file
@@ -0,0 +1,2394 @@
{/**
  * @typedef Props
  * @property {string} apiBaseUrl
  */}
import { CodeGroup } from '@/app/components/develop/code.tsx'
import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstruction, Paragraph } from '@/app/components/develop/md.tsx'
# 知识库 API
<div>
  ### 鉴权
  Dify Service API 使用 `API-Key` 进行鉴权。
  建议开发者把 `API-Key` 放在后端存储,而非分享或者放在客户端存储,以免 `API-Key` 泄露,导致财产损失。
  所有 API 请求都应在 **`Authorization`** HTTP Header 中包含您的 `API-Key`,如下所示:
  <CodeGroup title="Code">
    ```javascript
      Authorization: Bearer {API_KEY}
    ```
  </CodeGroup>
</div>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/document/create-by-text'
  method='POST'
  title='通过文本创建文档'
  name='#create-by-text'
/>
<Row>
  <Col>
    此接口基于已存在知识库,在此知识库的基础上通过文本创建新的文档
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='name' type='string' key='name'>
        文档名称
      </Property>
      <Property name='text' type='string' key='text'>
        文档内容
      </Property>
      <Property name='indexing_technique' type='string' key='indexing_technique'>
        索引方式
          - <code>high_quality</code> 高质量:使用
        ding 模型进行嵌入,构建为向量数据库索引
          - <code>economy</code> 经济:使用 keyword table index 的倒排索引进行构建
      </Property>
      <Property name='doc_form' type='string' key='doc_form'>
        索引内容的形式
          - <code>text_model</code> text 文档直接 embedding,经济模式默认为该模式
          - <code>hierarchical_model</code> parent-child 模式
          - <code>qa_model</code> Q&A 模式:为分片文档生成 Q&A 对,然后对问题进行 embedding
      </Property>
      <Property name='doc_language' type='string' key='doc_language'>
        在 Q&A 模式下,指定文档的语言,例如:<code>English</code>、<code>Chinese</code>
      </Property>
      <Property name='process_rule' type='object' key='process_rule'>
        处理规则
          - <code>mode</code> (string) 清洗、分段模式 ,automatic 自动 / custom 自定义
          - <code>rules</code> (object) 自定义规则(自动模式下,该字段为空)
            - <code>pre_processing_rules</code> (array[object]) 预处理规则
              - <code>id</code> (string) 预处理规则的唯一标识符
                - 枚举:
                  - <code>remove_extra_spaces</code> 替换连续空格、换行符、制表符
                  - <code>remove_urls_emails</code> 删除 URL、电子邮件地址
              - <code>enabled</code> (bool) 是否选中该规则,不传入文档 ID 时代表默认值
            - <code>segmentation</code> (object) 分段规则
              - <code>separator</code> 自定义分段标识符,目前仅允许设置一个分隔符。默认为 <code>\n</code>
              - <code>max_tokens</code> 最大长度(token)默认为 1000
            - <code>parent_mode</code> 父分段的召回模式 <code>full-doc</code> 全文召回 / <code>paragraph</code> 段落召回
            - <code>subchunk_segmentation</code> (object) 子分段规则
              - <code>separator</code> 分段标识符,目前仅允许设置一个分隔符。默认为 <code>***</code>
              - <code>max_tokens</code> 最大长度 (token) 需要校验小于父级的长度
              - <code>chunk_overlap</code> 分段重叠指的是在对数据进行分段时,段与段之间存在一定的重叠部分(选填)
      </Property>
      <PropertyInstruction>当知识库未设置任何参数的时候,首次上传需要提供以下参数,未提供则使用默认选项:</PropertyInstruction>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        检索模式
          - <code>search_method</code> (string) 检索方法
            - <code>hybrid_search</code> 混合检索
            - <code>semantic_search</code> 语义检索
            - <code>full_text_search</code> 全文检索
          - <code>reranking_enable</code> (bool) 是否开启rerank
          - <code>reranking_mode</code> (String) 混合检索
            - <code>weighted_score</code> 权重设置
            - <code>reranking_model</code> Rerank 模型
          - <code>reranking_model</code> (object) Rerank 模型配置
            - <code>reranking_provider_name</code> (string) Rerank 模型的提供商
            - <code>reranking_model_name</code> (string) Rerank 模型的名称
          - <code>top_k</code> (int) 召回条数
          - <code>score_threshold_enabled</code> (bool)是否开启召回分数限制
          - <code>score_threshold</code> (float) 召回分数限制
      </Property>
      <Property name='embedding_model' type='string' key='embedding_model'>
        Embedding 模型名称
      </Property>
      <Property name='embedding_model_provider' type='string' key='embedding_model_provider'>
        Embedding 模型供应商
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/document/create-by-text"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/document/create-by-text' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"name": "text","text": "text","indexing_technique": "high_quality","process_rule": {"mode": "automatic"}}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/document/create-by-text' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "name": "text",
        "text": "text",
        "indexing_technique": "high_quality",
        "process_rule": {
            "mode": "automatic"
        }
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "document": {
        "id": "",
        "position": 1,
        "data_source_type": "upload_file",
        "data_source_info": {
            "upload_file_id": ""
        },
        "dataset_process_rule_id": "",
        "name": "text.txt",
        "created_from": "api",
        "created_by": "",
        "created_at": 1695690280,
        "tokens": 0,
        "indexing_status": "waiting",
        "error": null,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "archived": false,
        "display_status": "queuing",
        "word_count": 0,
        "hit_count": 0,
        "doc_form": "text_model"
      },
      "batch": ""
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/document/create-by-file'
  method='POST'
  title='通过文件创建文档 '
  name='#create-by-file'
/>
<Row>
  <Col>
    此接口基于已存在知识库,在此知识库的基础上通过文件创建新的文档
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='data' type='multipart/form-data json string' key='data'>
        - <code>original_document_id</code> 源文档 ID(选填)
          - 用于重新上传文档或修改文档清洗、分段配置,缺失的信息从源文档复制
          - 源文档不可为归档的文档
          - 当传入 <code>original_document_id</code> 时,代表文档进行更新操作,<code>process_rule</code> 为可填项目,不填默认使用源文档的分段方式
          - 未传入 <code>original_document_id</code> 时,代表文档进行新增操作,<code>process_rule</code> 为必填
        - <code>indexing_technique</code> 索引方式
          - <code>high_quality</code> 高质量:使用  embedding 模型进行嵌入,构建为向量数据库索引
          - <code>economy</code> 经济:使用 keyword table index 的倒排索引进行构建
        - <code>doc_form</code> 索引内容的形式
          - <code>text_model</code> text 文档直接 embedding,经济模式默认为该模式
          - <code>hierarchical_model</code> parent-child 模式
          - <code>qa_model</code> Q&A 模式:为分片文档生成 Q&A 对,然后对问题进行 embedding
        - <code>doc_language</code> 在 Q&A 模式下,指定文档的语言,例如:<code>English</code>、<code>Chinese</code>
        - <code>process_rule</code> 处理规则
          - <code>mode</code> (string) 清洗、分段模式 ,automatic 自动 / custom 自定义
          - <code>rules</code> (object) 自定义规则(自动模式下,该字段为空)
            - <code>pre_processing_rules</code> (array[object]) 预处理规则
              - <code>id</code> (string) 预处理规则的唯一标识符
                - 枚举:
                  - <code>remove_extra_spaces</code> 替换连续空格、换行符、制表符
                  - <code>remove_urls_emails</code> 删除 URL、电子邮件地址
              - <code>enabled</code> (bool) 是否选中该规则,不传入文档 ID 时代表默认值
            - <code>segmentation</code> (object) 分段规则
              - <code>separator</code> 自定义分段标识符,目前仅允许设置一个分隔符。默认为 \n
              - <code>max_tokens</code> 最大长度(token)默认为 1000
            - <code>parent_mode</code> 父分段的召回模式 <code>full-doc</code> 全文召回 / <code>paragraph</code> 段落召回
            - <code>subchunk_segmentation</code> (object) 子分段规则
              - <code>separator</code> 分段标识符,目前仅允许设置一个分隔符。默认为 <code>***</code>
              - <code>max_tokens</code> 最大长度 (token) 需要校验小于父级的长度
              - <code>chunk_overlap</code> 分段重叠指的是在对数据进行分段时,段与段之间存在一定的重叠部分(选填)
      </Property>
      <Property name='file' type='multipart/form-data' key='file'>
        需要上传的文件。
      </Property>
      <PropertyInstruction>当知识库未设置任何参数的时候,首次上传需要提供以下参数,未提供则使用默认选项:</PropertyInstruction>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        检索模式
          - <code>search_method</code> (string) 检索方法
            - <code>hybrid_search</code> 混合检索
            - <code>semantic_search</code> 语义检索
            - <code>full_text_search</code> 全文检索
          - <code>reranking_enable</code> (bool) 是否开启rerank
          - <code>reranking_model</code> (object) Rerank 模型配置
            - <code>reranking_provider_name</code> (string) Rerank 模型的提供商
            - <code>reranking_model_name</code> (string) Rerank 模型的名称
          - <code>top_k</code> (int) 召回条数
          - <code>score_threshold_enabled</code> (bool)是否开启召回分数限制
          - <code>score_threshold</code> (float) 召回分数限制
      </Property>
      <Property name='embedding_model' type='string' key='embedding_model'>
        Embedding 模型名称
      </Property>
      <Property name='embedding_model_provider' type='string' key='embedding_model_provider'>
        Embedding 模型供应商
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/document/create-by-file"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/document/create-by-file' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'data="{"indexing_technique":"high_quality","process_rule":{"rules":{"pre_processing_rules":[{"id":"remove_extra_spaces","enabled":true},{"id":"remove_urls_emails","enabled":true}],"segmentation":{"separator":"###","max_tokens":500}},"mode":"custom"}}";type=text/plain' \\\n--form 'file=@"/path/to/file"'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/document/create-by-file' \
    --header 'Authorization: Bearer {api_key}' \
    --form 'data="{\"name\":\"Dify\",\"indexing_technique\":\"high_quality\",\"process_rule\":{\"rules\":{\"pre_processing_rules\":[{\"id\":\"remove_extra_spaces\",\"enabled\":true},{\"id\":\"remove_urls_emails\",\"enabled\":true}],\"segmentation\":{\"separator\":\"###\",\"max_tokens\":500}},\"mode\":\"custom\"}}";type=text/plain' \
    --form 'file=@"/path/to/file"'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "document": {
        "id": "",
        "position": 1,
        "data_source_type": "upload_file",
        "data_source_info": {
          "upload_file_id": ""
        },
        "dataset_process_rule_id": "",
        "name": "Dify.txt",
        "created_from": "api",
        "created_by": "",
        "created_at": 1695308667,
        "tokens": 0,
        "indexing_status": "waiting",
        "error": null,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "archived": false,
        "display_status": "queuing",
        "word_count": 0,
        "hit_count": 0,
        "doc_form": "text_model"
      },
      "batch": ""
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets'
  method='POST'
  title='创建空知识库'
  name='#create_empty_dataset'
/>
<Row>
  <Col>
    ### Request Body
    <Properties>
      <Property name='name' type='string' key='name'>
        知识库名称(必填)
      </Property>
      <Property name='description' type='string' key='description'>
        知识库描述(选填)
      </Property>
      <Property name='indexing_technique' type='string' key='indexing_technique'>
        索引模式(选填,建议填写)
          - <code>high_quality</code> 高质量
          - <code>economy</code> 经济
      </Property>
      <Property name='permission' type='string' key='permission'>
        权限(选填,默认 only_me)
          - <code>only_me</code> 仅自己
          - <code>all_team_members</code> 所有团队成员
          - <code>partial_members</code> 部分团队成员
      </Property>
      <Property name='provider' type='string' key='provider'>
        Provider(选填,默认 vendor)
          - <code>vendor</code> 上传文件
          - <code>external</code> 外部知识库
      </Property>
      <Property name='external_knowledge_api_id' type='str' key='external_knowledge_api_id'>
        外部知识库 API_ID(选填)
      </Property>
      <Property name='external_knowledge_id' type='str' key='external_knowledge_id'>
        外部知识库 ID(选填)
      </Property>
      <Property name='embedding_model' type='str' key='embedding_model'>
        Embedding 模型名称
      </Property>
      <Property name='embedding_model_provider' type='str' key='embedding_model_provider'>
        Embedding 模型供应商
      </Property>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        检索模式
          - <code>search_method</code> (string) 检索方法
            - <code>hybrid_search</code> 混合检索
            - <code>semantic_search</code> 语义检索
            - <code>full_text_search</code> 全文检索
          - <code>reranking_enable</code> (bool) 是否开启rerank
          - <code>reranking_model</code> (object) Rerank 模型配置
            - <code>reranking_provider_name</code> (string) Rerank 模型的提供商
            - <code>reranking_model_name</code> (string) Rerank 模型的名称
          - <code>top_k</code> (int) 召回条数
          - <code>score_threshold_enabled</code> (bool)是否开启召回分数限制
          - <code>score_threshold</code> (float) 召回分数限制
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"name": "name", "permission": "only_me"}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "name": "name",
      "permission": "only_me"
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "",
      "name": "name",
      "description": null,
      "provider": "vendor",
      "permission": "only_me",
      "data_source_type": null,
      "indexing_technique": null,
      "app_count": 0,
      "document_count": 0,
      "word_count": 0,
      "created_by": "",
      "created_at": 1695636173,
      "updated_by": "",
      "updated_at": 1695636173,
      "embedding_model": null,
      "embedding_model_provider": null,
      "embedding_available": null
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets'
  method='GET'
  title='知识库列表'
  name='#dataset_list'
/>
<Row>
  <Col>
    ### Query
    <Properties>
      <Property name='keyword' type='string' key='keyword'>
        搜索关键词,可选
      </Property>
      <Property name='tag_ids' type='array[string]' key='tag_ids'>
        标签 ID 列表,可选
      </Property>
      <Property name='page' type='integer' key='page'>
        页码,可选,默认为 1
      </Property>
      <Property name='limit' type='string' key='limit'>
        返回条数,可选,默认 20,范围 1-100
      </Property>
      <Property name='include_all' type='boolean' key='include_all'>
        是否包含所有数据集(仅对所有者生效),可选,默认为 false
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets?page=1&limit=20' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets?page=1&limit=20' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": [
        {
          "id": "",
          "name": "知识库名称",
          "description": "描述信息",
          "permission": "only_me",
          "data_source_type": "upload_file",
          "indexing_technique": "",
          "app_count": 2,
          "document_count": 10,
          "word_count": 1200,
          "created_by": "",
          "created_at": "",
          "updated_by": "",
          "updated_at": ""
        },
        ...
      ],
      "has_more": true,
      "limit": 20,
      "total": 50,
      "page": 1
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}'
  method='GET'
  title='查看知识库详情'
  name='#view_dataset'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "eaedb485-95ac-4ffd-ab1e-18da6d676a2f",
      "name": "Test Knowledge Base",
      "description": "",
      "provider": "vendor",
      "permission": "only_me",
      "data_source_type": null,
      "indexing_technique": null,
      "app_count": 0,
      "document_count": 0,
      "word_count": 0,
      "created_by": "e99a1635-f725-4951-a99a-1daaaa76cfc6",
      "created_at": 1735620612,
      "updated_by": "e99a1635-f725-4951-a99a-1daaaa76cfc6",
      "updated_at": 1735620612,
      "embedding_model": null,
      "embedding_model_provider": null,
      "embedding_available": true,
      "retrieval_model_dict": {
        "search_method": "semantic_search",
        "reranking_enable": false,
        "reranking_mode": null,
        "reranking_model": {
          "reranking_provider_name": "",
          "reranking_model_name": ""
        },
        "weights": null,
        "top_k": 2,
        "score_threshold_enabled": false,
        "score_threshold": null
      },
      "tags": [],
      "doc_form": null,
      "external_knowledge_info": {
        "external_knowledge_id": null,
        "external_knowledge_api_id": null,
        "external_knowledge_api_name": null,
        "external_knowledge_api_endpoint": null
      },
      "external_retrieval_model": {
        "top_k": 2,
        "score_threshold": 0.0,
        "score_threshold_enabled": null
      }
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}'
  method='PATCH'
  title='修改知识库详情'
  name='#update_dataset'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='indexing_technique' type='string' key='indexing_technique'>
        索引模式(选填,建议填写)
          - <code>high_quality</code> 高质量
          - <code>economy</code> 经济
      </Property>
      <Property name='permission' type='string' key='permission'>
        权限(选填,默认 only_me)
          - <code>only_me</code> 仅自己
          - <code>all_team_members</code> 所有团队成员
          - <code>partial_members</code> 部分团队成员
      </Property>
      <Property name='embedding_model_provider' type='string' key='embedding_model_provider'>
        嵌入模型提供商(选填), 必须先在系统内设定好接入的模型,对应的是provider字段
      </Property>
      <Property name='embedding_model' type='string' key='embedding_model'>
        嵌入模型(选填)
      </Property>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        检索参数(选填,如不填,按照默认方式召回)
        - <code>search_method</code> (text) 检索方法:以下四个关键字之一,必填
          - <code>keyword_search</code> 关键字检索
          - <code>semantic_search</code> 语义检索
          - <code>full_text_search</code> 全文检索
          - <code>hybrid_search</code> 混合检索
        - <code>reranking_enable</code> (bool) 是否启用 Reranking,非必填,如果检索模式为 semantic_search 模式或者 hybrid_search 则传值
        - <code>reranking_mode</code> (object) Rerank 模型配置,非必填,如果启用了 reranking 则传值
            - <code>reranking_provider_name</code> (string) Rerank 模型提供商
            - <code>reranking_model_name</code> (string) Rerank 模型名称
        - <code>weights</code> (float) 混合检索模式下语意检索的权重设置
        - <code>top_k</code> (integer) 返回结果数量,非必填
        - <code>score_threshold_enabled</code> (bool) 是否开启 score 阈值
        - <code>score_threshold</code> (float) Score 阈值
      </Property>
      <Property name='partial_member_list' type='array' key='partial_member_list'>
        部分团队成员 ID 列表(选填)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="PATCH"
      label="/datasets/{dataset_id}"
      targetCode={`curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{
        "name": "Test Knowledge Base",
        "indexing_technique": "high_quality",
        "permission": "only_me",
        "embedding_model_provider": "zhipuai",
        "embedding_model": "embedding-3",
        "retrieval_model": {
          "search_method": "keyword_search",
          "reranking_enable": false,
          "reranking_mode": null,
          "reranking_model": {
              "reranking_provider_name": "",
              "reranking_model_name": ""
          },
          "weights": null,
          "top_k": 1,
          "score_threshold_enabled": false,
          "score_threshold": null
        },
        "partial_member_list": []
      }'
    `}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "name": "Test Knowledge Base",
      "indexing_technique": "high_quality",
      "permission": "only_me",
      "embedding_model_provider": "zhipuai",
      "embedding_model": "embedding-3",
      "retrieval_model": {
        "search_method": "keyword_search",
        "reranking_enable": false,
        "reranking_mode": null,
        "reranking_model": {
            "reranking_provider_name": "",
            "reranking_model_name": ""
        },
        "weights": null,
        "top_k": 1,
        "score_threshold_enabled": false,
        "score_threshold": null
      },
      "partial_member_list": []
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "eaedb485-95ac-4ffd-ab1e-18da6d676a2f",
      "name": "Test Knowledge Base",
      "description": "",
      "provider": "vendor",
      "permission": "only_me",
      "data_source_type": null,
      "indexing_technique": "high_quality",
      "app_count": 0,
      "document_count": 0,
      "word_count": 0,
      "created_by": "e99a1635-f725-4951-a99a-1daaaa76cfc6",
      "created_at": 1735620612,
      "updated_by": "e99a1635-f725-4951-a99a-1daaaa76cfc6",
      "updated_at": 1735622679,
      "embedding_model": "embedding-3",
      "embedding_model_provider": "zhipuai",
      "embedding_available": null,
      "retrieval_model_dict": {
          "search_method": "semantic_search",
          "reranking_enable": false,
          "reranking_mode": null,
          "reranking_model": {
              "reranking_provider_name": "",
              "reranking_model_name": ""
          },
          "weights": null,
          "top_k": 2,
          "score_threshold_enabled": false,
          "score_threshold": null
      },
      "tags": [],
      "doc_form": null,
      "external_knowledge_info": {
          "external_knowledge_id": null,
          "external_knowledge_api_id": null,
          "external_knowledge_api_name": null,
          "external_knowledge_api_endpoint": null
      },
      "external_retrieval_model": {
          "top_k": 2,
          "score_threshold": 0.0,
          "score_threshold_enabled": null
      },
      "partial_member_list": []
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}'
  method='DELETE'
  title='删除知识库'
  name='#delete_dataset'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="DELETE"
      label="/datasets/{dataset_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```text {{ title: 'Response' }}
    204 No Content
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/update-by-text'
  method='POST'
  title='通过文本更新文档'
  name='#update-by-text'
/>
<Row>
  <Col>
    此接口基于已存在知识库,在此知识库的基础上通过文本更新文档
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        文档 ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='name' type='string' key='name'>
        文档名称(选填)
      </Property>
      <Property name='text' type='string' key='text'>
        文档内容(选填)
      </Property>
      <Property name='process_rule' type='object' key='process_rule'>
        处理规则(选填)
          - <code>mode</code> (string) 清洗、分段模式 ,automatic 自动 / custom 自定义
          - <code>rules</code> (object) 自定义规则(自动模式下,该字段为空)
            - <code>pre_processing_rules</code> (array[object]) 预处理规则
              - <code>id</code> (string) 预处理规则的唯一标识符
                - 枚举:
                  - <code>remove_extra_spaces</code> 替换连续空格、换行符、制表符
                  - <code>remove_urls_emails</code> 删除 URL、电子邮件地址
              - <code>enabled</code> (bool) 是否选中该规则,不传入文档 ID 时代表默认值
            - <code>segmentation</code> (object) 分段规则
              - <code>separator</code> 自定义分段标识符,目前仅允许设置一个分隔符。默认为 \n
              - <code>max_tokens</code> 最大长度(token)默认为 1000
            - <code>parent_mode</code> 父分段的召回模式 <code>full-doc</code> 全文召回 / <code>paragraph</code> 段落召回
            - <code>subchunk_segmentation</code> (object) 子分段规则
              - <code>separator</code> 分段标识符,目前仅允许设置一个分隔符。默认为 <code>***</code>
              - <code>max_tokens</code> 最大长度 (token) 需要校验小于父级的长度
              - <code>chunk_overlap</code> 分段重叠指的是在对数据进行分段时,段与段之间存在一定的重叠部分(选填)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/update-by-text"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/update-by-text' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"name": "name","text": "text"}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/update-by-text' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "name": "name",
        "text": "text"
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "document": {
        "id": "",
        "position": 1,
        "data_source_type": "upload_file",
        "data_source_info": {
          "upload_file_id": ""
        },
        "dataset_process_rule_id": "",
        "name": "name.txt",
        "created_from": "api",
        "created_by": "",
        "created_at": 1695308667,
        "tokens": 0,
        "indexing_status": "waiting",
        "error": null,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "archived": false,
        "display_status": "queuing",
        "word_count": 0,
        "hit_count": 0,
        "doc_form": "text_model"
      },
      "batch": ""
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/update-by-file'
  method='POST'
  title='通过文件更新文档'
  name='#update-by-file'
/>
<Row>
  <Col>
    此接口基于已存在知识库,在此知识库的基础上通过文件更新文档的操作。
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        文档 ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='name' type='string' key='name'>
        文档名称(选填)
      </Property>
      <Property name='file' type='multipart/form-data' key='file'>
        需要上传的文件
      </Property>
      <Property name='process_rule' type='object' key='process_rule'>
        处理规则(选填)
          - <code>mode</code> (string) 清洗、分段模式 ,automatic 自动 / custom 自定义
          - <code>rules</code> (object) 自定义规则(自动模式下,该字段为空)
            - <code>pre_processing_rules</code> (array[object]) 预处理规则
              - <code>id</code> (string) 预处理规则的唯一标识符
                - 枚举:
                  - <code>remove_extra_spaces</code> 替换连续空格、换行符、制表符
                  - <code>remove_urls_emails</code> 删除 URL、电子邮件地址
              - <code>enabled</code> (bool) 是否选中该规则,不传入文档 ID 时代表默认值
            - <code>segmentation</code> (object) 分段规则
              - <code>separator</code> 自定义分段标识符,目前仅允许设置一个分隔符。默认为 \n
              - <code>max_tokens</code> 最大长度(token)默认为 1000
            - <code>parent_mode</code> 父分段的召回模式 <code>full-doc</code> 全文召回 / <code>paragraph</code> 段落召回
            - <code>subchunk_segmentation</code> (object) 子分段规则
              - <code>separator</code> 分段标识符,目前仅允许设置一个分隔符。默认为 <code>***</code>
              - <code>max_tokens</code> 最大长度 (token) 需要校验小于父级的长度
              - <code>chunk_overlap</code> 分段重叠指的是在对数据进行分段时,段与段之间存在一定的重叠部分(选填)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/update-by-file"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/update-by-file' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'data="{"name":"Dify","indexing_technique":"high_quality","process_rule":{"rules":{"pre_processing_rules":[{"id":"remove_extra_spaces","enabled":true},{"id":"remove_urls_emails","enabled":true}],"segmentation":{"separator":"###","max_tokens":500}},"mode":"custom"}}";type=text/plain' \\\n--form 'file=@"/path/to/file"'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/update-by-file' \
    --header 'Authorization: Bearer {api_key}' \
    --form 'data="{\"name\":\"Dify\",\"indexing_technique\":\"high_quality\",\"process_rule\":{\"rules\":{\"pre_processing_rules\":[{\"id\":\"remove_extra_spaces\",\"enabled\":true},{\"id\":\"remove_urls_emails\",\"enabled\":true}],\"segmentation\":{\"separator\":\"###\",\"max_tokens\":500}},\"mode\":\"custom\"}}";type=text/plain' \
    --form 'file=@"/path/to/file"'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "document": {
        "id": "",
        "position": 1,
        "data_source_type": "upload_file",
        "data_source_info": {
          "upload_file_id": ""
        },
        "dataset_process_rule_id": "",
        "name": "Dify.txt",
        "created_from": "api",
        "created_by": "",
        "created_at": 1695308667,
        "tokens": 0,
        "indexing_status": "waiting",
        "error": null,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "archived": false,
        "display_status": "queuing",
        "word_count": 0,
        "hit_count": 0,
        "doc_form": "text_model"
      },
      "batch": "20230921150427533684"
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{batch}/indexing-status'
  method='GET'
  title='获取文档嵌入状态(进度)'
  name='#indexing_status'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='batch' type='string' key='batch'>
        上传文档的批次号
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}/documents/{batch}/indexing-status"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{batch}/indexing-status' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{batch}/indexing-status' \
    --header 'Authorization: Bearer {api_key}' \
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data":[{
        "id": "",
        "indexing_status": "indexing",
        "processing_started_at": 1681623462.0,
        "parsing_completed_at": 1681623462.0,
        "cleaning_completed_at": 1681623462.0,
        "splitting_completed_at": 1681623462.0,
        "completed_at": null,
        "paused_at": null,
        "error": null,
        "stopped_at": null,
        "completed_segments": 24,
        "total_segments": 100
      }]
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}'
  method='DELETE'
  title='删除文档'
  name='#delete_document'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        文档 ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="DELETE"
      label="/datasets/{dataset_id}/documents/{document_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}' \
    --header 'Authorization: Bearer {api_key}' \
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```text {{ title: 'Response' }}
    204 No Content
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents'
  method='GET'
  title='知识库文档列表'
  name='#dataset_document_list'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
    </Properties>
    ### Query
    <Properties>
      <Property name='keyword' type='string' key='keyword'>
        搜索关键词,可选,目前仅搜索文档名称
      </Property>
      <Property name='page' type='string' key='page'>
        页码,可选
      </Property>
      <Property name='limit' type='string' key='limit'>
        返回条数,可选,默认 20,范围 1-100
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}/documents"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents' \
    --header 'Authorization: Bearer {api_key}' \
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": [
        {
          "id": "",
          "position": 1,
          "data_source_type": "file_upload",
          "data_source_info": null,
          "dataset_process_rule_id": null,
          "name": "dify",
          "created_from": "",
          "created_by": "",
          "created_at": 1681623639,
          "tokens": 0,
          "indexing_status": "waiting",
          "error": null,
          "enabled": true,
          "disabled_at": null,
          "disabled_by": null,
          "archived": false
        },
      ],
      "has_more": false,
      "limit": 20,
      "total": 9,
      "page": 1
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments'
  method='POST'
  title='新增分段'
  name='#create_new_segment'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        文档 ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='segments' type='object list' key='segments'>
        - <code>content</code> (text) 文本内容/问题内容,必填
        - <code>answer</code> (text) 答案内容,非必填,如果知识库的模式为 Q&A 模式则传值
        - <code>keywords</code> (list) 关键字,非必填
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/segments"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"segments": [{"content": "1","answer": "1","keywords": ["a"]}]}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "segments": [
        {
          "content": "1",
          "answer": "1",
          "keywords": ["a"]
        }
      ]
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": [{
        "id": "",
        "position": 1,
        "document_id": "",
        "content": "1",
        "answer": "1",
        "word_count": 25,
        "tokens": 0,
        "keywords": [
            "a"
        ],
        "index_node_id": "",
        "index_node_hash": "",
        "hit_count": 0,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }],
      "doc_form": "text_model"
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments'
  method='GET'
  title='查询文档分段'
  name='#get_segment'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        文档 ID
      </Property>
    </Properties>
     ### Query
    <Properties>
      <Property name='keyword' type='string' key='keyword'>
        搜索关键词,可选
      </Property>
      <Property name='status' type='string' key='status'>
        搜索状态,completed
      </Property>
      <Property name='page' type='string' key='page'>
        页码,可选
      </Property>
      <Property name='limit' type='string' key='limit'>
        返回条数,可选,默认 20,范围 1-100
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}/documents/{document_id}/segments"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": [{
        "id": "",
        "position": 1,
        "document_id": "",
        "content": "1",
        "answer": "1",
        "word_count": 25,
        "tokens": 0,
        "keywords": [
            "a"
        ],
        "index_node_id": "",
        "index_node_hash": "",
        "hit_count": 0,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }],
      "doc_form": "text_model",
      "has_more": false,
      "limit": 20,
      "total": 9,
      "page": 1
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}'
  method='DELETE'
  title='删除文档分段'
  name='#delete_segment'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        文档 ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        文档分段ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="DELETE"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```text {{ title: 'Response' }}
    204 No Content
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}'
  method='POST'
  title='更新文档分段'
  name='#update_segment'
/>
<Row>
  <Col>
    ### POST
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        文档 ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        文档分段ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='segment' type='object' key='segment'>
        - <code>content</code> (text) 文本内容/问题内容,必填
        - <code>answer</code> (text) 答案内容,非必填,如果知识库的模式为 Q&A 模式则传值
        - <code>keywords</code> (list) 关键字,非必填
        - <code>enabled</code> (bool) false/true,非必填
        - <code>regenerate_child_chunks</code> (bool) 是否重新生成子分段,非必填
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'\\\n--data-raw '{\"segment\": {\"content\": \"1\",\"answer\": \"1\", \"keywords\": [\"a\"], \"enabled\": false}}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
      "segment": {
          "content": "1",
          "answer": "1",
          "keywords": ["a"],
          "enabled": false
      }
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": {
        "id": "",
        "position": 1,
        "document_id": "",
        "content": "1",
        "answer": "1",
        "word_count": 25,
        "tokens": 0,
        "keywords": [
            "a"
        ],
        "index_node_id": "",
        "index_node_hash": "",
        "hit_count": 0,
        "enabled": true,
        "disabled_at": null,
        "disabled_by": null,
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      },
      "doc_form": "text_model"
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks'
  method='POST'
  title='新增文档子分段'
  name='#create_child_chunk'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        文档 ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        分段 ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='content' type='string' key='content'>
        子分段内容
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"content": "子分段内容"}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "content": "子分段内容"
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": {
        "id": "",
        "segment_id": "",
        "content": "子分段内容",
        "word_count": 25,
        "tokens": 0,
        "index_node_id": "",
        "index_node_hash": "",
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks'
  method='GET'
  title='查询文档子分段'
  name='#get_child_chunks'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        文档 ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        分段 ID
      </Property>
    </Properties>
    ### Query
    <Properties>
      <Property name='keyword' type='string' key='keyword'>
        搜索关键词(选填)
      </Property>
      <Property name='page' type='integer' key='page'>
        页码(选填,默认1)
      </Property>
      <Property name='limit' type='integer' key='limit'>
        每页数量(选填,默认20,最大100)
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks?page=1&limit=20' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks?page=1&limit=20' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": [{
        "id": "",
        "segment_id": "",
        "content": "子分段内容",
        "word_count": 25,
        "tokens": 0,
        "index_node_id": "",
        "index_node_hash": "",
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }],
      "total": 1,
      "total_pages": 1,
      "page": 1,
      "limit": 20
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}'
  method='DELETE'
  title='删除文档子分段'
  name='#delete_child_chunk'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        文档 ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        分段 ID
      </Property>
      <Property name='child_chunk_id' type='string' key='child_chunk_id'>
        子分段 ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="DELETE"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' \
    --header 'Authorization: Bearer {api_key}'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```text {{ title: 'Response' }}
    204 No Content
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Row>
  <Col>
    ### 错误信息
    <Properties>
      <Property name='code' type='string' key='code'>
        返回的错误代码
      </Property>
    </Properties>
    <Properties>
      <Property name='status' type='number' key='status'>
        返回的错误状态
      </Property>
    </Properties>
    <Properties>
      <Property name='message' type='string' key='message'>
        返回的错误信息
      </Property>
    </Properties>
  </Col>
  <Col>
    <CodeGroup title="Example">
    ```json {{ title: 'Response' }}
      {
        "code": "no_file_uploaded",
        "message": "Please upload your file.",
        "status": 400
      }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}'
  method='PATCH'
  title='更新文档子分段'
  name='#update_child_chunk'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        文档 ID
      </Property>
      <Property name='segment_id' type='string' key='segment_id'>
        分段 ID
      </Property>
      <Property name='child_chunk_id' type='string' key='child_chunk_id'>
        子分段 ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='content' type='string' key='content'>
        子分段内容
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="PATCH"
      label="/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}"
      targetCode={`curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{"content": "更新的子分段内容"}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "content": "更新的子分段内容"
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "data": {
        "id": "",
        "segment_id": "",
        "content": "更新的子分段内容",
        "word_count": 25,
        "tokens": 0,
        "index_node_id": "",
        "index_node_hash": "",
        "status": "completed",
        "created_by": "",
        "created_at": 1695312007,
        "indexing_at": 1695312007,
        "completed_at": 1695312007,
        "error": null,
        "stopped_at": null
      }
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/{document_id}/upload-file'
  method='GET'
  title='获取上传文件'
  name='#get_upload_file'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='document_id' type='string' key='document_id'>
        文档 ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}/documents/{document_id}/upload-file"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/upload-file' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/documents/{document_id}/upload-file' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "file_id",
      "name": "file_name",
      "size": 1024,
      "extension": "txt",
      "url": "preview_url",
      "download_url": "download_url",
      "mime_type": "text/plain",
      "created_by": "user_id",
      "created_at": 1728734540,
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/retrieve'
  method='POST'
  title='检索知识库'
  name='#dataset_retrieval'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='query' type='string' key='query'>
        检索关键词
      </Property>
      <Property name='retrieval_model' type='object' key='retrieval_model'>
        检索参数(选填,如不填,按照默认方式召回)
        - <code>search_method</code> (text) 检索方法:以下四个关键字之一,必填
          - <code>keyword_search</code> 关键字检索
          - <code>semantic_search</code> 语义检索
          - <code>full_text_search</code> 全文检索
          - <code>hybrid_search</code> 混合检索
        - <code>reranking_enable</code> (bool) 是否启用 Reranking,非必填,如果检索模式为 semantic_search 模式或者 hybrid_search 则传值
        - <code>reranking_mode</code> (object) Rerank 模型配置,非必填,如果启用了 reranking 则传值
            - <code>reranking_provider_name</code> (string) Rerank 模型提供商
            - <code>reranking_model_name</code> (string) Rerank 模型名称
        - <code>weights</code> (float) 混合检索模式下语意检索的权重设置
        - <code>top_k</code> (integer) 返回结果数量,非必填
        - <code>score_threshold_enabled</code> (bool) 是否开启 score 阈值
        - <code>score_threshold</code> (float) Score 阈值
      </Property>
      <Property name='external_retrieval_model' type='object' key='external_retrieval_model'>
          未启用字段
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/retrieve"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/retrieve' \\\n--header 'Authorization: Bearer {api_key}'\\\n--header 'Content-Type: application/json'\\\n--data-raw '{
    "query": "test",
    "retrieval_model": {
        "search_method": "keyword_search",
        "reranking_enable": false,
        "reranking_mode": null,
        "reranking_model": {
            "reranking_provider_name": "",
            "reranking_model_name": ""
        },
        "weights": null,
        "top_k": 1,
        "score_threshold_enabled": false,
        "score_threshold": null
    }
}'`}
    >
    ```bash {{ title: 'cURL' }}
    curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/retrieve' \
    --header 'Authorization: Bearer {api_key}' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "query": "test",
        "retrieval_model": {
            "search_method": "keyword_search",
            "reranking_enable": false,
            "reranking_mode": null,
            "reranking_model": {
                "reranking_provider_name": "",
                "reranking_model_name": ""
            },
            "weights": null,
            "top_k": 2,
            "score_threshold_enabled": false,
            "score_threshold": null
        }
    }'
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "query": {
        "content": "test"
      },
      "records": [
        {
          "segment": {
            "id": "7fa6f24f-8679-48b3-bc9d-bdf28d73f218",
            "position": 1,
            "document_id": "a8c6c36f-9f5d-4d7a-8472-f5d7b75d71d2",
            "content": "Operation guide",
            "answer": null,
            "word_count": 847,
            "tokens": 280,
            "keywords": [
              "install",
              "java",
              "base",
              "scripts",
              "jdk",
              "manual",
              "internal",
              "opens",
              "add",
              "vmoptions"
            ],
            "index_node_id": "39dd8443-d960-45a8-bb46-7275ad7fbc8e",
            "index_node_hash": "0189157697b3c6a418ccf8264a09699f25858975578f3467c76d6bfc94df1d73",
            "hit_count": 0,
            "enabled": true,
            "disabled_at": null,
            "disabled_by": null,
            "status": "completed",
            "created_by": "dbcb1ab5-90c8-41a7-8b78-73b235eb6f6f",
            "created_at": 1728734540,
            "indexing_at": 1728734552,
            "completed_at": 1728734584,
            "error": null,
            "stopped_at": null,
            "document": {
              "id": "a8c6c36f-9f5d-4d7a-8472-f5d7b75d71d2",
              "data_source_type": "upload_file",
              "name": "readme.txt",
            }
          },
          "score": 3.730463140527718e-05,
          "tsne_position": null
        }
      ]
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata'
  method='POST'
  title='新增元数据'
  name='#create_metadata'
/>
<Row>
  <Col>
    ### Params
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='segment' type='object' key='segment'>
        - <code>type</code> (string) 元数据类型,必填
        - <code>name</code> (string) 元数据名称,必填
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/metadata"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/metadata' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'\\\n--data-raw '{"type": "string", "name": "test"}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "abc",
      "type": "string",
      "name": "test",
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata/{metadata_id}'
  method='PATCH'
  title='更新元数据'
  name='#update_metadata'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='metadata_id' type='string' key='metadata_id'>
        元数据 ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='segment' type='object' key='segment'>
        - <code>name</code> (string) 元数据名称,必填
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="PATCH"
      label="/datasets/{dataset_id}/metadata/{metadata_id}"
      targetCode={`curl --location --request PATCH '${props.apiBaseUrl}/datasets/{dataset_id}/metadata/{metadata_id}' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'\\\n--data-raw '{"name": "test"}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "id": "abc",
      "type": "string",
      "name": "test",
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata/{metadata_id}'
  method='DELETE'
  title='删除元数据'
  name='#delete_metadata'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='metadata_id' type='string' key='metadata_id'>
        元数据 ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="DELETE"
      label="/datasets/{dataset_id}/metadata/{metadata_id}"
      targetCode={`curl --location --request DELETE '${props.apiBaseUrl}/datasets/{dataset_id}/metadata/{metadata_id}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata/built-in/{action}'
  method='POST'
  title='启用/禁用内置元数据'
  name='#toggle_metadata'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
      <Property name='action' type='string' key='action'>
        disable/enable
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/metadata/built-in/{action}"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/metadata/built-in/{action}' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/documents/metadata'
  method='POST'
  title='更新文档元数据'
  name='#update_documents_metadata'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
    </Properties>
    ### Request Body
    <Properties>
      <Property name='operation_data' type='object list' key='segments'>
        - <code>document_id</code> (string) 文档 ID
        - <code>metadata_list</code> (list) 元数据列表
          - <code>id</code> (string) 元数据 ID
          - <code>type</code> (string) 元数据类型
          - <code>name</code> (string) 元数据名称
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="POST"
      label="/datasets/{dataset_id}/documents/metadata"
      targetCode={`curl --location --request POST '${props.apiBaseUrl}/datasets/{dataset_id}/documents/metadata' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json'\\\n--data-raw '{"operation_data": [{"document_id": "document_id", "metadata_list": [{"id": "id", "value": "value", "name": "name"}]}]}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
  url='/datasets/{dataset_id}/metadata'
  method='GET'
  title='查询知识库元数据列表'
  name='#dataset_metadata_list'
/>
<Row>
  <Col>
    ### Path
    <Properties>
      <Property name='dataset_id' type='string' key='dataset_id'>
        知识库 ID
      </Property>
    </Properties>
  </Col>
  <Col sticky>
    <CodeGroup
      title="Request"
      tag="GET"
      label="/datasets/{dataset_id}/metadata"
      targetCode={`curl --location --request GET '${props.apiBaseUrl}/datasets/{dataset_id}/metadata' \\\n--header 'Authorization: Bearer {api_key}'`}
    >
    ```bash {{ title: 'cURL' }}
    ```
    </CodeGroup>
    <CodeGroup title="Response">
    ```json {{ title: 'Response' }}
    {
      "doc_metadata": [
        {
          "id": "",
          "name": "name",
          "type": "string",
          "use_count": 0,
        },
        ...
      ],
      "built_in_field_enabled": true
    }
    ```
    </CodeGroup>
  </Col>
</Row>
<hr className='ml-0 mr-0' />
<Heading
 url='/workspaces/current/models/model-types/text-embedding'
 method='GET'
 title='获取嵌入模型列表'
 name='#model_type_list'
/>
<Row>
   <Col>
     ### Query
     <Properties>
     </Properties>
   </Col>
   <Col sticky>
     <CodeGroup
       title="Request"
       tag="GET"
       label="/datasets/{dataset_id}"
       targetCode={`curl --location --location --request GET '${props.apiBaseUrl}/workspaces/current/models/model-types/text-embedding' \\\n--header 'Authorization: Bearer {api_key}' \\\n--header 'Content-Type: application/json' `}
     >
     ```bash {{ title: 'cURL' }}
     curl --location --request GET '${props.apiBaseUrl}/workspaces/current/models/model-types/text-embedding' \
     --header 'Authorization: Bearer {api_key}' \
     --header 'Content-Type: application/json' \
     ```
     </CodeGroup>
     <CodeGroup title="Response">
     ```json {{ title: 'Response' }}
     {
       "data": [
           {
               "provider": "zhipuai",
               "label": {
                   "zh_Hans": "智谱 AI",
                   "en_US": "ZHIPU AI"
               },
               "icon_small": {
                   "zh_Hans": "http://127.0.0.1:5001/console/api/workspaces/current/model-providers/zhipuai/icon_small/zh_Hans",
                   "en_US": "http://127.0.0.1:5001/console/api/workspaces/current/model-providers/zhipuai/icon_small/en_US"
               },
               "icon_large": {
                   "zh_Hans": "http://127.0.0.1:5001/console/api/workspaces/current/model-providers/zhipuai/icon_large/zh_Hans",
                   "en_US": "http://127.0.0.1:5001/console/api/workspaces/current/model-providers/zhipuai/icon_large/en_US"
               },
               "status": "active",
               "models": [
                   {
                       "model": "embedding-3",
                       "label": {
                           "zh_Hans": "embedding-3",
                           "en_US": "embedding-3"
                       },
                       "model_type": "text-embedding",
                       "features": null,
                       "fetch_from": "predefined-model",
                       "model_properties": {
                           "context_size": 8192
                       },
                       "deprecated": false,
                       "status": "active",
                       "load_balancing_enabled": false
                   },
                   {
                       "model": "embedding-2",
                       "label": {
                           "zh_Hans": "embedding-2",
                           "en_US": "embedding-2"
                       },
                       "model_type": "text-embedding",
                       "features": null,
                       "fetch_from": "predefined-model",
                       "model_properties": {
                           "context_size": 8192
                       },
                       "deprecated": false,
                       "status": "active",
                       "load_balancing_enabled": false
                   },
                   {
                       "model": "text_embedding",
                       "label": {
                           "zh_Hans": "text_embedding",
                           "en_US": "text_embedding"
                       },
                       "model_type": "text-embedding",
                       "features": null,
                       "fetch_from": "predefined-model",
                       "model_properties": {
                           "context_size": 512
                       },
                       "deprecated": false,
                       "status": "active",
                       "load_balancing_enabled": false
                   }
               ]
           }
       ]
     }
     ```
     </CodeGroup>
   </Col>
</Row>
<hr className='ml-0 mr-0' />
<Row>
  <Col>
    ### 错误信息
    <Properties>
      <Property name='code' type='string' key='code'>
        返回的错误代码
      </Property>
    </Properties>
    <Properties>
      <Property name='status' type='number' key='status'>
        返回的错误状态
      </Property>
    </Properties>
    <Properties>
      <Property name='message' type='string' key='message'>
        返回的错误信息
      </Property>
    </Properties>
  </Col>
  <Col>
    <CodeGroup title="Example">
    ```json {{ title: 'Response' }}
      {
        "code": "no_file_uploaded",
        "message": "Please upload your file.",
        "status": 400
      }
    ```
    </CodeGroup>
  </Col>
</Row>
<table className="max-w-auto border-collapse border border-slate-400" style={{ maxWidth: 'none', width: 'auto' }}>
  <thead style={{ background: '#f9fafc' }}>
    <tr>
      <th className="p-2 border border-slate-300">code</th>
      <th className="p-2 border border-slate-300">status</th>
      <th className="p-2 border border-slate-300">message</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td className="p-2 border border-slate-300">no_file_uploaded</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">Please upload your file.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">too_many_files</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">Only one file is allowed.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">file_too_large</td>
      <td className="p-2 border border-slate-300">413</td>
      <td className="p-2 border border-slate-300">File size exceeded.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">unsupported_file_type</td>
      <td className="p-2 border border-slate-300">415</td>
      <td className="p-2 border border-slate-300">File type not allowed.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">high_quality_dataset_only</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">Current operation only supports 'high-quality' datasets.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">dataset_not_initialized</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">The dataset is still being initialized or indexing. Please wait a moment.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">archived_document_immutable</td>
      <td className="p-2 border border-slate-300">403</td>
      <td className="p-2 border border-slate-300">The archived document is not editable.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">dataset_name_duplicate</td>
      <td className="p-2 border border-slate-300">409</td>
      <td className="p-2 border border-slate-300">The dataset name already exists. Please modify your dataset name.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">invalid_action</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">Invalid action.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">document_already_finished</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">The document has been processed. Please refresh the page or go to the document details.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">document_indexing</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">The document is being processed and cannot be edited.</td>
    </tr>
    <tr>
      <td className="p-2 border border-slate-300">invalid_metadata</td>
      <td className="p-2 border border-slate-300">400</td>
      <td className="p-2 border border-slate-300">The metadata content is incorrect. Please check and verify.</td>
    </tr>
  </tbody>
</table>
<div className="pb-4" />
app/(commonLayout)/education-apply/page.tsx
New file
@@ -0,0 +1,29 @@
'use client'
import {
  useEffect,
  useMemo,
} from 'react'
import {
  useRouter,
  useSearchParams,
} from 'next/navigation'
import EducationApplyPage from '@/app/education-apply/education-apply-page'
import { useProviderContext } from '@/context/provider-context'
export default function EducationApply() {
  const router = useRouter()
  const { enableEducationPlan, isEducationAccount } = useProviderContext()
  const searchParams = useSearchParams()
  const token = searchParams.get('token')
  const showEducationApplyPage = useMemo(() => {
    return enableEducationPlan && !isEducationAccount && token
  }, [enableEducationPlan, isEducationAccount, token])
  useEffect(() => {
    if (!showEducationApplyPage)
      router.replace('/')
  }, [showEducationApplyPage, router])
  return <EducationApplyPage />
}
app/(commonLayout)/explore/apps/page.tsx
New file
@@ -0,0 +1,8 @@
import React from 'react'
import AppList from '@/app/components/explore/app-list'
const Apps = () => {
  return <AppList />
}
export default React.memo(Apps)
app/(commonLayout)/explore/installed/[appId]/page.tsx
New file
@@ -0,0 +1,16 @@
import type { FC } from 'react'
import React from 'react'
import Main from '@/app/components/explore/installed-app'
export type IInstalledAppProps = {
  params: Promise<{
    appId: string
  }>
}
const InstalledApp: FC<IInstalledAppProps> = async ({ params }) => {
  return (
    <Main id={(await params).appId} />
  )
}
export default React.memo(InstalledApp)
app/(commonLayout)/explore/layout.tsx
New file
@@ -0,0 +1,16 @@
import type { FC } from 'react'
import React from 'react'
import ExploreClient from '@/app/components/explore'
export type IAppDetail = {
  children: React.ReactNode
}
const AppDetail: FC<IAppDetail> = ({ children }) => {
  return (
    <ExploreClient>
      {children}
    </ExploreClient>
  )
}
export default React.memo(AppDetail)
app/(commonLayout)/layout.tsx
New file
@@ -0,0 +1,38 @@
import React from 'react'
import type { ReactNode } from 'react'
import SwrInitor from '@/app/components/swr-initor'
import { AppContextProvider } from '@/context/app-context'
import GA, { GaType } from '@/app/components/base/ga'
import HeaderWrapper from '@/app/components/header/header-wrapper'
import Header from '@/app/components/header'
import { EventEmitterContextProvider } from '@/context/event-emitter'
import { ProviderContextProvider } from '@/context/provider-context'
import { ModalContextProvider } from '@/context/modal-context'
const Layout = ({ children }: { children: ReactNode }) => {
  return (
    <>
      <GA gaType={GaType.admin} />
      <SwrInitor>
        <AppContextProvider>
          <EventEmitterContextProvider>
            <ProviderContextProvider>
              <ModalContextProvider>
                <HeaderWrapper>
                  <Header />
                </HeaderWrapper>
                {children}
              </ModalContextProvider>
            </ProviderContextProvider>
          </EventEmitterContextProvider>
        </AppContextProvider>
      </SwrInitor>
    </>
  )
}
export const metadata = {
  title: 'Dify',
}
export default Layout
app/(commonLayout)/list.module.css
New file
@@ -0,0 +1,217 @@
.listItem {
  @apply col-span-1 bg-white border-2 border-solid border-transparent rounded-xl shadow-xs min-h-[160px] flex flex-col transition-all duration-200 ease-in-out cursor-pointer hover:shadow-lg;
}
.listItem.newItemCard {
  @apply outline outline-1 outline-gray-200 -outline-offset-1 hover:shadow-sm hover:bg-white;
  background-color: rgba(229, 231, 235, 0.5);
}
.listItem.selectable {
  @apply relative bg-gray-50 outline outline-1 outline-gray-200 -outline-offset-1 shadow-none hover:bg-none hover:shadow-none hover:outline-primary-200 transition-colors;
}
.listItem.selectable * {
  @apply relative;
}
.listItem.selectable::before {
  content: "";
  @apply absolute top-0 left-0 block w-full h-full rounded-lg pointer-events-none opacity-0 transition-opacity duration-200 ease-in-out hover:opacity-100;
  background: linear-gradient(0deg,
      rgba(235, 245, 255, 0.5),
      rgba(235, 245, 255, 0.5)),
    #ffffff;
}
.listItem.selectable:hover::before {
  @apply opacity-100;
}
.listItem.selected {
  @apply border-primary-600 hover:border-primary-600 border-2;
}
.listItem.selected::before {
  @apply opacity-100;
}
.appIcon {
  @apply flex items-center justify-center w-8 h-8 bg-pink-100 rounded-lg grow-0 shrink-0;
}
.appIcon.medium {
  @apply w-9 h-9;
}
.appIcon.large {
  @apply w-10 h-10;
}
.newItemIcon {
  @apply flex items-center justify-center w-8 h-8 transition-colors duration-200 ease-in-out border border-gray-200 rounded-lg hover:bg-white grow-0 shrink-0;
}
.listItem:hover .newItemIcon {
  @apply bg-gray-50 border-primary-100;
}
.newItemCard .newItemIcon {
  @apply bg-gray-100;
}
.newItemCard:hover .newItemIcon {
  @apply bg-white;
}
.selectable .newItemIcon {
  @apply bg-gray-50;
}
.selectable:hover .newItemIcon {
  @apply bg-primary-50;
}
.newItemIconImage {
  @apply grow-0 shrink-0 block w-4 h-4 bg-center bg-contain transition-colors duration-200 ease-in-out;
  color: #1f2a37;
}
.listItem:hover .newIconImage {
  @apply text-primary-600;
}
.newItemIconAdd {
  background-image: url("./apps/assets/add.svg");
}
/* .newItemIconChat {
  background-image: url("~@/app/components/base/icons/assets/public/header-nav/studio/Robot.svg");
}
.selected .newItemIconChat {
  background-image: url("~@/app/components/base/icons/assets/public/header-nav/studio/Robot-Active.svg");
} */
.newItemIconComplete {
  background-image: url("./apps/assets/completion.svg");
}
.listItemTitle {
  @apply flex pt-[14px] px-[14px] pb-3 h-[66px] items-center gap-3 grow-0 shrink-0;
}
.listItemHeading {
  @apply relative h-8 text-sm font-medium leading-8 grow;
}
.listItemHeadingContent {
  @apply absolute top-0 left-0 w-full h-full overflow-hidden text-ellipsis whitespace-nowrap;
}
.actionIconWrapper {
  @apply hidden h-8 w-8 p-2 rounded-md border-none hover:bg-gray-100 !important;
}
.listItem:hover .actionIconWrapper {
  @apply !inline-flex;
}
.deleteDatasetIcon {
  @apply hidden grow-0 shrink-0 basis-8 w-8 h-8 rounded-lg transition-colors duration-200 ease-in-out bg-white border border-gray-200 hover:bg-gray-100 bg-center bg-no-repeat;
  background-size: 16px;
  background-image: url('~@/assets/delete.svg');
}
.listItem:hover .deleteDatasetIcon {
  @apply block;
}
.listItemDescription {
  @apply mb-3 px-[14px] h-9 text-xs leading-normal text-gray-500 line-clamp-2;
}
.listItemDescription.noClip {
  @apply line-clamp-none;
}
.listItemFooter {
  @apply flex items-center flex-wrap min-h-[42px] px-[14px] pt-2 pb-[10px];
}
.listItemFooter.datasetCardFooter {
  @apply flex items-center gap-4 text-xs text-gray-500;
}
.listItemStats {
  @apply flex items-center gap-1;
}
.listItemFooterIcon {
  @apply block w-3 h-3 bg-center bg-contain;
}
.solidChatIcon {
  background-image: url("./apps/assets/chat-solid.svg");
}
.solidCompletionIcon {
  background-image: url("./apps/assets/completion-solid.svg");
}
.newItemCardHeading {
  @apply transition-colors duration-200 ease-in-out;
}
.listItem:hover .newItemCardHeading {
  @apply text-primary-600;
}
.listItemLink {
  @apply inline-flex items-center gap-1 text-xs text-gray-400 transition-colors duration-200 ease-in-out;
}
.listItem:hover .listItemLink {
  @apply text-primary-600;
}
.linkIcon {
  @apply block w-[13px] h-[13px] bg-center bg-contain;
  background-image: url("./apps/assets/link.svg");
}
.linkIcon.grayLinkIcon {
  background-image: url("./apps/assets/link-gray.svg");
}
.listItem:hover .grayLinkIcon {
  background-image: url("./apps/assets/link.svg");
}
.rightIcon {
  @apply block w-[13px] h-[13px] bg-center bg-contain;
  background-image: url("./apps/assets/right-arrow.svg");
}
.socialMediaLink {
  @apply flex items-center justify-center w-8 h-8 cursor-pointer hover:opacity-80 transition-opacity duration-200 ease-in-out;
}
.socialMediaIcon {
  @apply block w-6 h-6 bg-center bg-contain;
}
/* #region new app dialog */
.newItemCaption {
  @apply inline-flex items-center mb-2 text-sm font-medium;
}
/* #endregion new app dialog */
.unavailable {
  @apply opacity-50;
}
.listItem:hover .unavailable {
  @apply opacity-100;
}
app/(commonLayout)/plugins/page.tsx
New file
@@ -0,0 +1,16 @@
import PluginPage from '@/app/components/plugins/plugin-page'
import PluginsPanel from '@/app/components/plugins/plugin-page/plugins-panel'
import Marketplace from '@/app/components/plugins/marketplace'
import { getLocaleOnServer } from '@/i18n/server'
const PluginList = async () => {
  const locale = await getLocaleOnServer()
  return (
    <PluginPage
      plugins={<PluginsPanel />}
      marketplace={<Marketplace locale={locale} pluginTypeSwitchClassName='top-[60px]' searchBoxAutoAnimate={false} showSearchParams={false} />}
    />
  )
}
export default PluginList
app/(commonLayout)/tools/page.tsx
New file
@@ -0,0 +1,28 @@
'use client'
import type { FC } from 'react'
import { useRouter } from 'next/navigation'
import { useTranslation } from 'react-i18next'
import React, { useEffect } from 'react'
import ToolProviderList from '@/app/components/tools/provider-list'
import { useAppContext } from '@/context/app-context'
const Layout: FC = () => {
  const { t } = useTranslation()
  const router = useRouter()
  const { isCurrentWorkspaceDatasetOperator } = useAppContext()
  useEffect(() => {
    if (typeof window !== 'undefined')
      document.title = `${t('tools.title')} - Dify`
    if (isCurrentWorkspaceDatasetOperator)
      return router.replace('/datasets')
  }, [isCurrentWorkspaceDatasetOperator, router, t])
  useEffect(() => {
    if (isCurrentWorkspaceDatasetOperator)
      return router.replace('/datasets')
  }, [isCurrentWorkspaceDatasetOperator, router])
  return <ToolProviderList />
}
export default React.memo(Layout)
app/(shareLayout)/chat/[token]/page.tsx
New file
@@ -0,0 +1,11 @@
'use client'
import React from 'react'
import ChatWithHistoryWrap from '@/app/components/base/chat/chat-with-history'
const Chat = () => {
  return (
    <ChatWithHistoryWrap />
  )
}
export default React.memo(Chat)
app/(shareLayout)/chatbot/[token]/page.tsx
New file
@@ -0,0 +1,11 @@
'use client'
import React from 'react'
import EmbeddedChatbot from '@/app/components/base/chat/embedded-chatbot'
const Chatbot = () => {
  return (
    <EmbeddedChatbot />
  )
}
export default React.memo(Chatbot)
app/(shareLayout)/completion/[token]/page.tsx
New file
@@ -0,0 +1,10 @@
import React from 'react'
import Main from '@/app/components/share/text-generation'
const Completion = () => {
  return (
    <Main />
  )
}
export default React.memo(Completion)
app/(shareLayout)/layout.tsx
New file
@@ -0,0 +1,19 @@
import React from 'react'
import type { FC } from 'react'
import type { Metadata } from 'next'
export const metadata: Metadata = {
  icons: 'data:,', // prevent browser from using default favicon
}
const Layout: FC<{
  children: React.ReactNode
}> = ({ children }) => {
  return (
    <div className="h-full min-w-[300px] pb-[env(safe-area-inset-bottom)]">
      {children}
    </div>
  )
}
export default Layout
app/(shareLayout)/webapp-signin/page.tsx
New file
@@ -0,0 +1,103 @@
'use client'
import { useRouter, useSearchParams } from 'next/navigation'
import type { FC } from 'react'
import React, { useEffect } from 'react'
import cn from '@/utils/classnames'
import Toast from '@/app/components/base/toast'
import { fetchSystemFeatures, fetchWebOAuth2SSOUrl, fetchWebOIDCSSOUrl, fetchWebSAMLSSOUrl } from '@/service/share'
import { setAccessToken } from '@/app/components/share/utils'
import Loading from '@/app/components/base/loading'
const WebSSOForm: FC = () => {
  const searchParams = useSearchParams()
  const router = useRouter()
  const redirectUrl = searchParams.get('redirect_url')
  const tokenFromUrl = searchParams.get('web_sso_token')
  const message = searchParams.get('message')
  const showErrorToast = (message: string) => {
    Toast.notify({
      type: 'error',
      message,
    })
  }
  const getAppCodeFromRedirectUrl = () => {
    const appCode = redirectUrl?.split('/').pop()
    if (!appCode)
      return null
    return appCode
  }
  const processTokenAndRedirect = async () => {
    const appCode = getAppCodeFromRedirectUrl()
    if (!appCode || !tokenFromUrl || !redirectUrl) {
      showErrorToast('redirect url or app code or token is invalid.')
      return
    }
    await setAccessToken(appCode, tokenFromUrl)
    router.push(redirectUrl)
  }
  const handleSSOLogin = async (protocol: string) => {
    const appCode = getAppCodeFromRedirectUrl()
    if (!appCode || !redirectUrl) {
      showErrorToast('redirect url or app code is invalid.')
      return
    }
    switch (protocol) {
      case 'saml': {
        const samlRes = await fetchWebSAMLSSOUrl(appCode, redirectUrl)
        router.push(samlRes.url)
        break
      }
      case 'oidc': {
        const oidcRes = await fetchWebOIDCSSOUrl(appCode, redirectUrl)
        router.push(oidcRes.url)
        break
      }
      case 'oauth2': {
        const oauth2Res = await fetchWebOAuth2SSOUrl(appCode, redirectUrl)
        router.push(oauth2Res.url)
        break
      }
      default:
        showErrorToast('SSO protocol is not supported.')
    }
  }
  useEffect(() => {
    const init = async () => {
      const res = await fetchSystemFeatures()
      const protocol = res.sso_enforced_for_web_protocol
      if (message) {
        showErrorToast(message)
        return
      }
      if (!tokenFromUrl) {
        await handleSSOLogin(protocol)
        return
      }
      await processTokenAndRedirect()
    }
    init()
  }, [message, tokenFromUrl]) // Added dependencies to useEffect
  return (
    <div className="flex h-full items-center justify-center">
      <div className={cn('flex w-full grow flex-col items-center justify-center', 'px-6', 'md:px-[108px]')}>
        <Loading type='area' />
      </div>
    </div>
  )
}
export default React.memo(WebSSOForm)
app/(shareLayout)/workflow/[token]/page.tsx
New file
@@ -0,0 +1,11 @@
import React from 'react'
import Main from '@/app/components/share/text-generation'
const Workflow = () => {
  return (
    <Main isWorkflow />
  )
}
export default React.memo(Workflow)
app/account/account-page/AvatarWithEdit.tsx
New file
@@ -0,0 +1,122 @@
'use client'
import type { Area } from 'react-easy-crop'
import React, { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { RiPencilLine } from '@remixicon/react'
import { updateUserProfile } from '@/service/common'
import { ToastContext } from '@/app/components/base/toast'
import ImageInput, { type OnImageInput } from '@/app/components/base/app-icon-picker/ImageInput'
import Modal from '@/app/components/base/modal'
import Divider from '@/app/components/base/divider'
import Button from '@/app/components/base/button'
import Avatar, { type AvatarProps } from '@/app/components/base/avatar'
import { useLocalFileUploader } from '@/app/components/base/image-uploader/hooks'
import type { ImageFile } from '@/types/app'
import getCroppedImg from '@/app/components/base/app-icon-picker/utils'
import { DISABLE_UPLOAD_IMAGE_AS_ICON } from '@/config'
type InputImageInfo = { file: File } | { tempUrl: string; croppedAreaPixels: Area; fileName: string }
type AvatarWithEditProps = AvatarProps & { onSave?: () => void }
const AvatarWithEdit = ({ onSave, ...props }: AvatarWithEditProps) => {
  const { t } = useTranslation()
  const { notify } = useContext(ToastContext)
  const [inputImageInfo, setInputImageInfo] = useState<InputImageInfo>()
  const [isShowAvatarPicker, setIsShowAvatarPicker] = useState(false)
  const [uploading, setUploading] = useState(false)
  const handleImageInput: OnImageInput = useCallback(async (isCropped: boolean, fileOrTempUrl: string | File, croppedAreaPixels?: Area, fileName?: string) => {
    setInputImageInfo(
      isCropped
        ? { tempUrl: fileOrTempUrl as string, croppedAreaPixels: croppedAreaPixels!, fileName: fileName! }
        : { file: fileOrTempUrl as File },
    )
  }, [setInputImageInfo])
  const handleSaveAvatar = useCallback(async (uploadedFileId: string) => {
    try {
      await updateUserProfile({ url: 'account/avatar', body: { avatar: uploadedFileId } })
      notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
      setIsShowAvatarPicker(false)
      onSave?.()
    }
    catch (e) {
      notify({ type: 'error', message: (e as Error).message })
    }
  }, [notify, onSave, t])
  const { handleLocalFileUpload } = useLocalFileUploader({
    limit: 3,
    disabled: false,
    onUpload: (imageFile: ImageFile) => {
      if (imageFile.progress === 100) {
        setUploading(false)
        setInputImageInfo(undefined)
        handleSaveAvatar(imageFile.fileId)
      }
      // Error
      if (imageFile.progress === -1)
        setUploading(false)
    },
  })
  const handleSelect = useCallback(async () => {
    if (!inputImageInfo)
      return
    setUploading(true)
    if ('file' in inputImageInfo) {
      handleLocalFileUpload(inputImageInfo.file)
      return
    }
    const blob = await getCroppedImg(inputImageInfo.tempUrl, inputImageInfo.croppedAreaPixels, inputImageInfo.fileName)
    const file = new File([blob], inputImageInfo.fileName, { type: blob.type })
    handleLocalFileUpload(file)
  }, [handleLocalFileUpload, inputImageInfo])
  if (DISABLE_UPLOAD_IMAGE_AS_ICON)
    return <Avatar {...props} />
  return (
    <>
      <div>
        <div className="group relative">
          <Avatar {...props} />
          <div
            onClick={() => { setIsShowAvatarPicker(true) }}
            className="absolute inset-0 flex cursor-pointer items-center justify-center rounded-full bg-black bg-opacity-50 opacity-0 transition-opacity group-hover:opacity-100"
          >
            <span className="text-xs text-white">
              <RiPencilLine />
            </span>
          </div>
        </div>
      </div>
      <Modal
        closable
        className="!w-[362px] !p-0"
        isShow={isShowAvatarPicker}
        onClose={() => setIsShowAvatarPicker(false)}
      >
        <ImageInput onImageInput={handleImageInput} cropShape='round' />
        <Divider className='m-0' />
        <div className='flex w-full items-center justify-center gap-2 p-3'>
          <Button className='w-full' onClick={() => setIsShowAvatarPicker(false)}>
            {t('app.iconPicker.cancel')}
          </Button>
          <Button variant="primary" className='w-full' disabled={uploading || !inputImageInfo} loading={uploading} onClick={handleSelect}>
            {t('app.iconPicker.ok')}
          </Button>
        </div>
      </Modal>
    </>
  )
}
export default AvatarWithEdit
app/account/account-page/index.module.css
New file
@@ -0,0 +1,9 @@
.modal {
  padding: 24px 32px !important;
  width: 400px !important;
}
.bg {
  background: linear-gradient(180deg, rgba(217, 45, 32, 0.05) 0%, rgba(217, 45, 32, 0.00) 24.02%), #F9FAFB;
}
app/account/account-page/index.tsx
New file
@@ -0,0 +1,320 @@
'use client'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import {
  RiGraduationCapFill,
} from '@remixicon/react'
import { useContext } from 'use-context-selector'
import DeleteAccount from '../delete-account'
import s from './index.module.css'
import AvatarWithEdit from './AvatarWithEdit'
import Collapse from '@/app/components/header/account-setting/collapse'
import type { IItem } from '@/app/components/header/account-setting/collapse'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import { updateUserProfile } from '@/service/common'
import { useAppContext } from '@/context/app-context'
import { useProviderContext } from '@/context/provider-context'
import { ToastContext } from '@/app/components/base/toast'
import AppIcon from '@/app/components/base/app-icon'
import { IS_CE_EDITION } from '@/config'
import Input from '@/app/components/base/input'
import PremiumBadge from '@/app/components/base/premium-badge'
const titleClassName = `
  system-sm-semibold text-text-secondary
`
const descriptionClassName = `
  mt-1 body-xs-regular text-text-tertiary
`
const validPassword = /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/
export default function AccountPage() {
  const { t } = useTranslation()
  const { systemFeatures } = useAppContext()
  const { mutateUserProfile, userProfile, apps } = useAppContext()
  const { isEducationAccount } = useProviderContext()
  const { notify } = useContext(ToastContext)
  const [editNameModalVisible, setEditNameModalVisible] = useState(false)
  const [editName, setEditName] = useState('')
  const [editing, setEditing] = useState(false)
  const [editPasswordModalVisible, setEditPasswordModalVisible] = useState(false)
  const [currentPassword, setCurrentPassword] = useState('')
  const [password, setPassword] = useState('')
  const [confirmPassword, setConfirmPassword] = useState('')
  const [showDeleteAccountModal, setShowDeleteAccountModal] = useState(false)
  const [showCurrentPassword, setShowCurrentPassword] = useState(false)
  const [showPassword, setShowPassword] = useState(false)
  const [showConfirmPassword, setShowConfirmPassword] = useState(false)
  const handleEditName = () => {
    setEditNameModalVisible(true)
    setEditName(userProfile.name)
  }
  const handleSaveName = async () => {
    try {
      setEditing(true)
      await updateUserProfile({ url: 'account/name', body: { name: editName } })
      notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
      mutateUserProfile()
      setEditNameModalVisible(false)
      setEditing(false)
    }
    catch (e) {
      notify({ type: 'error', message: (e as Error).message })
      setEditNameModalVisible(false)
      setEditing(false)
    }
  }
  const showErrorMessage = (message: string) => {
    notify({
      type: 'error',
      message,
    })
  }
  const valid = () => {
    if (!password.trim()) {
      showErrorMessage(t('login.error.passwordEmpty'))
      return false
    }
    if (!validPassword.test(password)) {
      showErrorMessage(t('login.error.passwordInvalid'))
      return false
    }
    if (password !== confirmPassword) {
      showErrorMessage(t('common.account.notEqual'))
      return false
    }
    return true
  }
  const resetPasswordForm = () => {
    setCurrentPassword('')
    setPassword('')
    setConfirmPassword('')
  }
  const handleSavePassword = async () => {
    if (!valid())
      return
    try {
      setEditing(true)
      await updateUserProfile({
        url: 'account/password',
        body: {
          password: currentPassword,
          new_password: password,
          repeat_new_password: confirmPassword,
        },
      })
      notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
      mutateUserProfile()
      setEditPasswordModalVisible(false)
      resetPasswordForm()
      setEditing(false)
    }
    catch (e) {
      notify({ type: 'error', message: (e as Error).message })
      setEditPasswordModalVisible(false)
      setEditing(false)
    }
  }
  const renderAppItem = (item: IItem) => {
    return (
      <div className='flex px-3 py-1'>
        <div className='mr-3'>
          <AppIcon size='tiny' />
        </div>
        <div className='system-sm-medium mt-[3px] text-text-secondary'>{item.name}</div>
      </div>
    )
  }
  return (
    <>
      <div className='pb-3 pt-2'>
        <h4 className='title-2xl-semi-bold text-text-primary'>{t('common.account.myAccount')}</h4>
      </div>
      <div className='mb-8 flex items-center rounded-xl bg-gradient-to-r from-background-gradient-bg-fill-chat-bg-2 to-background-gradient-bg-fill-chat-bg-1 p-6'>
        <AvatarWithEdit avatar={userProfile.avatar_url} name={userProfile.name} onSave={ mutateUserProfile } size={64} />
        <div className='ml-4'>
          <p className='system-xl-semibold text-text-primary'>
            {userProfile.name}
            {isEducationAccount && (
              <PremiumBadge size='s' color='blue' className='ml-1 !px-2'>
                <RiGraduationCapFill className='mr-1 h-3 w-3' />
                <span className='system-2xs-medium'>EDU</span>
              </PremiumBadge>
            )}
          </p>
          <p className='system-xs-regular text-text-tertiary'>{userProfile.email}</p>
        </div>
      </div>
      <div className='mb-8'>
        <div className={titleClassName}>{t('common.account.name')}</div>
        <div className='mt-2 flex w-full items-center justify-between gap-2'>
          <div className='system-sm-regular flex-1 rounded-lg bg-components-input-bg-normal p-2 text-components-input-text-filled '>
            <span className='pl-1'>{userProfile.name}</span>
          </div>
          <div className='system-sm-medium cursor-pointer rounded-lg bg-components-button-tertiary-bg px-3 py-2 text-components-button-tertiary-text' onClick={handleEditName}>
            {t('common.operation.edit')}
          </div>
        </div>
      </div>
      <div className='mb-8'>
        <div className={titleClassName}>{t('common.account.email')}</div>
        <div className='mt-2 flex w-full items-center justify-between gap-2'>
          <div className='system-sm-regular flex-1 rounded-lg bg-components-input-bg-normal p-2 text-components-input-text-filled '>
            <span className='pl-1'>{userProfile.email}</span>
          </div>
        </div>
      </div>
      {
        systemFeatures.enable_email_password_login && (
          <div className='mb-8 flex justify-between gap-2'>
            <div>
              <div className='system-sm-semibold mb-1 text-text-secondary'>{t('common.account.password')}</div>
              <div className='body-xs-regular mb-2 text-text-tertiary'>{t('common.account.passwordTip')}</div>
            </div>
            <Button onClick={() => setEditPasswordModalVisible(true)}>{userProfile.is_password_set ? t('common.account.resetPassword') : t('common.account.setPassword')}</Button>
          </div>
        )
      }
      <div className='mb-6 border-[1px] border-divider-subtle' />
      <div className='mb-8'>
        <div className={titleClassName}>{t('common.account.langGeniusAccount')}</div>
        <div className={descriptionClassName}>{t('common.account.langGeniusAccountTip')}</div>
        {!!apps.length && (
          <Collapse
            title={`${t('common.account.showAppLength', { length: apps.length })}`}
            items={apps.map(app => ({ key: app.id, name: app.name }))}
            renderItem={renderAppItem}
            wrapperClassName='mt-2'
          />
        )}
        {!IS_CE_EDITION && <Button className='mt-2 text-components-button-destructive-secondary-text' onClick={() => setShowDeleteAccountModal(true)}>{t('common.account.delete')}</Button>}
      </div>
      {
        editNameModalVisible && (
          <Modal
            isShow
            onClose={() => setEditNameModalVisible(false)}
            className={s.modal}
          >
            <div className='title-2xl-semi-bold mb-6 text-text-primary'>{t('common.account.editName')}</div>
            <div className={titleClassName}>{t('common.account.name')}</div>
            <Input className='mt-2'
              value={editName}
              onChange={e => setEditName(e.target.value)}
            />
            <div className='mt-10 flex justify-end'>
              <Button className='mr-2' onClick={() => setEditNameModalVisible(false)}>{t('common.operation.cancel')}</Button>
              <Button
                disabled={editing || !editName}
                variant='primary'
                onClick={handleSaveName}
              >
                {t('common.operation.save')}
              </Button>
            </div>
          </Modal>
        )
      }
      {
        editPasswordModalVisible && (
          <Modal
            isShow
            onClose={() => {
              setEditPasswordModalVisible(false)
              resetPasswordForm()
            }}
            className={s.modal}
          >
            <div className='title-2xl-semi-bold mb-6 text-text-primary'>{userProfile.is_password_set ? t('common.account.resetPassword') : t('common.account.setPassword')}</div>
            {userProfile.is_password_set && (
              <>
                <div className={titleClassName}>{t('common.account.currentPassword')}</div>
                <div className='relative mt-2'>
                  <Input
                    type={showCurrentPassword ? 'text' : 'password'}
                    value={currentPassword}
                    onChange={e => setCurrentPassword(e.target.value)}
                  />
                  <div className="absolute inset-y-0 right-0 flex items-center">
                    <Button
                      type="button"
                      variant='ghost'
                      onClick={() => setShowCurrentPassword(!showCurrentPassword)}
                    >
                      {showCurrentPassword ? '👀' : '😝'}
                    </Button>
                  </div>
                </div>
              </>
            )}
            <div className='system-sm-semibold mt-8 text-text-secondary'>
              {userProfile.is_password_set ? t('common.account.newPassword') : t('common.account.password')}
            </div>
            <div className='relative mt-2'>
              <Input
                type={showPassword ? 'text' : 'password'}
                value={password}
                onChange={e => setPassword(e.target.value)}
              />
              <div className="absolute inset-y-0 right-0 flex items-center">
                <Button
                  type="button"
                  variant='ghost'
                  onClick={() => setShowPassword(!showPassword)}
                >
                  {showPassword ? '👀' : '😝'}
                </Button>
              </div>
            </div>
            <div className='system-sm-semibold mt-8 text-text-secondary'>{t('common.account.confirmPassword')}</div>
            <div className='relative mt-2'>
              <Input
                type={showConfirmPassword ? 'text' : 'password'}
                value={confirmPassword}
                onChange={e => setConfirmPassword(e.target.value)}
              />
              <div className="absolute inset-y-0 right-0 flex items-center">
                <Button
                  type="button"
                  variant='ghost'
                  onClick={() => setShowConfirmPassword(!showConfirmPassword)}
                >
                  {showConfirmPassword ? '👀' : '😝'}
                </Button>
              </div>
            </div>
            <div className='mt-10 flex justify-end'>
              <Button className='mr-2' onClick={() => {
                setEditPasswordModalVisible(false)
                resetPasswordForm()
              }}>{t('common.operation.cancel')}</Button>
              <Button
                disabled={editing}
                variant='primary'
                onClick={handleSavePassword}
              >
                {userProfile.is_password_set ? t('common.operation.reset') : t('common.operation.save')}
              </Button>
            </div>
          </Modal>
        )
      }
      {
        showDeleteAccountModal && (
          <DeleteAccount
            onCancel={() => setShowDeleteAccountModal(false)}
            onConfirm={() => setShowDeleteAccountModal(false)}
          />
        )
      }
    </>
  )
}
app/account/avatar.tsx
New file
@@ -0,0 +1,109 @@
'use client'
import { useTranslation } from 'react-i18next'
import { Fragment } from 'react'
import { useRouter } from 'next/navigation'
import {
  RiGraduationCapFill,
} from '@remixicon/react'
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
import Avatar from '@/app/components/base/avatar'
import { logout } from '@/service/common'
import { useAppContext } from '@/context/app-context'
import { useProviderContext } from '@/context/provider-context'
import { LogOut01 } from '@/app/components/base/icons/src/vender/line/general'
import PremiumBadge from '@/app/components/base/premium-badge'
export type IAppSelector = {
  isMobile: boolean
}
export default function AppSelector() {
  const router = useRouter()
  const { t } = useTranslation()
  const { userProfile } = useAppContext()
  const { isEducationAccount } = useProviderContext()
  const handleLogout = async () => {
    await logout({
      url: '/logout',
      params: {},
    })
    localStorage.removeItem('setup_status')
    localStorage.removeItem('console_token')
    localStorage.removeItem('refresh_token')
    router.push('/signin')
  }
  return (
    <Menu as="div" className="relative inline-block text-left">
      {
        ({ open }) => (
          <>
            <div>
              <MenuButton
                className={`
                    p-1x inline-flex
                    items-center rounded-[20px] text-sm
                    text-text-primary
                    mobile:px-1
                    ${open && 'bg-components-panel-bg-blur'}
                  `}
              >
                <Avatar avatar={userProfile.avatar_url} name={userProfile.name} size={32} />
              </MenuButton>
            </div>
            <Transition
              as={Fragment}
              enter="transition ease-out duration-100"
              enterFrom="transform opacity-0 scale-95"
              enterTo="transform opacity-100 scale-100"
              leave="transition ease-in duration-75"
              leaveFrom="transform opacity-100 scale-100"
              leaveTo="transform opacity-0 scale-95"
            >
              <MenuItems
                className="
                    absolute -right-2 -top-1 w-60 max-w-80
                    origin-top-right divide-y divide-divider-subtle rounded-lg bg-components-panel-bg-blur
                    shadow-lg
                  "
              >
                <MenuItem>
                  <div className='p-1'>
                    <div className='flex flex-nowrap items-center px-3 py-2'>
                      <div className='grow'>
                        <div className='system-md-medium break-all text-text-primary'>
                          {userProfile.name}
                          {isEducationAccount && (
                            <PremiumBadge size='s' color='blue' className='ml-1 !px-2'>
                              <RiGraduationCapFill className='mr-1 h-3 w-3' />
                              <span className='system-2xs-medium'>EDU</span>
                            </PremiumBadge>
                          )}
                        </div>
                        <div className='system-xs-regular break-all text-text-tertiary'>{userProfile.email}</div>
                      </div>
                      <Avatar avatar={userProfile.avatar_url} name={userProfile.name} size={32} />
                    </div>
                  </div>
                </MenuItem>
                <MenuItem>
                  <div className='p-1' onClick={() => handleLogout()}>
                    <div
                      className='group flex h-9 cursor-pointer items-center justify-start rounded-lg px-3 hover:bg-state-base-hover'
                    >
                      <LogOut01 className='mr-1 flex h-4 w-4 text-text-tertiary' />
                      <div className='text-[14px] font-normal text-text-secondary'>{t('common.userProfile.logout')}</div>
                    </div>
                  </div>
                </MenuItem>
              </MenuItems>
            </Transition>
          </>
        )
      }
    </Menu>
  )
}
app/account/delete-account/components/check-email.tsx
New file
@@ -0,0 +1,48 @@
'use client'
import { useTranslation } from 'react-i18next'
import { useCallback, useState } from 'react'
import Link from 'next/link'
import { useSendDeleteAccountEmail } from '../state'
import { useAppContext } from '@/context/app-context'
import Input from '@/app/components/base/input'
import Button from '@/app/components/base/button'
type DeleteAccountProps = {
  onCancel: () => void
  onConfirm: () => void
}
export default function CheckEmail(props: DeleteAccountProps) {
  const { t } = useTranslation()
  const { userProfile } = useAppContext()
  const [userInputEmail, setUserInputEmail] = useState('')
  const { isPending: isSendingEmail, mutateAsync: getDeleteEmailVerifyCode } = useSendDeleteAccountEmail()
  const handleConfirm = useCallback(async () => {
    try {
      const ret = await getDeleteEmailVerifyCode()
      if (ret.result === 'success')
        props.onConfirm()
    }
    catch (error) { console.error(error) }
  }, [getDeleteEmailVerifyCode, props])
  return <>
    <div className='body-md-medium py-1 text-text-destructive'>
      {t('common.account.deleteTip')}
    </div>
    <div className='body-md-regular pb-2 pt-1 text-text-secondary'>
      {t('common.account.deletePrivacyLinkTip')}
      <Link href='https://dify.ai/privacy' className='text-text-accent'>{t('common.account.deletePrivacyLink')}</Link>
    </div>
    <label className='system-sm-semibold mb-1 mt-3 flex h-6 items-center text-text-secondary'>{t('common.account.deleteLabel')}</label>
    <Input placeholder={t('common.account.deletePlaceholder') as string} onChange={(e) => {
      setUserInputEmail(e.target.value)
    }} />
    <div className='mt-3 flex w-full flex-col gap-2'>
      <Button className='w-full' disabled={userInputEmail !== userProfile.email || isSendingEmail} loading={isSendingEmail} variant='primary' onClick={handleConfirm}>{t('common.account.sendVerificationButton')}</Button>
      <Button className='w-full' onClick={props.onCancel}>{t('common.operation.cancel')}</Button>
    </div>
  </>
}
app/account/delete-account/components/feed-back.tsx
New file
@@ -0,0 +1,68 @@
'use client'
import { useTranslation } from 'react-i18next'
import { useCallback, useState } from 'react'
import { useRouter } from 'next/navigation'
import { useDeleteAccountFeedback } from '../state'
import { useAppContext } from '@/context/app-context'
import Button from '@/app/components/base/button'
import CustomDialog from '@/app/components/base/dialog'
import Textarea from '@/app/components/base/textarea'
import Toast from '@/app/components/base/toast'
import { logout } from '@/service/common'
type DeleteAccountProps = {
  onCancel: () => void
  onConfirm: () => void
}
export default function FeedBack(props: DeleteAccountProps) {
  const { t } = useTranslation()
  const { userProfile } = useAppContext()
  const router = useRouter()
  const [userFeedback, setUserFeedback] = useState('')
  const { isPending, mutateAsync: sendFeedback } = useDeleteAccountFeedback()
  const handleSuccess = useCallback(async () => {
    try {
      await logout({
        url: '/logout',
        params: {},
      })
      localStorage.removeItem('refresh_token')
      localStorage.removeItem('console_token')
      router.push('/signin')
      Toast.notify({ type: 'info', message: t('common.account.deleteSuccessTip') })
    }
    catch (error) { console.error(error) }
  }, [router, t])
  const handleSubmit = useCallback(async () => {
    try {
      await sendFeedback({ feedback: userFeedback, email: userProfile.email })
      props.onConfirm()
      await handleSuccess()
    }
    catch (error) { console.error(error) }
  }, [handleSuccess, userFeedback, sendFeedback, userProfile, props])
  const handleSkip = useCallback(() => {
    props.onCancel()
    handleSuccess()
  }, [handleSuccess, props])
  return <CustomDialog
    show={true}
    onClose={props.onCancel}
    title={t('common.account.feedbackTitle')}
    className="max-w-[480px]"
    footer={false}
  >
    <label className='system-sm-semibold mb-1 mt-3 flex items-center text-text-secondary'>{t('common.account.feedbackLabel')}</label>
    <Textarea rows={6} value={userFeedback} placeholder={t('common.account.feedbackPlaceholder') as string} onChange={(e) => {
      setUserFeedback(e.target.value)
    }} />
    <div className='mt-3 flex w-full flex-col gap-2'>
      <Button className='w-full' loading={isPending} variant='primary' onClick={handleSubmit}>{t('common.operation.submit')}</Button>
      <Button className='w-full' onClick={handleSkip}>{t('common.operation.skip')}</Button>
    </div>
  </CustomDialog>
}
app/account/delete-account/components/verify-email.tsx
New file
@@ -0,0 +1,55 @@
'use client'
import { useTranslation } from 'react-i18next'
import { useCallback, useEffect, useState } from 'react'
import Link from 'next/link'
import { useAccountDeleteStore, useConfirmDeleteAccount, useSendDeleteAccountEmail } from '../state'
import Input from '@/app/components/base/input'
import Button from '@/app/components/base/button'
import Countdown from '@/app/components/signin/countdown'
const CODE_EXP = /[A-Za-z\d]{6}/gi
type DeleteAccountProps = {
  onCancel: () => void
  onConfirm: () => void
}
export default function VerifyEmail(props: DeleteAccountProps) {
  const { t } = useTranslation()
  const emailToken = useAccountDeleteStore(state => state.sendEmailToken)
  const [verificationCode, setVerificationCode] = useState<string>()
  const [shouldButtonDisabled, setShouldButtonDisabled] = useState(true)
  const { mutate: sendEmail } = useSendDeleteAccountEmail()
  const { isPending: isDeleting, mutateAsync: confirmDeleteAccount } = useConfirmDeleteAccount()
  useEffect(() => {
    setShouldButtonDisabled(!(verificationCode && CODE_EXP.test(verificationCode)) || isDeleting)
  }, [verificationCode, isDeleting])
  const handleConfirm = useCallback(async () => {
    try {
      const ret = await confirmDeleteAccount({ code: verificationCode!, token: emailToken })
      if (ret.result === 'success')
        props.onConfirm()
    }
    catch (error) { console.error(error) }
  }, [emailToken, verificationCode, confirmDeleteAccount, props])
  return <>
    <div className='body-md-medium pt-1 text-text-destructive'>
      {t('common.account.deleteTip')}
    </div>
    <div className='body-md-regular pb-2 pt-1 text-text-secondary'>
      {t('common.account.deletePrivacyLinkTip')}
      <Link href='https://dify.ai/privacy' className='text-text-accent'>{t('common.account.deletePrivacyLink')}</Link>
    </div>
    <label className='system-sm-semibold mb-1 mt-3 flex h-6 items-center text-text-secondary'>{t('common.account.verificationLabel')}</label>
    <Input minLength={6} maxLength={6} placeholder={t('common.account.verificationPlaceholder') as string} onChange={(e) => {
      setVerificationCode(e.target.value)
    }} />
    <div className='mt-3 flex w-full flex-col gap-2'>
      <Button className='w-full' disabled={shouldButtonDisabled} loading={isDeleting} variant='warning' onClick={handleConfirm}>{t('common.account.permanentlyDeleteButton')}</Button>
      <Button className='w-full' onClick={props.onCancel}>{t('common.operation.cancel')}</Button>
      <Countdown onResend={sendEmail} />
    </div>
  </>
}
app/account/delete-account/index.tsx
New file
@@ -0,0 +1,44 @@
'use client'
import { useTranslation } from 'react-i18next'
import { useCallback, useState } from 'react'
import CheckEmail from './components/check-email'
import VerifyEmail from './components/verify-email'
import FeedBack from './components/feed-back'
import CustomDialog from '@/app/components/base/dialog'
import { COUNT_DOWN_KEY, COUNT_DOWN_TIME_MS } from '@/app/components/signin/countdown'
type DeleteAccountProps = {
  onCancel: () => void
  onConfirm: () => void
}
export default function DeleteAccount(props: DeleteAccountProps) {
  const { t } = useTranslation()
  const [showVerifyEmail, setShowVerifyEmail] = useState(false)
  const [showFeedbackDialog, setShowFeedbackDialog] = useState(false)
  const handleEmailCheckSuccess = useCallback(async () => {
    try {
      setShowVerifyEmail(true)
      localStorage.setItem(COUNT_DOWN_KEY, `${COUNT_DOWN_TIME_MS}`)
    }
    catch (error) { console.error(error) }
  }, [])
  if (showFeedbackDialog)
    return <FeedBack onCancel={props.onCancel} onConfirm={props.onConfirm} />
  return <CustomDialog
    show={true}
    onClose={props.onCancel}
    title={t('common.account.delete')}
    className="max-w-[480px]"
    footer={false}
  >
    {!showVerifyEmail && <CheckEmail onCancel={props.onCancel} onConfirm={handleEmailCheckSuccess} />}
    {showVerifyEmail && <VerifyEmail onCancel={props.onCancel} onConfirm={() => {
      setShowFeedbackDialog(true)
    }} />}
  </CustomDialog>
}
app/account/delete-account/state.tsx
New file
@@ -0,0 +1,39 @@
import { useMutation } from '@tanstack/react-query'
import { create } from 'zustand'
import { sendDeleteAccountCode, submitDeleteAccountFeedback, verifyDeleteAccountCode } from '@/service/common'
type State = {
  sendEmailToken: string
  setSendEmailToken: (token: string) => void
}
export const useAccountDeleteStore = create<State>(set => ({
  sendEmailToken: '',
  setSendEmailToken: (token: string) => set({ sendEmailToken: token }),
}))
export function useSendDeleteAccountEmail() {
  const updateEmailToken = useAccountDeleteStore(state => state.setSendEmailToken)
  return useMutation({
    mutationKey: ['delete-account'],
    mutationFn: sendDeleteAccountCode,
    onSuccess: (ret) => {
      if (ret.result === 'success')
        updateEmailToken(ret.data)
    },
  })
}
export function useConfirmDeleteAccount() {
  return useMutation({
    mutationKey: ['confirm-delete-account'],
    mutationFn: verifyDeleteAccountCode,
  })
}
export function useDeleteAccountFeedback() {
  return useMutation({
    mutationKey: ['delete-account-feedback'],
    mutationFn: submitDeleteAccountFeedback,
  })
}
app/account/header.tsx
New file
@@ -0,0 +1,39 @@
'use client'
import { useTranslation } from 'react-i18next'
import { RiArrowRightUpLine, RiRobot2Line } from '@remixicon/react'
import { useRouter } from 'next/navigation'
import Button from '../components/base/button'
import Avatar from './avatar'
import DifyLogo from '@/app/components/base/logo/dify-logo'
import { useCallback } from 'react'
const Header = () => {
  const { t } = useTranslation()
  const router = useRouter()
  const back = useCallback(() => {
    router.back()
  }, [router])
  return (
    <div className='flex flex-1 items-center justify-between px-4'>
      <div className='flex items-center gap-3'>
        <div className='flex cursor-pointer items-center' onClick={back}>
          <DifyLogo />
        </div>
        <div className='h-4 w-[1px] origin-center rotate-[11.31deg] bg-divider-regular' />
        <p className='title-3xl-semi-bold relative mt-[-2px] text-text-primary'>{t('common.account.account')}</p>
      </div>
      <div className='flex shrink-0 items-center gap-3'>
        <Button className='system-sm-medium gap-2 px-3 py-2' onClick={back}>
          <RiRobot2Line className='h-4 w-4' />
          <p>{t('common.account.studio')}</p>
          <RiArrowRightUpLine className='h-4 w-4' />
        </Button>
        <div className='h-4 w-[1px] bg-divider-regular' />
        <Avatar />
      </div>
    </div>
  )
}
export default Header
app/account/layout.tsx
New file
@@ -0,0 +1,40 @@
import React from 'react'
import type { ReactNode } from 'react'
import Header from './header'
import SwrInitor from '@/app/components/swr-initor'
import { AppContextProvider } from '@/context/app-context'
import GA, { GaType } from '@/app/components/base/ga'
import HeaderWrapper from '@/app/components/header/header-wrapper'
import { EventEmitterContextProvider } from '@/context/event-emitter'
import { ProviderContextProvider } from '@/context/provider-context'
import { ModalContextProvider } from '@/context/modal-context'
const Layout = ({ children }: { children: ReactNode }) => {
  return (
    <>
      <GA gaType={GaType.admin} />
      <SwrInitor>
        <AppContextProvider>
          <EventEmitterContextProvider>
            <ProviderContextProvider>
              <ModalContextProvider>
                <HeaderWrapper>
                  <Header />
                </HeaderWrapper>
                <div className='relative flex h-0 shrink-0 grow flex-col overflow-y-auto bg-components-panel-bg'>
                  {children}
                </div>
              </ModalContextProvider>
            </ProviderContextProvider>
          </EventEmitterContextProvider>
        </AppContextProvider>
      </SwrInitor>
    </>
  )
}
export const metadata = {
  title: 'Dify',
}
export default Layout
app/account/page.tsx
New file
@@ -0,0 +1,7 @@
import AccountPage from './account-page'
export default function Account() {
  return <div className='mx-auto w-full max-w-[640px] px-6 pt-12'>
    <AccountPage />
  </div>
}
app/activate/activateForm.tsx
New file
@@ -0,0 +1,67 @@
'use client'
import { useTranslation } from 'react-i18next'
import useSWR from 'swr'
import { useRouter, useSearchParams } from 'next/navigation'
import cn from '@/utils/classnames'
import Button from '@/app/components/base/button'
import { invitationCheck } from '@/service/common'
import Loading from '@/app/components/base/loading'
const ActivateForm = () => {
  const router = useRouter()
  const { t } = useTranslation()
  const searchParams = useSearchParams()
  const workspaceID = searchParams.get('workspace_id')
  const email = searchParams.get('email')
  const token = searchParams.get('token')
  const checkParams = {
    url: '/activate/check',
    params: {
      ...workspaceID && { workspace_id: workspaceID },
      ...email && { email },
      token,
    },
  }
  const { data: checkRes } = useSWR(checkParams, invitationCheck, {
    revalidateOnFocus: false,
    onSuccess(data) {
      if (data.is_valid) {
        const params = new URLSearchParams(searchParams)
        const { email, workspace_id } = data.data
        params.set('email', encodeURIComponent(email))
        params.set('workspace_id', encodeURIComponent(workspace_id))
        params.set('invite_token', encodeURIComponent(token as string))
        router.replace(`/signin?${params.toString()}`)
      }
    },
  })
  return (
    <div className={
      cn(
        'flex w-full grow flex-col items-center justify-center',
        'px-6',
        'md:px-[108px]',
      )
    }>
      {!checkRes && <Loading />}
      {checkRes && !checkRes.is_valid && (
        <div className="flex flex-col md:w-[400px]">
          <div className="mx-auto w-full">
            <div className="mb-3 flex h-20 w-20 items-center justify-center rounded-[20px] border border-divider-regular bg-components-option-card-option-bg p-5 text-[40px] font-bold shadow-lg">🤷‍♂️</div>
            <h2 className="text-[32px] font-bold text-text-primary">{t('login.invalid')}</h2>
          </div>
          <div className="mx-auto mt-6 w-full">
            <Button variant='primary' className='w-full !text-sm'>
              <a href="https://dify.ai">{t('login.explore')}</a>
            </Button>
          </div>
        </div>
      )}
    </div>
  )
}
export default ActivateForm
app/activate/page.tsx
New file
@@ -0,0 +1,20 @@
import React from 'react'
import Header from '../signin/_header'
import ActivateForm from './activateForm'
import cn from '@/utils/classnames'
const Activate = () => {
  return (
    <div className={cn('flex min-h-screen w-full justify-center bg-background-default-burn p-6')}>
      <div className={cn('flex w-full shrink-0 flex-col rounded-2xl border border-effects-highlight bg-background-default-subtle')}>
        <Header />
        <ActivateForm />
        <div className='px-8 py-6 text-sm font-normal text-text-tertiary'>
          © {new Date().getFullYear()} LangGenius, Inc. All rights reserved.
        </div>
      </div>
    </div>
  )
}
export default Activate
app/components/app-sidebar/app-info.tsx
New file
@@ -0,0 +1,418 @@
import { useTranslation } from 'react-i18next'
import { useRouter } from 'next/navigation'
import { useContext, useContextSelector } from 'use-context-selector'
import React, { useCallback, useState } from 'react'
import {
  RiDeleteBinLine,
  RiEditLine,
  RiEqualizer2Line,
  RiExchange2Line,
  RiFileCopy2Line,
  RiFileDownloadLine,
  RiFileUploadLine,
  RiMoreLine,
} from '@remixicon/react'
import AppIcon from '../base/app-icon'
import SwitchAppModal from '../app/switch-app-modal'
import cn from '@/utils/classnames'
import Confirm from '@/app/components/base/confirm'
import { useStore as useAppStore } from '@/app/components/app/store'
import { ToastContext } from '@/app/components/base/toast'
import AppsContext, { useAppContext } from '@/context/app-context'
import { useProviderContext } from '@/context/provider-context'
import { copyApp, deleteApp, exportAppConfig, updateAppInfo } from '@/service/apps'
import DuplicateAppModal from '@/app/components/app/duplicate-modal'
import type { DuplicateAppModalProps } from '@/app/components/app/duplicate-modal'
import CreateAppModal from '@/app/components/explore/create-app-modal'
import type { CreateAppModalProps } from '@/app/components/explore/create-app-modal'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import { getRedirection } from '@/utils/app-redirection'
import UpdateDSLModal from '@/app/components/workflow/update-dsl-modal'
import type { EnvironmentVariable } from '@/app/components/workflow/types'
import DSLExportConfirmModal from '@/app/components/workflow/dsl-export-confirm-modal'
import { fetchWorkflowDraft } from '@/service/workflow'
import ContentDialog from '@/app/components/base/content-dialog'
import Button from '@/app/components/base/button'
import CardView from '@/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/cardView'
import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '../base/portal-to-follow-elem'
export type IAppInfoProps = {
  expand: boolean
}
const AppInfo = ({ expand }: IAppInfoProps) => {
  const { t } = useTranslation()
  const { notify } = useContext(ToastContext)
  const { replace } = useRouter()
  const { onPlanInfoChanged } = useProviderContext()
  const appDetail = useAppStore(state => state.appDetail)
  const setAppDetail = useAppStore(state => state.setAppDetail)
  const [open, setOpen] = useState(false)
  const [showEditModal, setShowEditModal] = useState(false)
  const [showDuplicateModal, setShowDuplicateModal] = useState(false)
  const [showConfirmDelete, setShowConfirmDelete] = useState(false)
  const [showSwitchModal, setShowSwitchModal] = useState<boolean>(false)
  const [showImportDSLModal, setShowImportDSLModal] = useState<boolean>(false)
  const [secretEnvList, setSecretEnvList] = useState<EnvironmentVariable[]>([])
  const mutateApps = useContextSelector(
    AppsContext,
    state => state.mutateApps,
  )
  const onEdit: CreateAppModalProps['onConfirm'] = useCallback(async ({
    name,
    icon_type,
    icon,
    icon_background,
    description,
    use_icon_as_answer_icon,
  }) => {
    if (!appDetail)
      return
    try {
      const app = await updateAppInfo({
        appID: appDetail.id,
        name,
        icon_type,
        icon,
        icon_background,
        description,
        use_icon_as_answer_icon,
      })
      setShowEditModal(false)
      notify({
        type: 'success',
        message: t('app.editDone'),
      })
      setAppDetail(app)
      mutateApps()
    }
    catch {
      notify({ type: 'error', message: t('app.editFailed') })
    }
  }, [appDetail, mutateApps, notify, setAppDetail, t])
  const onCopy: DuplicateAppModalProps['onConfirm'] = async ({ name, icon_type, icon, icon_background }) => {
    if (!appDetail)
      return
    try {
      const newApp = await copyApp({
        appID: appDetail.id,
        name,
        icon_type,
        icon,
        icon_background,
        mode: appDetail.mode,
      })
      setShowDuplicateModal(false)
      notify({
        type: 'success',
        message: t('app.newApp.appCreated'),
      })
      localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1')
      mutateApps()
      onPlanInfoChanged()
      getRedirection(true, newApp, replace)
    }
    catch {
      notify({ type: 'error', message: t('app.newApp.appCreateFailed') })
    }
  }
  const onExport = async (include = false) => {
    if (!appDetail)
      return
    try {
      const { data } = await exportAppConfig({
        appID: appDetail.id,
        include,
      })
      const a = document.createElement('a')
      const file = new Blob([data], { type: 'application/yaml' })
      a.href = URL.createObjectURL(file)
      a.download = `${appDetail.name}.yml`
      a.click()
    }
    catch {
      notify({ type: 'error', message: t('app.exportFailed') })
    }
  }
  const exportCheck = async () => {
    if (!appDetail)
      return
    if (appDetail.mode !== 'workflow' && appDetail.mode !== 'advanced-chat') {
      onExport()
      return
    }
    try {
      const workflowDraft = await fetchWorkflowDraft(`/apps/${appDetail.id}/workflows/draft`)
      const list = (workflowDraft.environment_variables || []).filter(env => env.value_type === 'secret')
      if (list.length === 0) {
        onExport()
        return
      }
      setSecretEnvList(list)
    }
    catch {
      notify({ type: 'error', message: t('app.exportFailed') })
    }
  }
  const onConfirmDelete = useCallback(async () => {
    if (!appDetail)
      return
    try {
      await deleteApp(appDetail.id)
      notify({ type: 'success', message: t('app.appDeleted') })
      mutateApps()
      onPlanInfoChanged()
      setAppDetail()
      replace('/apps')
    }
    catch (e: any) {
      notify({
        type: 'error',
        message: `${t('app.appDeleteFailed')}${'message' in e ? `: ${e.message}` : ''}`,
      })
    }
    setShowConfirmDelete(false)
  }, [appDetail, mutateApps, notify, onPlanInfoChanged, replace, setAppDetail, t])
  const { isCurrentWorkspaceEditor } = useAppContext()
  const [showMore, setShowMore] = useState(false)
  const handleTriggerMore = useCallback(() => {
    setShowMore(true)
  }, [setShowMore])
  if (!appDetail)
    return null
  return (
    <div>
      <button
        onClick={() => {
          if (isCurrentWorkspaceEditor)
            setOpen(v => !v)
        }}
        className='block w-full'
      >
        <div className={cn('flex rounded-lg', expand ? 'flex-col gap-2 p-2 pb-2.5' : 'items-start justify-center gap-1 p-1', open && 'bg-state-base-hover', isCurrentWorkspaceEditor && 'cursor-pointer hover:bg-state-base-hover')}>
          <div className={`flex items-center self-stretch ${expand ? 'justify-between' : 'flex-col gap-1'}`}>
            <AppIcon
              size={expand ? 'large' : 'small'}
              iconType={appDetail.icon_type}
              icon={appDetail.icon}
              background={appDetail.icon_background}
              imageUrl={appDetail.icon_url}
            />
            <div className='flex items-center justify-center rounded-md p-0.5'>
              <div className='flex h-5 w-5 items-center justify-center'>
                <RiEqualizer2Line className='h-4 w-4 text-text-tertiary' />
              </div>
            </div>
          </div>
          {
            expand && (
              <div className='flex flex-col items-start gap-1'>
                <div className='flex w-full'>
                  <div className='system-md-semibold truncate text-text-secondary'>{appDetail.name}</div>
                </div>
                <div className='system-2xs-medium-uppercase text-text-tertiary'>{appDetail.mode === 'advanced-chat' ? t('app.types.advanced') : appDetail.mode === 'agent-chat' ? t('app.types.agent') : appDetail.mode === 'chat' ? t('app.types.chatbot') : appDetail.mode === 'completion' ? t('app.types.completion') : t('app.types.workflow')}</div>
              </div>
            )
          }
        </div>
      </button>
      <ContentDialog
        show={open}
        onClose={() => setOpen(false)}
        className='absolute bottom-2 left-2 top-2 flex w-[420px] flex-col rounded-2xl !p-0'
      >
        <div className='flex shrink-0 flex-col items-start justify-center gap-3 self-stretch p-4'>
          <div className='flex items-center gap-3 self-stretch'>
            <AppIcon
              size="large"
              iconType={appDetail.icon_type}
              icon={appDetail.icon}
              background={appDetail.icon_background}
              imageUrl={appDetail.icon_url}
            />
            <div className='flex w-full grow flex-col items-start justify-center'>
              <div className='system-md-semibold w-full truncate text-text-secondary'>{appDetail.name}</div>
              <div className='system-2xs-medium-uppercase text-text-tertiary'>{appDetail.mode === 'advanced-chat' ? t('app.types.advanced') : appDetail.mode === 'agent-chat' ? t('app.types.agent') : appDetail.mode === 'chat' ? t('app.types.chatbot') : appDetail.mode === 'completion' ? t('app.types.completion') : t('app.types.workflow')}</div>
            </div>
          </div>
          {/* description */}
          {appDetail.description && (
            <div className='system-xs-regular text-text-tertiary'>{appDetail.description}</div>
          )}
          {/* operations */}
          <div className='flex flex-wrap items-center gap-1 self-stretch'>
            <Button
              size={'small'}
              variant={'secondary'}
              className='gap-[1px]'
              onClick={() => {
                setOpen(false)
                setShowEditModal(true)
              }}
            >
              <RiEditLine className='h-3.5 w-3.5 text-components-button-secondary-text' />
              <span className='system-xs-medium text-components-button-secondary-text'>{t('app.editApp')}</span>
            </Button>
            <Button
              size={'small'}
              variant={'secondary'}
              className='gap-[1px]'
              onClick={() => {
                setOpen(false)
                setShowDuplicateModal(true)
              }}
            >
              <RiFileCopy2Line className='h-3.5 w-3.5 text-components-button-secondary-text' />
              <span className='system-xs-medium text-components-button-secondary-text'>{t('app.duplicate')}</span>
            </Button>
            <Button
              size={'small'}
              variant={'secondary'}
              className='gap-[1px]'
              onClick={exportCheck}
            >
              <RiFileDownloadLine className='h-3.5 w-3.5 text-components-button-secondary-text' />
              <span className='system-xs-medium text-components-button-secondary-text'>{t('app.export')}</span>
            </Button>
            {appDetail.mode !== 'agent-chat' && <PortalToFollowElem
              open={showMore}
              onOpenChange={setShowMore}
              placement='bottom-end'
              offset={{
                mainAxis: 4,
              }}>
              <PortalToFollowElemTrigger onClick={handleTriggerMore}>
                <Button
                  size={'small'}
                  variant={'secondary'}
                  className='gap-[1px]'
                >
                  <RiMoreLine className='h-3.5 w-3.5 text-components-button-secondary-text' />
                  <span className='system-xs-medium text-components-button-secondary-text'>{t('common.operation.more')}</span>
                </Button>
              </PortalToFollowElemTrigger>
              <PortalToFollowElemContent className='z-[21]'>
                <div className='flex w-[264px] flex-col rounded-[12px] border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-1 shadow-lg backdrop-blur-[5px]'>
                  {
                    (appDetail.mode === 'advanced-chat' || appDetail.mode === 'workflow')
                    && <div className='flex h-8 cursor-pointer items-center gap-x-1 rounded-lg p-1.5 hover:bg-state-base-hover'
                      onClick={() => {
                        setOpen(false)
                        setShowImportDSLModal(true)
                      }}>
                      <RiFileUploadLine className='h-4 w-4 text-text-tertiary' />
                      <span className='system-md-regular text-text-secondary'>{t('workflow.common.importDSL')}</span>
                    </div>
                  }
                  {
                    (appDetail.mode === 'completion' || appDetail.mode === 'chat')
                    && <div className='flex h-8 cursor-pointer items-center gap-x-1 rounded-lg p-1.5 hover:bg-state-base-hover'
                      onClick={() => {
                        setOpen(false)
                        setShowSwitchModal(true)
                      }}>
                      <RiExchange2Line className='h-4 w-4 text-text-tertiary' />
                      <span className='system-md-regular text-text-secondary'>{t('app.switch')}</span>
                    </div>
                  }
                </div>
              </PortalToFollowElemContent>
            </PortalToFollowElem>}
          </div>
        </div>
        <div className='flex flex-1'>
          <CardView
            appId={appDetail.id}
            isInPanel={true}
            className='flex grow flex-col gap-2 overflow-auto px-2 py-1'
          />
        </div>
        <div className='flex min-h-fit shrink-0 flex-col items-start justify-center gap-3 self-stretch border-t-[0.5px] border-divider-subtle p-2'>
          <Button
            size={'medium'}
            variant={'ghost'}
            className='gap-0.5'
            onClick={() => {
              setOpen(false)
              setShowConfirmDelete(true)
            }}
          >
            <RiDeleteBinLine className='h-4 w-4 text-text-tertiary' />
            <span className='system-sm-medium text-text-tertiary'>{t('common.operation.deleteApp')}</span>
          </Button>
        </div>
      </ContentDialog>
      {showSwitchModal && (
        <SwitchAppModal
          inAppDetail
          show={showSwitchModal}
          appDetail={appDetail}
          onClose={() => setShowSwitchModal(false)}
          onSuccess={() => setShowSwitchModal(false)}
        />
      )}
      {showEditModal && (
        <CreateAppModal
          isEditModal
          appName={appDetail.name}
          appIconType={appDetail.icon_type}
          appIcon={appDetail.icon}
          appIconBackground={appDetail.icon_background}
          appIconUrl={appDetail.icon_url}
          appDescription={appDetail.description}
          appMode={appDetail.mode}
          appUseIconAsAnswerIcon={appDetail.use_icon_as_answer_icon}
          show={showEditModal}
          onConfirm={onEdit}
          onHide={() => setShowEditModal(false)}
        />
      )}
      {showDuplicateModal && (
        <DuplicateAppModal
          appName={appDetail.name}
          icon_type={appDetail.icon_type}
          icon={appDetail.icon}
          icon_background={appDetail.icon_background}
          icon_url={appDetail.icon_url}
          show={showDuplicateModal}
          onConfirm={onCopy}
          onHide={() => setShowDuplicateModal(false)}
        />
      )}
      {showConfirmDelete && (
        <Confirm
          title={t('app.deleteAppConfirmTitle')}
          content={t('app.deleteAppConfirmContent')}
          isShow={showConfirmDelete}
          onConfirm={onConfirmDelete}
          onCancel={() => setShowConfirmDelete(false)}
        />
      )}
      {showImportDSLModal && (
        <UpdateDSLModal
          onCancel={() => setShowImportDSLModal(false)}
          onBackup={exportCheck}
        />
      )}
      {secretEnvList.length > 0 && (
        <DSLExportConfirmModal
          envList={secretEnvList}
          onConfirm={onExport}
          onClose={() => setSecretEnvList([])}
        />
      )}
    </div>
  )
}
export default React.memo(AppInfo)
app/components/app-sidebar/basic.tsx
New file
@@ -0,0 +1,99 @@
import React from 'react'
import { useTranslation } from 'react-i18next'
import AppIcon from '../base/app-icon'
import Tooltip from '@/app/components/base/tooltip'
export type IAppBasicProps = {
  iconType?: 'app' | 'api' | 'dataset' | 'webapp' | 'notion'
  icon?: string
  icon_background?: string | null
  isExternal?: boolean
  name: string
  type: string | React.ReactNode
  hoverTip?: string
  textStyle?: { main?: string; extra?: string }
  isExtraInLine?: boolean
  mode?: string
}
const ApiSvg = <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M8.5 3.5C8.5 4.60457 9.39543 5.5 10.5 5.5C11.6046 5.5 12.5 4.60457 12.5 3.5C12.5 2.39543 11.6046 1.5 10.5 1.5C9.39543 1.5 8.5 2.39543 8.5 3.5Z" stroke="#5850EC" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
  <path d="M12.5 9C12.5 10.1046 13.3954 11 14.5 11C15.6046 11 16.5 10.1046 16.5 9C16.5 7.89543 15.6046 7 14.5 7C13.3954 7 12.5 7.89543 12.5 9Z" stroke="#5850EC" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
  <path d="M8.5 3.5H5.5L3.5 6.5" stroke="#5850EC" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
  <path d="M8.5 14.5C8.5 15.6046 9.39543 16.5 10.5 16.5C11.6046 16.5 12.5 15.6046 12.5 14.5C12.5 13.3954 11.6046 12.5 10.5 12.5C9.39543 12.5 8.5 13.3954 8.5 14.5Z" stroke="#5850EC" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
  <path d="M8.5 14.5H5.5L3.5 11.5" stroke="#5850EC" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
  <path d="M12.5 9H1.5" stroke="#5850EC" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
</svg>
const DatasetSvg = <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path fillRule="evenodd" clipRule="evenodd" d="M0.833497 5.13481C0.833483 4.69553 0.83347 4.31654 0.858973 4.0044C0.88589 3.67495 0.94532 3.34727 1.10598 3.03195C1.34567 2.56155 1.72812 2.17909 2.19852 1.93941C2.51384 1.77875 2.84152 1.71932 3.17097 1.6924C3.48312 1.6669 3.86209 1.66691 4.30137 1.66693L7.62238 1.66684C8.11701 1.66618 8.55199 1.66561 8.95195 1.80356C9.30227 1.92439 9.62134 2.12159 9.88607 2.38088C10.1883 2.67692 10.3823 3.06624 10.603 3.50894L11.3484 5.00008H14.3679C15.0387 5.00007 15.5924 5.00006 16.0434 5.03691C16.5118 5.07518 16.9424 5.15732 17.3468 5.36339C17.974 5.68297 18.4839 6.19291 18.8035 6.82011C19.0096 7.22456 19.0917 7.65515 19.13 8.12356C19.1668 8.57455 19.1668 9.12818 19.1668 9.79898V13.5345C19.1668 14.2053 19.1668 14.7589 19.13 15.2099C19.0917 15.6784 19.0096 16.1089 18.8035 16.5134C18.4839 17.1406 17.974 17.6505 17.3468 17.9701C16.9424 18.1762 16.5118 18.2583 16.0434 18.2966C15.5924 18.3334 15.0387 18.3334 14.3679 18.3334H5.63243C4.96163 18.3334 4.40797 18.3334 3.95698 18.2966C3.48856 18.2583 3.05798 18.1762 2.65353 17.9701C2.02632 17.6505 1.51639 17.1406 1.19681 16.5134C0.990734 16.1089 0.908597 15.6784 0.870326 15.2099C0.833478 14.7589 0.833487 14.2053 0.833497 13.5345V5.13481ZM7.51874 3.33359C8.17742 3.33359 8.30798 3.34447 8.4085 3.37914C8.52527 3.41942 8.63163 3.48515 8.71987 3.57158C8.79584 3.64598 8.86396 3.7579 9.15852 4.34704L9.48505 5.00008L2.50023 5.00008C2.50059 4.61259 2.50314 4.34771 2.5201 4.14012C2.5386 3.91374 2.57 3.82981 2.59099 3.7886C2.67089 3.6318 2.79837 3.50432 2.95517 3.42442C2.99638 3.40343 3.08031 3.37203 3.30669 3.35353C3.54281 3.33424 3.85304 3.33359 4.3335 3.33359H7.51874Z" fill="#444CE7" />
</svg>
const WebappSvg = <svg width="16" height="18" viewBox="0 0 16 18" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M14.375 5.45825L7.99998 8.99992M7.99998 8.99992L1.62498 5.45825M7.99998 8.99992L8 16.1249M14.75 12.0439V5.95603C14.75 5.69904 14.75 5.57055 14.7121 5.45595C14.6786 5.35457 14.6239 5.26151 14.5515 5.18299C14.4697 5.09424 14.3574 5.03184 14.1328 4.90704L8.58277 1.8237C8.37007 1.70553 8.26372 1.64645 8.15109 1.62329C8.05141 1.60278 7.9486 1.60278 7.84891 1.62329C7.73628 1.64645 7.62993 1.70553 7.41723 1.8237L1.86723 4.90704C1.64259 5.03184 1.53026 5.09424 1.44847 5.18299C1.37612 5.26151 1.32136 5.35457 1.28786 5.45595C1.25 5.57055 1.25 5.69904 1.25 5.95603V12.0439C1.25 12.3008 1.25 12.4293 1.28786 12.5439C1.32136 12.6453 1.37612 12.7384 1.44847 12.8169C1.53026 12.9056 1.64259 12.968 1.86723 13.0928L7.41723 16.1762C7.62993 16.2943 7.73628 16.3534 7.84891 16.3766C7.9486 16.3971 8.05141 16.3971 8.15109 16.3766C8.26372 16.3534 8.37007 16.2943 8.58277 16.1762L14.1328 13.0928C14.3574 12.968 14.4697 12.9056 14.5515 12.8169C14.6239 12.7384 14.6786 12.6453 14.7121 12.5439C14.75 12.4293 14.75 12.3008 14.75 12.0439Z" stroke="#155EEF" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
</svg>
const NotionSvg = <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  <g clipPath="url(#clip0_6294_13848)">
    <path fill-rule="evenodd" clip-rule="evenodd" d="M4.287 21.9133L1.70748 18.6999C1.08685 17.9267 0.75 16.976 0.75 15.9974V4.36124C0.75 2.89548 1.92269 1.67923 3.43553 1.57594L15.3991 0.759137C16.2682 0.699797 17.1321 0.930818 17.8461 1.41353L22.0494 4.25543C22.8018 4.76414 23.25 5.59574 23.25 6.48319V19.7124C23.25 21.1468 22.0969 22.3345 20.6157 22.4256L7.3375 23.243C6.1555 23.3158 5.01299 22.8178 4.287 21.9133Z" fill="white" />
    <path d="M8.43607 10.1842V10.0318C8.43607 9.64564 8.74535 9.32537 9.14397 9.29876L12.0475 9.10491L16.0628 15.0178V9.82823L15.0293 9.69046V9.6181C15.0293 9.22739 15.3456 8.90501 15.7493 8.88433L18.3912 8.74899V9.12918C18.3912 9.30765 18.2585 9.46031 18.0766 9.49108L17.4408 9.59861V18.0029L16.6429 18.2773C15.9764 18.5065 15.2343 18.2611 14.8527 17.6853L10.9545 11.803V17.4173L12.1544 17.647L12.1377 17.7583C12.0853 18.1069 11.7843 18.3705 11.4202 18.3867L8.43607 18.5195C8.39662 18.1447 8.67758 17.8093 9.06518 17.7686L9.45771 17.7273V10.2416L8.43607 10.1842Z" fill="black" />
    <path fill-rule="evenodd" clip-rule="evenodd" d="M15.5062 2.22521L3.5426 3.04201C2.82599 3.09094 2.27051 3.66706 2.27051 4.36136V15.9975C2.27051 16.6499 2.49507 17.2837 2.90883 17.7992L5.48835 21.0126C5.90541 21.5322 6.56174 21.8183 7.24076 21.7765L20.519 20.9591C21.1995 20.9172 21.7293 20.3716 21.7293 19.7125V6.48332C21.7293 6.07557 21.5234 5.69348 21.1777 5.45975L16.9743 2.61784C16.546 2.32822 16.0277 2.1896 15.5062 2.22521ZM4.13585 4.54287C3.96946 4.41968 4.04865 4.16303 4.25768 4.14804L15.5866 3.33545C15.9476 3.30956 16.3063 3.40896 16.5982 3.61578L18.8713 5.22622C18.9576 5.28736 18.9171 5.41935 18.8102 5.42516L6.8129 6.07764C6.44983 6.09739 6.09144 5.99073 5.80276 5.77699L4.13585 4.54287ZM6.25018 8.12315C6.25018 7.7334 6.56506 7.41145 6.9677 7.38952L19.6523 6.69871C20.0447 6.67734 20.375 6.97912 20.375 7.35898V18.8141C20.375 19.2031 20.0613 19.5247 19.6594 19.5476L7.05516 20.2648C6.61845 20.2896 6.25018 19.954 6.25018 19.5312V8.12315Z" fill="black" />
  </g>
  <defs>
    <clipPath id="clip0_6294_13848">
      <rect width="24" height="24" fill="white" />
    </clipPath>
  </defs>
</svg>
const ICON_MAP = {
  app: <AppIcon className='border !border-[rgba(0,0,0,0.05)]' />,
  api: <AppIcon innerIcon={ApiSvg} className='border !border-purple-200 !bg-purple-50' />,
  dataset: <AppIcon innerIcon={DatasetSvg} className='!border-[0.5px] !border-indigo-100 !bg-indigo-25' />,
  webapp: <AppIcon innerIcon={WebappSvg} className='border !border-primary-200 !bg-primary-100' />,
  notion: <AppIcon innerIcon={NotionSvg} className='!border-[0.5px] !border-indigo-100 !bg-white' />,
}
export default function AppBasic({ icon, icon_background, name, isExternal, type, hoverTip, textStyle, isExtraInLine, mode = 'expand', iconType = 'app' }: IAppBasicProps) {
  const { t } = useTranslation()
  return (
    <div className="flex grow items-center">
      {icon && icon_background && iconType === 'app' && (
        <div className='mr-3 shrink-0'>
          <AppIcon icon={icon} background={icon_background} />
        </div>
      )}
      {iconType !== 'app'
        && <div className='mr-3 shrink-0'>
          {ICON_MAP[iconType]}
        </div>
      }
      {mode === 'expand' && <div className="group w-full">
        <div className={`system-md-semibold flex flex-row items-center text-text-secondary group-hover:text-text-primary ${textStyle?.main ?? ''}`}>
          <div className="min-w-0 overflow-hidden text-ellipsis break-normal">
            {name}
          </div>
          {hoverTip
            && <Tooltip
              popupContent={
                <div className='w-[240px]'>
                  {hoverTip}
                </div>
              }
              popupClassName='ml-1'
              triggerClassName='w-4 h-4 ml-1'
              position='top'
            />
          }
        </div>
        {isExtraInLine ? (
          <div className="system-2xs-medium-uppercase flex text-text-tertiary">{type}</div>
        ) : (
          <div className='system-2xs-medium-uppercase text-text-tertiary'>{isExternal ? t('dataset.externalTag') : type}</div>
        )}
      </div>}
    </div>
  )
}
app/components/app-sidebar/completion.png
app/components/app-sidebar/dataset-info.tsx
New file
@@ -0,0 +1,45 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import AppIcon from '../base/app-icon'
const DatasetSvg = <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path fillRule="evenodd" clipRule="evenodd" d="M0.833497 5.13481C0.833483 4.69553 0.83347 4.31654 0.858973 4.0044C0.88589 3.67495 0.94532 3.34727 1.10598 3.03195C1.34567 2.56155 1.72812 2.17909 2.19852 1.93941C2.51384 1.77875 2.84152 1.71932 3.17097 1.6924C3.48312 1.6669 3.86209 1.66691 4.30137 1.66693L7.62238 1.66684C8.11701 1.66618 8.55199 1.66561 8.95195 1.80356C9.30227 1.92439 9.62134 2.12159 9.88607 2.38088C10.1883 2.67692 10.3823 3.06624 10.603 3.50894L11.3484 5.00008H14.3679C15.0387 5.00007 15.5924 5.00006 16.0434 5.03691C16.5118 5.07518 16.9424 5.15732 17.3468 5.36339C17.974 5.68297 18.4839 6.19291 18.8035 6.82011C19.0096 7.22456 19.0917 7.65515 19.13 8.12356C19.1668 8.57455 19.1668 9.12818 19.1668 9.79898V13.5345C19.1668 14.2053 19.1668 14.7589 19.13 15.2099C19.0917 15.6784 19.0096 16.1089 18.8035 16.5134C18.4839 17.1406 17.974 17.6505 17.3468 17.9701C16.9424 18.1762 16.5118 18.2583 16.0434 18.2966C15.5924 18.3334 15.0387 18.3334 14.3679 18.3334H5.63243C4.96163 18.3334 4.40797 18.3334 3.95698 18.2966C3.48856 18.2583 3.05798 18.1762 2.65353 17.9701C2.02632 17.6505 1.51639 17.1406 1.19681 16.5134C0.990734 16.1089 0.908597 15.6784 0.870326 15.2099C0.833478 14.7589 0.833487 14.2053 0.833497 13.5345V5.13481ZM7.51874 3.33359C8.17742 3.33359 8.30798 3.34447 8.4085 3.37914C8.52527 3.41942 8.63163 3.48515 8.71987 3.57158C8.79584 3.64598 8.86396 3.7579 9.15852 4.34704L9.48505 5.00008L2.50023 5.00008C2.50059 4.61259 2.50314 4.34771 2.5201 4.14012C2.5386 3.91374 2.57 3.82981 2.59099 3.7886C2.67089 3.6318 2.79837 3.50432 2.95517 3.42442C2.99638 3.40343 3.08031 3.37203 3.30669 3.35353C3.54281 3.33424 3.85304 3.33359 4.3335 3.33359H7.51874Z" fill="#444CE7" />
</svg>
type Props = {
  isExternal?: boolean
  name: string
  description: string
  expand: boolean
  extraInfo?: React.ReactNode
}
const DatasetInfo: FC<Props> = ({
  name,
  description,
  isExternal,
  expand,
  extraInfo,
}) => {
  const { t } = useTranslation()
  return (
    <div className='pl-1 pt-1'>
      <div className='mr-3 shrink-0'>
        <AppIcon innerIcon={DatasetSvg} className='!border-[0.5px] !border-indigo-100 !bg-indigo-25' />
      </div>
      {expand && (
        <div className='mt-2'>
          <div className='system-md-semibold text-text-secondary'>
            {name}
          </div>
          <div className='system-2xs-medium-uppercase mt-1 text-text-tertiary'>{isExternal ? t('dataset.externalTag') : t('dataset.localDocs')}</div>
          <div className='system-xs-regular  my-3 text-text-tertiary first-letter:capitalize'>{description}</div>
        </div>
      )}
      {extraInfo}
    </div>
  )
}
export default React.memo(DatasetInfo)
app/components/app-sidebar/expert.png
app/components/app-sidebar/index.tsx
New file
@@ -0,0 +1,126 @@
import React, { useEffect } from 'react'
import { useShallow } from 'zustand/react/shallow'
import { RiLayoutLeft2Line, RiLayoutRight2Line } from '@remixicon/react'
import NavLink from './navLink'
import type { NavIcon } from './navLink'
import AppBasic from './basic'
import AppInfo from './app-info'
import DatasetInfo from './dataset-info'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import { useStore as useAppStore } from '@/app/components/app/store'
import cn from '@/utils/classnames'
export type IAppDetailNavProps = {
  iconType?: 'app' | 'dataset' | 'notion'
  title: string
  desc: string
  isExternal?: boolean
  icon: string
  icon_background: string
  navigation: Array<{
    name: string
    href: string
    icon: NavIcon
    selectedIcon: NavIcon
  }>
  extraInfo?: (modeState: string) => React.ReactNode
}
const AppDetailNav = ({ title, desc, isExternal, icon, icon_background, navigation, extraInfo, iconType = 'app' }: IAppDetailNavProps) => {
  const { appSidebarExpand, setAppSiderbarExpand } = useAppStore(useShallow(state => ({
    appSidebarExpand: state.appSidebarExpand,
    setAppSiderbarExpand: state.setAppSiderbarExpand,
  })))
  const media = useBreakpoints()
  const isMobile = media === MediaType.mobile
  const expand = appSidebarExpand === 'expand'
  const handleToggle = (state: string) => {
    setAppSiderbarExpand(state === 'expand' ? 'collapse' : 'expand')
  }
  useEffect(() => {
    if (appSidebarExpand) {
      localStorage.setItem('app-detail-collapse-or-expand', appSidebarExpand)
      setAppSiderbarExpand(appSidebarExpand)
    }
  }, [appSidebarExpand, setAppSiderbarExpand])
  return (
    <div
      className={`
        flex shrink-0 flex-col border-r border-divider-burn bg-background-default-subtle transition-all
        ${expand ? 'w-[216px]' : 'w-14'}
      `}
    >
      <div
        className={`
          shrink-0
          ${expand ? 'p-2' : 'p-1'}
        `}
      >
        {iconType === 'app' && (
          <AppInfo expand={expand} />
        )}
        {iconType === 'dataset' && (
          <DatasetInfo
            name={title}
            description={desc}
            isExternal={isExternal}
            expand={expand}
            extraInfo={extraInfo && extraInfo(appSidebarExpand)}
          />
        )}
        {!['app', 'dataset'].includes(iconType) && (
          <AppBasic
            mode={appSidebarExpand}
            iconType={iconType}
            icon={icon}
            icon_background={icon_background}
            name={title}
            type={desc}
            isExternal={isExternal}
          />
        )}
      </div>
      <div className='px-4'>
        <div className={cn('mx-auto mt-1 h-[1px] bg-divider-subtle', !expand && 'w-6')} />
      </div>
      <nav
        className={`
          grow space-y-1
          ${expand ? 'p-4' : 'px-2.5 py-4'}
        `}
      >
        {navigation.map((item, index) => {
          return (
            <NavLink key={index} mode={appSidebarExpand} iconMap={{ selected: item.selectedIcon, normal: item.icon }} name={item.name} href={item.href} />
          )
        })}
      </nav>
      {
        !isMobile && (
          <div
            className={`
              shrink-0 py-3
              ${expand ? 'px-6' : 'px-4'}
            `}
          >
            <div
              className='flex h-6 w-6 cursor-pointer items-center justify-center'
              onClick={() => handleToggle(appSidebarExpand)}
            >
              {
                expand
                  ? <RiLayoutRight2Line className='h-5 w-5 text-components-menu-item-text' />
                  : <RiLayoutLeft2Line className='h-5 w-5 text-components-menu-item-text' />
              }
            </div>
          </div>
        )
      }
    </div>
  )
}
export default React.memo(AppDetailNav)
app/components/app-sidebar/navLink.tsx
New file
@@ -0,0 +1,63 @@
'use client'
import { useSelectedLayoutSegment } from 'next/navigation'
import Link from 'next/link'
import classNames from '@/utils/classnames'
import type { RemixiconComponentType } from '@remixicon/react'
export type NavIcon = React.ComponentType<
React.PropsWithoutRef<React.ComponentProps<'svg'>> & {
  title?: string | undefined
  titleId?: string | undefined
}> | RemixiconComponentType
export type NavLinkProps = {
  name: string
  href: string
  iconMap: {
    selected: NavIcon
    normal: NavIcon
  }
  mode?: string
}
export default function NavLink({
  name,
  href,
  iconMap,
  mode = 'expand',
}: NavLinkProps) {
  const segment = useSelectedLayoutSegment()
  const formattedSegment = (() => {
    let res = segment?.toLowerCase()
    // logs and annotations use the same nav
    if (res === 'annotations')
      res = 'logs'
    return res
  })()
  const isActive = href.toLowerCase().split('/')?.pop() === formattedSegment
  const NavIcon = isActive ? iconMap.selected : iconMap.normal
  return (
    <Link
      key={name}
      href={href}
      className={classNames(
        isActive ? 'bg-state-accent-active text-text-accent font-semibold' : 'text-components-menu-item-text hover:bg-state-base-hover hover:text-components-menu-item-text-hover',
        'group flex items-center h-9 rounded-md py-2 text-sm font-normal',
        mode === 'expand' ? 'px-3' : 'px-2.5',
      )}
      title={mode === 'collapse' ? name : ''}
    >
      <NavIcon
        className={classNames(
          'h-4 w-4 flex-shrink-0',
          mode === 'expand' ? 'mr-2' : 'mr-0',
        )}
        aria-hidden="true"
      />
      {mode === 'expand' && name}
    </Link>
  )
}
app/components/app-sidebar/style.module.css
New file
@@ -0,0 +1,11 @@
.sidebar {
    border-right: 1px solid #F3F4F6;
}
.completionPic {
background-image: url('./completion.png')
}
.expertPic {
background-image: url('./expert.png')
}
app/components/app/annotation/add-annotation-modal/edit-item/index.tsx
New file
@@ -0,0 +1,45 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import Textarea from '@/app/components/base/textarea'
import { Robot, User } from '@/app/components/base/icons/src/public/avatar'
export enum EditItemType {
  Query = 'query',
  Answer = 'answer',
}
type Props = {
  type: EditItemType
  content: string
  onChange: (content: string) => void
}
const EditItem: FC<Props> = ({
  type,
  content,
  onChange,
}) => {
  const { t } = useTranslation()
  const avatar = type === EditItemType.Query ? <User className='h-6 w-6' /> : <Robot className='h-6 w-6' />
  const name = type === EditItemType.Query ? t('appAnnotation.addModal.queryName') : t('appAnnotation.addModal.answerName')
  const placeholder = type === EditItemType.Query ? t('appAnnotation.addModal.queryPlaceholder') : t('appAnnotation.addModal.answerPlaceholder')
  return (
    <div className='flex' onClick={e => e.stopPropagation()}>
      <div className='mr-3 shrink-0'>
        {avatar}
      </div>
      <div className='grow'>
        <div className='system-xs-semibold mb-1 text-text-primary'>{name}</div>
        <Textarea
          value={content}
          onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => onChange(e.target.value)}
          placeholder={placeholder}
          autoFocus
        />
      </div>
    </div>
  )
}
export default React.memo(EditItem)
app/components/app/annotation/add-annotation-modal/index.tsx
New file
@@ -0,0 +1,121 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import type { AnnotationItemBasic } from '../type'
import EditItem, { EditItemType } from './edit-item'
import Checkbox from '@/app/components/base/checkbox'
import Drawer from '@/app/components/base/drawer-plus'
import Button from '@/app/components/base/button'
import Toast from '@/app/components/base/toast'
import { useProviderContext } from '@/context/provider-context'
import AnnotationFull from '@/app/components/billing/annotation-full'
type Props = {
  isShow: boolean
  onHide: () => void
  onAdd: (payload: AnnotationItemBasic) => void
}
const AddAnnotationModal: FC<Props> = ({
  isShow,
  onHide,
  onAdd,
}) => {
  const { t } = useTranslation()
  const { plan, enableBilling } = useProviderContext()
  const isAnnotationFull = (enableBilling && plan.usage.annotatedResponse >= plan.total.annotatedResponse)
  const [question, setQuestion] = useState('')
  const [answer, setAnswer] = useState('')
  const [isCreateNext, setIsCreateNext] = useState(false)
  const [isSaving, setIsSaving] = useState(false)
  const isValid = (payload: AnnotationItemBasic) => {
    if (!payload.question)
      return t('appAnnotation.errorMessage.queryRequired')
    if (!payload.answer)
      return t('appAnnotation.errorMessage.answerRequired')
    return true
  }
  const handleSave = async () => {
    const payload = {
      question,
      answer,
    }
    if (isValid(payload) !== true) {
      Toast.notify({
        type: 'error',
        message: isValid(payload) as string,
      })
      return
    }
    setIsSaving(true)
    try {
      await onAdd(payload)
    }
    catch {
    }
    setIsSaving(false)
    if (isCreateNext) {
      setQuestion('')
      setAnswer('')
    }
    else {
      onHide()
    }
  }
  return (
    <div>
      <Drawer
        isShow={isShow}
        onHide={onHide}
        maxWidthClassName='!max-w-[480px]'
        title={t('appAnnotation.addModal.title') as string}
        body={(
          <div className='space-y-6 p-6 pb-4'>
            <EditItem
              type={EditItemType.Query}
              content={question}
              onChange={setQuestion}
            />
            <EditItem
              type={EditItemType.Answer}
              content={answer}
              onChange={setAnswer}
            />
          </div>
        )}
        foot={
          (
            <div>
              {isAnnotationFull && (
                <div className='mb-4 mt-6 px-6'>
                  <AnnotationFull />
                </div>
              )}
              <div className='system-sm-medium flex h-16 items-center justify-between rounded-bl-xl rounded-br-xl border-t border-divider-subtle bg-background-section-burn px-4 text-text-tertiary'>
                <div
                  className='flex items-center space-x-2'
                >
                  <Checkbox checked={isCreateNext} onCheck={() => setIsCreateNext(!isCreateNext)} />
                  <div>{t('appAnnotation.addModal.createNext')}</div>
                </div>
                <div className='mt-2 flex space-x-2'>
                  <Button className='h-7 text-xs' onClick={onHide}>{t('common.operation.cancel')}</Button>
                  <Button className='h-7 text-xs' variant='primary' onClick={handleSave} loading={isSaving} disabled={isAnnotationFull}>{t('common.operation.add')}</Button>
                </div>
              </div>
            </div>
          )
        }
      >
      </Drawer>
    </div>
  )
}
export default React.memo(AddAnnotationModal)
app/components/app/annotation/batch-add-annotation-modal/csv-downloader.tsx
New file
@@ -0,0 +1,73 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import {
  useCSVDownloader,
} from 'react-papaparse'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { Download02 as DownloadIcon } from '@/app/components/base/icons/src/vender/solid/general'
import I18n from '@/context/i18n'
import { LanguagesSupported } from '@/i18n/language'
const CSV_TEMPLATE_QA_EN = [
  ['question', 'answer'],
  ['question1', 'answer1'],
  ['question2', 'answer2'],
]
const CSV_TEMPLATE_QA_CN = [
  ['问题', '答案'],
  ['问题 1', '答案 1'],
  ['问题 2', '答案 2'],
]
const CSVDownload: FC = () => {
  const { t } = useTranslation()
  const { locale } = useContext(I18n)
  const { CSVDownloader, Type } = useCSVDownloader()
  const getTemplate = () => {
    return locale !== LanguagesSupported[1] ? CSV_TEMPLATE_QA_EN : CSV_TEMPLATE_QA_CN
  }
  return (
    <div className='mt-6'>
      <div className='system-sm-medium text-text-primary'>{t('share.generation.csvStructureTitle')}</div>
      <div className='mt-2 max-h-[500px] overflow-auto'>
        <table className='w-full table-fixed border-separate border-spacing-0 rounded-lg border border-divider-regular text-xs'>
          <thead className='text-text-tertiary'>
            <tr>
              <td className='h-9 border-b border-divider-regular pl-3 pr-2'>{t('appAnnotation.batchModal.question')}</td>
              <td className='h-9 border-b border-divider-regular pl-3 pr-2'>{t('appAnnotation.batchModal.answer')}</td>
            </tr>
          </thead>
          <tbody className='text-text-secondary'>
            <tr>
              <td className='h-9 border-b border-divider-subtle pl-3 pr-2 text-[13px]'>{t('appAnnotation.batchModal.question')} 1</td>
              <td className='h-9 border-b border-divider-subtle pl-3 pr-2 text-[13px]'>{t('appAnnotation.batchModal.answer')} 1</td>
            </tr>
            <tr>
              <td className='h-9 pl-3 pr-2 text-[13px]'>{t('appAnnotation.batchModal.question')} 2</td>
              <td className='h-9 pl-3 pr-2 text-[13px]'>{t('appAnnotation.batchModal.answer')} 2</td>
            </tr>
          </tbody>
        </table>
      </div>
      <CSVDownloader
        className="mt-2 block cursor-pointer"
        type={Type.Link}
        filename={`template-${locale}`}
        bom={true}
        data={getTemplate()}
      >
        <div className='system-xs-medium flex h-[18px] items-center space-x-1 text-text-accent'>
          <DownloadIcon className='mr-1 h-3 w-3' />
          {t('appAnnotation.batchModal.template')}
        </div>
      </CSVDownloader>
    </div>
  )
}
export default React.memo(CSVDownload)
app/components/app/annotation/batch-add-annotation-modal/csv-uploader.tsx
New file
@@ -0,0 +1,126 @@
'use client'
import type { FC } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { RiDeleteBinLine } from '@remixicon/react'
import cn from '@/utils/classnames'
import { Csv as CSVIcon } from '@/app/components/base/icons/src/public/files'
import { ToastContext } from '@/app/components/base/toast'
import Button from '@/app/components/base/button'
export type Props = {
  file: File | undefined
  updateFile: (file?: File) => void
}
const CSVUploader: FC<Props> = ({
  file,
  updateFile,
}) => {
  const { t } = useTranslation()
  const { notify } = useContext(ToastContext)
  const [dragging, setDragging] = useState(false)
  const dropRef = useRef<HTMLDivElement>(null)
  const dragRef = useRef<HTMLDivElement>(null)
  const fileUploader = useRef<HTMLInputElement>(null)
  const handleDragEnter = (e: DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    e.target !== dragRef.current && setDragging(true)
  }
  const handleDragOver = (e: DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
  }
  const handleDragLeave = (e: DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    e.target === dragRef.current && setDragging(false)
  }
  const handleDrop = (e: DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setDragging(false)
    if (!e.dataTransfer)
      return
    const files = [...e.dataTransfer.files]
    if (files.length > 1) {
      notify({ type: 'error', message: t('datasetCreation.stepOne.uploader.validation.count') })
      return
    }
    updateFile(files[0])
  }
  const selectHandle = () => {
    if (fileUploader.current)
      fileUploader.current.click()
  }
  const removeFile = () => {
    if (fileUploader.current)
      fileUploader.current.value = ''
    updateFile()
  }
  const fileChangeHandle = (e: React.ChangeEvent<HTMLInputElement>) => {
    const currentFile = e.target.files?.[0]
    updateFile(currentFile)
  }
  useEffect(() => {
    dropRef.current?.addEventListener('dragenter', handleDragEnter)
    dropRef.current?.addEventListener('dragover', handleDragOver)
    dropRef.current?.addEventListener('dragleave', handleDragLeave)
    dropRef.current?.addEventListener('drop', handleDrop)
    return () => {
      dropRef.current?.removeEventListener('dragenter', handleDragEnter)
      dropRef.current?.removeEventListener('dragover', handleDragOver)
      dropRef.current?.removeEventListener('dragleave', handleDragLeave)
      dropRef.current?.removeEventListener('drop', handleDrop)
    }
  }, [])
  return (
    <div className='mt-6'>
      <input
        ref={fileUploader}
        style={{ display: 'none' }}
        type="file"
        id="fileUploader"
        accept='.csv'
        onChange={fileChangeHandle}
      />
      <div ref={dropRef}>
        {!file && (
          <div className={cn('system-sm-regular flex h-20 items-center rounded-xl border border-dashed border-components-dropzone-border bg-components-dropzone-bg', dragging && 'border border-components-dropzone-border-accent bg-components-dropzone-bg-accent')}>
            <div className='flex w-full items-center justify-center space-x-2'>
              <CSVIcon className="shrink-0" />
              <div className='text-text-tertiary'>
                {t('appAnnotation.batchModal.csvUploadTitle')}
                <span className='cursor-pointer text-text-accent' onClick={selectHandle}>{t('appAnnotation.batchModal.browse')}</span>
              </div>
            </div>
            {dragging && <div ref={dragRef} className='absolute left-0 top-0 h-full w-full' />}
          </div>
        )}
        {file && (
          <div className={cn('group flex h-20 items-center rounded-xl border border-components-panel-border bg-components-panel-bg px-6 text-sm font-normal', 'hover:border-components-panel-bg-blur hover:bg-components-panel-bg-blur')}>
            <CSVIcon className="shrink-0" />
            <div className='ml-2 flex w-0 grow'>
              <span className='max-w-[calc(100%_-_30px)] overflow-hidden text-ellipsis whitespace-nowrap text-text-primary'>{file.name.replace(/.csv$/, '')}</span>
              <span className='shrink-0 text-text-tertiary'>.csv</span>
            </div>
            <div className='hidden items-center group-hover:flex'>
              <Button variant='secondary' onClick={selectHandle}>{t('datasetCreation.stepOne.uploader.change')}</Button>
              <div className='mx-2 h-4 w-px bg-divider-regular' />
              <div className='cursor-pointer p-2' onClick={removeFile}>
                <RiDeleteBinLine className='h-4 w-4 text-text-tertiary' />
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  )
}
export default React.memo(CSVUploader)
app/components/app/annotation/batch-add-annotation-modal/index.tsx
New file
@@ -0,0 +1,124 @@
'use client'
import type { FC } from 'react'
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiCloseLine } from '@remixicon/react'
import CSVUploader from './csv-uploader'
import CSVDownloader from './csv-downloader'
import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal'
import Toast from '@/app/components/base/toast'
import { annotationBatchImport, checkAnnotationBatchImportProgress } from '@/service/annotation'
import { useProviderContext } from '@/context/provider-context'
import AnnotationFull from '@/app/components/billing/annotation-full'
import { noop } from 'lodash-es'
export enum ProcessStatus {
  WAITING = 'waiting',
  PROCESSING = 'processing',
  COMPLETED = 'completed',
  ERROR = 'error',
}
export type IBatchModalProps = {
  appId: string
  isShow: boolean
  onCancel: () => void
  onAdded: () => void
}
const BatchModal: FC<IBatchModalProps> = ({
  appId,
  isShow,
  onCancel,
  onAdded,
}) => {
  const { t } = useTranslation()
  const { plan, enableBilling } = useProviderContext()
  const isAnnotationFull = (enableBilling && plan.usage.annotatedResponse >= plan.total.annotatedResponse)
  const [currentCSV, setCurrentCSV] = useState<File>()
  const handleFile = (file?: File) => setCurrentCSV(file)
  useEffect(() => {
    if (!isShow)
      setCurrentCSV(undefined)
  }, [isShow])
  const [importStatus, setImportStatus] = useState<ProcessStatus | string>()
  const notify = Toast.notify
  const checkProcess = async (jobID: string) => {
    try {
      const res = await checkAnnotationBatchImportProgress({ jobID, appId })
      setImportStatus(res.job_status)
      if (res.job_status === ProcessStatus.WAITING || res.job_status === ProcessStatus.PROCESSING)
        setTimeout(() => checkProcess(res.job_id), 2500)
      if (res.job_status === ProcessStatus.ERROR)
        notify({ type: 'error', message: `${t('appAnnotation.batchModal.runError')}` })
      if (res.job_status === ProcessStatus.COMPLETED) {
        notify({ type: 'success', message: `${t('appAnnotation.batchModal.completed')}` })
        onAdded()
        onCancel()
      }
    }
    catch (e: any) {
      notify({ type: 'error', message: `${t('appAnnotation.batchModal.runError')}${'message' in e ? `: ${e.message}` : ''}` })
    }
  }
  const runBatch = async (csv: File) => {
    const formData = new FormData()
    formData.append('file', csv)
    try {
      const res = await annotationBatchImport({
        url: `/apps/${appId}/annotations/batch-import`,
        body: formData,
      })
      setImportStatus(res.job_status)
      checkProcess(res.job_id)
    }
    catch (e: any) {
      notify({ type: 'error', message: `${t('appAnnotation.batchModal.runError')}${'message' in e ? `: ${e.message}` : ''}` })
    }
  }
  const handleSend = () => {
    if (!currentCSV)
      return
    runBatch(currentCSV)
  }
  return (
    <Modal isShow={isShow} onClose={noop} className='!max-w-[520px] !rounded-xl px-8 py-6'>
      <div className='system-xl-medium relative pb-1 text-text-primary'>{t('appAnnotation.batchModal.title')}</div>
      <div className='absolute right-4 top-4 cursor-pointer p-2' onClick={onCancel}>
        <RiCloseLine className='h-4 w-4 text-text-tertiary' />
      </div>
      <CSVUploader
        file={currentCSV}
        updateFile={handleFile}
      />
      <CSVDownloader />
      {isAnnotationFull && (
        <div className='mt-4'>
          <AnnotationFull />
        </div>
      )}
      <div className='mt-[28px] flex justify-end pt-6'>
        <Button className='system-sm-medium mr-2 text-text-tertiary' onClick={onCancel}>
          {t('appAnnotation.batchModal.cancel')}
        </Button>
        <Button
          variant="primary"
          onClick={handleSend}
          disabled={isAnnotationFull || !currentCSV}
          loading={importStatus === ProcessStatus.PROCESSING || importStatus === ProcessStatus.WAITING}
        >
          {t('appAnnotation.batchModal.run')}
        </Button>
      </div>
    </Modal>
  )
}
export default React.memo(BatchModal)
app/components/app/annotation/edit-annotation-modal/edit-item/index.tsx
New file
@@ -0,0 +1,128 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiDeleteBinLine, RiEditFill, RiEditLine } from '@remixicon/react'
import { Robot, User } from '@/app/components/base/icons/src/public/avatar'
import Textarea from '@/app/components/base/textarea'
import Button from '@/app/components/base/button'
import cn from '@/utils/classnames'
export enum EditItemType {
  Query = 'query',
  Answer = 'answer',
}
type Props = {
  type: EditItemType
  content: string
  readonly?: boolean
  onSave: (content: string) => void
}
export const EditTitle: FC<{ className?: string; title: string }> = ({ className, title }) => (
  <div className={cn(className, 'system-xs-medium flex h-[18px] items-center text-text-tertiary')}>
    <RiEditFill className='mr-1 h-3.5 w-3.5' />
    <div>{title}</div>
    <div
      className='ml-2 h-[1px] grow'
      style={{
        background: 'linear-gradient(90deg, rgba(0, 0, 0, 0.05) -1.65%, rgba(0, 0, 0, 0.00) 100%)',
      }}
    ></div>
  </div>
)
const EditItem: FC<Props> = ({
  type,
  readonly,
  content,
  onSave,
}) => {
  const { t } = useTranslation()
  const [newContent, setNewContent] = useState('')
  const showNewContent = newContent && newContent !== content
  const avatar = type === EditItemType.Query ? <User className='h-6 w-6' /> : <Robot className='h-6 w-6' />
  const name = type === EditItemType.Query ? t('appAnnotation.editModal.queryName') : t('appAnnotation.editModal.answerName')
  const editTitle = type === EditItemType.Query ? t('appAnnotation.editModal.yourQuery') : t('appAnnotation.editModal.yourAnswer')
  const placeholder = type === EditItemType.Query ? t('appAnnotation.editModal.queryPlaceholder') : t('appAnnotation.editModal.answerPlaceholder')
  const [isEdit, setIsEdit] = useState(false)
  const handleSave = () => {
    onSave(newContent)
    setIsEdit(false)
  }
  const handleCancel = () => {
    setNewContent('')
    setIsEdit(false)
  }
  return (
    <div className='flex' onClick={e => e.stopPropagation()}>
      <div className='mr-3 shrink-0'>
        {avatar}
      </div>
      <div className='grow'>
        <div className='system-xs-semibold mb-1 text-text-primary'>{name}</div>
        <div className='system-sm-regular text-text-primary'>{content}</div>
        {!isEdit
          ? (
            <div>
              {showNewContent && (
                <div className='mt-3'>
                  <EditTitle title={editTitle} />
                  <div className='system-sm-regular mt-1 text-text-primary'>{newContent}</div>
                </div>
              )}
              <div className='mt-2 flex items-center'>
                {!readonly && (
                  <div
                    className='system-xs-medium flex cursor-pointer items-center space-x-1 text-text-accent'
                    onClick={() => {
                      setIsEdit(true)
                    }}
                  >
                    <RiEditLine className='mr-1 h-3.5 w-3.5' />
                    <div>{t('common.operation.edit')}</div>
                  </div>
                )}
                {showNewContent && (
                  <div className='system-xs-medium ml-2 flex items-center text-text-tertiary'>
                    <div className='mr-2'>·</div>
                    <div
                      className='flex cursor-pointer items-center space-x-1'
                      onClick={() => {
                        setNewContent(content)
                        onSave(content)
                      }}
                    >
                      <div className='h-3.5 w-3.5'>
                        <RiDeleteBinLine className='h-3.5 w-3.5' />
                      </div>
                      <div>{t('common.operation.delete')}</div>
                    </div>
                  </div>
                )}
              </div>
            </div>
          )
          : (
            <div className='mt-3'>
              <EditTitle title={editTitle} />
              <Textarea
                value={newContent}
                onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) => setNewContent(e.target.value)}
                placeholder={placeholder}
                autoFocus
              />
              <div className='mt-2 flex space-x-2'>
                <Button size='small' variant='primary' onClick={handleSave}>{t('common.operation.save')}</Button>
                <Button size='small' onClick={handleCancel}>{t('common.operation.cancel')}</Button>
              </div>
            </div>
          )}
      </div>
    </div>
  )
}
export default React.memo(EditItem)
app/components/app/annotation/edit-annotation-modal/index.tsx
New file
@@ -0,0 +1,146 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import EditItem, { EditItemType } from './edit-item'
import Drawer from '@/app/components/base/drawer-plus'
import { MessageCheckRemove } from '@/app/components/base/icons/src/vender/line/communication'
import Confirm from '@/app/components/base/confirm'
import { addAnnotation, editAnnotation } from '@/service/annotation'
import Toast from '@/app/components/base/toast'
import { useProviderContext } from '@/context/provider-context'
import AnnotationFull from '@/app/components/billing/annotation-full'
import useTimestamp from '@/hooks/use-timestamp'
type Props = {
  isShow: boolean
  onHide: () => void
  appId: string
  messageId?: string
  annotationId?: string
  query: string
  answer: string
  onEdited: (editedQuery: string, editedAnswer: string) => void
  onAdded: (annotationId: string, authorName: string, editedQuery: string, editedAnswer: string) => void
  createdAt?: number
  onRemove: () => void
  onlyEditResponse?: boolean
}
const EditAnnotationModal: FC<Props> = ({
  isShow,
  onHide,
  query,
  answer,
  onEdited,
  onAdded,
  appId,
  messageId,
  annotationId,
  createdAt,
  onRemove,
  onlyEditResponse,
}) => {
  const { t } = useTranslation()
  const { formatTime } = useTimestamp()
  const { plan, enableBilling } = useProviderContext()
  const isAdd = !annotationId
  const isAnnotationFull = (enableBilling && plan.usage.annotatedResponse >= plan.total.annotatedResponse)
  const handleSave = async (type: EditItemType, editedContent: string) => {
    let postQuery = query
    let postAnswer = answer
    if (type === EditItemType.Query)
      postQuery = editedContent
    else
      postAnswer = editedContent
    if (!isAdd) {
      await editAnnotation(appId, annotationId, {
        message_id: messageId,
        question: postQuery,
        answer: postAnswer,
      })
      onEdited(postQuery, postAnswer)
    }
    else {
      const res: any = await addAnnotation(appId, {
        question: postQuery,
        answer: postAnswer,
        message_id: messageId,
      })
      onAdded(res.id, res.account?.name, postQuery, postAnswer)
    }
    Toast.notify({
      message: t('common.api.actionSuccess') as string,
      type: 'success',
    })
  }
  const [showModal, setShowModal] = useState(false)
  return (
    <div>
      <Drawer
        isShow={isShow}
        onHide={onHide}
        maxWidthClassName='!max-w-[480px]'
        title={t('appAnnotation.editModal.title') as string}
        body={(
          <div>
            <div className='space-y-6 p-6 pb-4'>
              <EditItem
                type={EditItemType.Query}
                content={query}
                readonly={(isAdd && isAnnotationFull) || onlyEditResponse}
                onSave={editedContent => handleSave(EditItemType.Query, editedContent)}
              />
              <EditItem
                type={EditItemType.Answer}
                content={answer}
                readonly={isAdd && isAnnotationFull}
                onSave={editedContent => handleSave(EditItemType.Answer, editedContent)}
              />
              <Confirm
                isShow={showModal}
                onCancel={() => setShowModal(false)}
                onConfirm={() => {
                  onRemove()
                  setShowModal(false)
                  onHide()
                }}
                title={t('appDebug.feature.annotation.removeConfirm')}
              />
            </div>
          </div>
        )}
        foot={
          <div>
            {isAnnotationFull && (
              <div className='mb-4 mt-6 px-6'>
                <AnnotationFull />
              </div>
            )}
            {
              annotationId
                ? (
                  <div className='system-sm-medium flex h-16 items-center justify-between rounded-bl-xl rounded-br-xl border-t border-divider-subtle bg-background-section-burn px-4 text-text-tertiary'>
                    <div
                      className='flex cursor-pointer items-center space-x-2 pl-3'
                      onClick={() => setShowModal(true)}
                    >
                      <MessageCheckRemove />
                      <div>{t('appAnnotation.editModal.removeThisCache')}</div>
                    </div>
                    {createdAt && <div>{t('appAnnotation.editModal.createdAt')}&nbsp;{formatTime(createdAt, t('appLog.dateTimeFormat') as string)}</div>}
                  </div>
                )
                : undefined
            }
          </div>
        }
      />
    </div>
  )
}
export default React.memo(EditAnnotationModal)
app/components/app/annotation/empty-element.tsx
New file
@@ -0,0 +1,26 @@
'use client'
import type { FC, SVGProps } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
const ThreeDotsIcon = ({ className }: SVGProps<SVGElement>) => {
  return <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" className={className ?? ''}>
    <path d="M5 6.5V5M8.93934 7.56066L10 6.5M10.0103 11.5H11.5103" stroke="#374151" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
  </svg>
}
const EmptyElement: FC = () => {
  const { t } = useTranslation()
  return (
    <div className='flex h-full items-center justify-center'>
      <div className='box-border h-fit w-[560px] rounded-2xl bg-background-section-burn px-5 py-4'>
        <span className='system-md-semibold text-text-secondary'>{t('appAnnotation.noData.title')}<ThreeDotsIcon className='relative -left-1.5 -top-3 inline' /></span>
        <div className='system-sm-regular mt-2 text-text-tertiary'>
          {t('appAnnotation.noData.description')}
        </div>
      </div>
    </div>
  )
}
export default React.memo(EmptyElement)
app/components/app/annotation/filter.tsx
New file
@@ -0,0 +1,48 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import useSWR from 'swr'
import Input from '@/app/components/base/input'
import { fetchAnnotationsCount } from '@/service/log'
export type QueryParam = {
  keyword?: string
}
type IFilterProps = {
  appId: string
  queryParams: QueryParam
  setQueryParams: (v: QueryParam) => void
  children: React.JSX.Element
}
const Filter: FC<IFilterProps> = ({
  appId,
  queryParams,
  setQueryParams,
  children,
}) => {
  // TODO: change fetch list api
  const { data } = useSWR({ url: `/apps/${appId}/annotations/count` }, fetchAnnotationsCount)
  const { t } = useTranslation()
  if (!data)
    return null
  return (
    <div className='mb-2 flex flex-row flex-wrap items-center justify-between gap-2'>
      <Input
        wrapperClassName='w-[200px]'
        showLeftIcon
        showClearIcon
        value={queryParams.keyword}
        placeholder={t('common.operation.search')!}
        onChange={(e) => {
          setQueryParams({ ...queryParams, keyword: e.target.value })
        }}
        onClear={() => setQueryParams({ ...queryParams, keyword: '' })}
      />
      {children}
    </div>
  )
}
export default React.memo(Filter)
app/components/app/annotation/header-opts/index.tsx
New file
@@ -0,0 +1,175 @@
'use client'
import type { FC } from 'react'
import React, { Fragment, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import {
  RiAddLine,
  RiMoreFill,
} from '@remixicon/react'
import { useContext } from 'use-context-selector'
import {
  useCSVDownloader,
} from 'react-papaparse'
import { Menu, MenuButton, MenuItems, Transition } from '@headlessui/react'
import Button from '../../../base/button'
import AddAnnotationModal from '../add-annotation-modal'
import type { AnnotationItemBasic } from '../type'
import BatchAddModal from '../batch-add-annotation-modal'
import cn from '@/utils/classnames'
import CustomPopover from '@/app/components/base/popover'
import { FileDownload02, FilePlus02 } from '@/app/components/base/icons/src/vender/line/files'
import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows'
import I18n from '@/context/i18n'
import { fetchExportAnnotationList } from '@/service/annotation'
import { LanguagesSupported } from '@/i18n/language'
const CSV_HEADER_QA_EN = ['Question', 'Answer']
const CSV_HEADER_QA_CN = ['问题', '答案']
type Props = {
  appId: string
  onAdd: (payload: AnnotationItemBasic) => void
  onAdded: () => void
  controlUpdateList: number
}
const HeaderOptions: FC<Props> = ({
  appId,
  onAdd,
  onAdded,
  controlUpdateList,
}) => {
  const { t } = useTranslation()
  const { locale } = useContext(I18n)
  const { CSVDownloader, Type } = useCSVDownloader()
  const [list, setList] = useState<AnnotationItemBasic[]>([])
  const annotationUnavailable = list.length === 0
  const listTransformer = (list: AnnotationItemBasic[]) => list.map(
    (item: AnnotationItemBasic) => {
      const dataString = `{"messages": [{"role": "system", "content": ""}, {"role": "user", "content": ${JSON.stringify(item.question)}}, {"role": "assistant", "content": ${JSON.stringify(item.answer)}}]}`
      return dataString
    },
  )
  const JSONLOutput = () => {
    const a = document.createElement('a')
    const content = listTransformer(list).join('\n')
    const file = new Blob([content], { type: 'application/jsonl' })
    a.href = URL.createObjectURL(file)
    a.download = `annotations-${locale}.jsonl`
    a.click()
  }
  const fetchList = async () => {
    const { data }: any = await fetchExportAnnotationList(appId)
    setList(data as AnnotationItemBasic[])
  }
  useEffect(() => {
    fetchList()
  }, [])
  useEffect(() => {
    if (controlUpdateList)
      fetchList()
  }, [controlUpdateList])
  const [showBulkImportModal, setShowBulkImportModal] = useState(false)
  const Operations = () => {
    return (
      <div className="w-full py-1">
        <button className='mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50' onClick={() => {
          setShowBulkImportModal(true)
        }}>
          <FilePlus02 className='h-4 w-4 text-text-tertiary' />
          <span className='system-sm-regular grow text-left text-text-secondary'>{t('appAnnotation.table.header.bulkImport')}</span>
        </button>
        <Menu as="div" className="relative h-full w-full">
          <MenuButton className='mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50'>
            <FileDownload02 className='h-4 w-4 text-text-tertiary' />
            <span className='system-sm-regular grow text-left text-text-secondary'>{t('appAnnotation.table.header.bulkExport')}</span>
            <ChevronRight className='h-[14px] w-[14px] shrink-0 text-text-tertiary' />
          </MenuButton>
          <Transition
            as={Fragment}
            enter="transition ease-out duration-100"
            enterFrom="transform opacity-0 scale-95"
            enterTo="transform opacity-100 scale-100"
            leave="transition ease-in duration-75"
            leaveFrom="transform opacity-100 scale-100"
            leaveTo="transform opacity-0 scale-95"
          >
            <MenuItems
              className={cn(
                'absolute left-1 top-[1px] z-10 min-w-[100px] origin-top-right -translate-x-full rounded-xl border-[0.5px] border-components-panel-on-panel-item-bg bg-components-panel-bg py-1 shadow-xs',
              )}
            >
              <CSVDownloader
                type={Type.Link}
                filename={`annotations-${locale}`}
                bom={true}
                data={[
                  locale !== LanguagesSupported[1] ? CSV_HEADER_QA_EN : CSV_HEADER_QA_CN,
                  ...list.map(item => [item.question, item.answer]),
                ]}
              >
                <button disabled={annotationUnavailable} className='mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50'>
                  <span className='system-sm-regular grow text-left text-text-secondary'>CSV</span>
                </button>
              </CSVDownloader>
              <button disabled={annotationUnavailable} className={cn('mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 hover:bg-components-panel-on-panel-item-bg-hover disabled:opacity-50', '!border-0')} onClick={JSONLOutput}>
                <span className='system-sm-regular grow text-left text-text-secondary'>JSONL</span>
              </button>
            </MenuItems>
          </Transition>
        </Menu>
      </div>
    )
  }
  const [showAddModal, setShowAddModal] = React.useState(false)
  return (
    <div className='flex space-x-2'>
      <Button variant='primary' onClick={() => setShowAddModal(true)}>
        <RiAddLine className='mr-0.5 h-4 w-4' />
        <div>{t('appAnnotation.table.header.addAnnotation')}</div>
      </Button>
      <CustomPopover
        htmlContent={<Operations />}
        position="br"
        trigger="click"
        btnElement={
          <Button variant='secondary' className='w-8 p-0'>
            <RiMoreFill className='h-4 w-4' />
          </Button>
        }
        btnClassName='p-0 border-0'
        className={'!z-20 h-fit !w-[155px]'}
        popupClassName='!w-full !overflow-visible'
        manualClose
      />
      {showAddModal && (
        <AddAnnotationModal
          isShow={showAddModal}
          onHide={() => setShowAddModal(false)}
          onAdd={onAdd}
        />
      )}
      {
        showBulkImportModal && (
          <BatchAddModal
            appId={appId}
            isShow={showBulkImportModal}
            onCancel={() => setShowBulkImportModal(false)}
            onAdded={onAdded}
          />
        )
      }
    </div>
  )
}
export default React.memo(HeaderOptions)
app/components/app/annotation/index.tsx
New file
@@ -0,0 +1,287 @@
'use client'
import type { FC } from 'react'
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useDebounce } from 'ahooks'
import { RiEqualizer2Line } from '@remixicon/react'
import Toast from '../../base/toast'
import Filter from './filter'
import type { QueryParam } from './filter'
import List from './list'
import EmptyElement from './empty-element'
import HeaderOpts from './header-opts'
import { AnnotationEnableStatus, type AnnotationItem, type AnnotationItemBasic, JobStatus } from './type'
import ViewAnnotationModal from './view-annotation-modal'
import { MessageFast } from '@/app/components/base/icons/src/vender/solid/communication'
import ActionButton from '@/app/components/base/action-button'
import Pagination from '@/app/components/base/pagination'
import Switch from '@/app/components/base/switch'
import { addAnnotation, delAnnotation, fetchAnnotationConfig as doFetchAnnotationConfig, editAnnotation, fetchAnnotationList, queryAnnotationJobStatus, updateAnnotationScore, updateAnnotationStatus } from '@/service/annotation'
import Loading from '@/app/components/base/loading'
import { APP_PAGE_LIMIT } from '@/config'
import ConfigParamModal from '@/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal'
import type { AnnotationReplyConfig } from '@/models/debug'
import { sleep } from '@/utils'
import { useProviderContext } from '@/context/provider-context'
import AnnotationFullModal from '@/app/components/billing/annotation-full/modal'
import type { App } from '@/types/app'
import cn from '@/utils/classnames'
type Props = {
  appDetail: App
}
const Annotation: FC<Props> = ({
  appDetail,
}) => {
  const { t } = useTranslation()
  const [isShowEdit, setIsShowEdit] = React.useState(false)
  const [annotationConfig, setAnnotationConfig] = useState<AnnotationReplyConfig | null>(null)
  const [isChatApp, setIsChatApp] = useState(false)
  const fetchAnnotationConfig = async () => {
    const res = await doFetchAnnotationConfig(appDetail.id)
    setAnnotationConfig(res as AnnotationReplyConfig)
    return (res as AnnotationReplyConfig).id
  }
  useEffect(() => {
    const isChatApp = appDetail.mode !== 'completion'
    setIsChatApp(isChatApp)
    if (isChatApp)
      fetchAnnotationConfig()
  }, [])
  const [controlRefreshSwitch, setControlRefreshSwitch] = useState(Date.now())
  const { plan, enableBilling } = useProviderContext()
  const isAnnotationFull = (enableBilling && plan.usage.annotatedResponse >= plan.total.annotatedResponse)
  const [isShowAnnotationFullModal, setIsShowAnnotationFullModal] = useState(false)
  const ensureJobCompleted = async (jobId: string, status: AnnotationEnableStatus) => {
    let isCompleted = false
    while (!isCompleted) {
      const res: any = await queryAnnotationJobStatus(appDetail.id, status, jobId)
      isCompleted = res.job_status === JobStatus.completed
      if (isCompleted)
        break
      await sleep(2000)
    }
  }
  const [queryParams, setQueryParams] = useState<QueryParam>({})
  const [currPage, setCurrPage] = React.useState<number>(0)
  const debouncedQueryParams = useDebounce(queryParams, { wait: 500 })
  const [limit, setLimit] = React.useState<number>(APP_PAGE_LIMIT)
  const query = {
    page: currPage + 1,
    limit,
    keyword: debouncedQueryParams.keyword || '',
  }
  const [controlUpdateList, setControlUpdateList] = useState(Date.now())
  const [list, setList] = useState<AnnotationItem[]>([])
  const [total, setTotal] = useState(10)
  const [isLoading, setIsLoading] = useState(false)
  const fetchList = async (page = 1) => {
    setIsLoading(true)
    try {
      const { data, total }: any = await fetchAnnotationList(appDetail.id, {
        ...query,
        page,
      })
      setList(data as AnnotationItem[])
      setTotal(total)
    }
    catch {
    }
    setIsLoading(false)
  }
  useEffect(() => {
    fetchList(currPage + 1)
  }, [currPage])
  useEffect(() => {
    fetchList(1)
    setControlUpdateList(Date.now())
  }, [queryParams])
  const handleAdd = async (payload: AnnotationItemBasic) => {
    await addAnnotation(appDetail.id, {
      ...payload,
    })
    Toast.notify({
      message: t('common.api.actionSuccess'),
      type: 'success',
    })
    fetchList()
    setControlUpdateList(Date.now())
  }
  const handleRemove = async (id: string) => {
    await delAnnotation(appDetail.id, id)
    Toast.notify({
      message: t('common.api.actionSuccess'),
      type: 'success',
    })
    fetchList()
    setControlUpdateList(Date.now())
  }
  const [currItem, setCurrItem] = useState<AnnotationItem | null>(list[0])
  const [isShowViewModal, setIsShowViewModal] = useState(false)
  useEffect(() => {
    if (!isShowEdit)
      setControlRefreshSwitch(Date.now())
  }, [isShowEdit])
  const handleView = (item: AnnotationItem) => {
    setCurrItem(item)
    setIsShowViewModal(true)
  }
  const handleSave = async (question: string, answer: string) => {
    await editAnnotation(appDetail.id, (currItem as AnnotationItem).id, {
      question,
      answer,
    })
    Toast.notify({
      message: t('common.api.actionSuccess'),
      type: 'success',
    })
    fetchList()
    setControlUpdateList(Date.now())
  }
  return (
    <div className='flex h-full flex-col'>
      <p className='system-sm-regular text-text-tertiary'>{t('appLog.description')}</p>
      <div className='flex flex-1 flex-col py-4'>
        <Filter appId={appDetail.id} queryParams={queryParams} setQueryParams={setQueryParams}>
          <div className='flex items-center space-x-2'>
            {isChatApp && (
              <>
                <div className={cn(!annotationConfig?.enabled && 'pr-2', 'flex h-7 items-center space-x-1 rounded-lg border border-components-panel-border bg-components-panel-bg-blur pl-2')}>
                  <MessageFast className='h-4 w-4 text-util-colors-indigo-indigo-600' />
                  <div className='system-sm-medium text-text-primary'>{t('appAnnotation.name')}</div>
                  <Switch
                    key={controlRefreshSwitch}
                    defaultValue={annotationConfig?.enabled}
                    size='md'
                    onChange={async (value) => {
                      if (value) {
                        if (isAnnotationFull) {
                          setIsShowAnnotationFullModal(true)
                          setControlRefreshSwitch(Date.now())
                          return
                        }
                        setIsShowEdit(true)
                      }
                      else {
                        const { job_id: jobId }: any = await updateAnnotationStatus(appDetail.id, AnnotationEnableStatus.disable, annotationConfig?.embedding_model, annotationConfig?.score_threshold)
                        await ensureJobCompleted(jobId, AnnotationEnableStatus.disable)
                        await fetchAnnotationConfig()
                        Toast.notify({
                          message: t('common.api.actionSuccess'),
                          type: 'success',
                        })
                      }
                    }}
                  ></Switch>
                  {annotationConfig?.enabled && (
                    <div className='flex items-center pl-1.5'>
                      <div className='mr-1 h-3.5 w-[1px] shrink-0 bg-divider-subtle'></div>
                      <ActionButton onClick={() => setIsShowEdit(true)}>
                        <RiEqualizer2Line className='h-4 w-4 text-text-tertiary' />
                      </ActionButton>
                    </div>
                  )}
                </div>
                <div className='mx-3 h-3.5 w-[1px] shrink-0 bg-divider-regular'></div>
              </>
            )}
            <HeaderOpts
              appId={appDetail.id}
              controlUpdateList={controlUpdateList}
              onAdd={handleAdd}
              onAdded={() => {
                fetchList()
              }}
            />
          </div>
        </Filter>
        {isLoading
          ? <Loading type='app' />
          : total > 0
            ? <List
              list={list}
              onRemove={handleRemove}
              onView={handleView}
            />
            : <div className='flex h-full grow items-center justify-center'><EmptyElement /></div>
        }
        {/* Show Pagination only if the total is more than the limit */}
        {(total && total > APP_PAGE_LIMIT)
          ? <Pagination
            current={currPage}
            onChange={setCurrPage}
            total={total}
            limit={limit}
            onLimitChange={setLimit}
          />
          : null}
        {isShowViewModal && (
          <ViewAnnotationModal
            appId={appDetail.id}
            isShow={isShowViewModal}
            onHide={() => setIsShowViewModal(false)}
            onRemove={async () => {
              await handleRemove((currItem as AnnotationItem)?.id)
            }}
            item={currItem as AnnotationItem}
            onSave={handleSave}
          />
        )}
        {isShowEdit && (
          <ConfigParamModal
            appId={appDetail.id}
            isShow
            isInit={!annotationConfig?.enabled}
            onHide={() => {
              setIsShowEdit(false)
            }}
            onSave={async (embeddingModel, score) => {
              if (
                embeddingModel.embedding_model_name !== annotationConfig?.embedding_model?.embedding_model_name
                || embeddingModel.embedding_provider_name !== annotationConfig?.embedding_model?.embedding_provider_name
              ) {
                const { job_id: jobId }: any = await updateAnnotationStatus(appDetail.id, AnnotationEnableStatus.enable, embeddingModel, score)
                await ensureJobCompleted(jobId, AnnotationEnableStatus.enable)
              }
              const annotationId = await fetchAnnotationConfig()
              if (score !== annotationConfig?.score_threshold)
                await updateAnnotationScore(appDetail.id, annotationId, score)
              await fetchAnnotationConfig()
              Toast.notify({
                message: t('common.api.actionSuccess'),
                type: 'success',
              })
              setIsShowEdit(false)
            }}
            annotationConfig={annotationConfig!}
          />
        )}
        {
          isShowAnnotationFullModal && (
            <AnnotationFullModal
              show={isShowAnnotationFullModal}
              onHide={() => setIsShowAnnotationFullModal(false)}
            />
          )
        }
      </div>
    </div>
  )
}
export default React.memo(Annotation)
app/components/app/annotation/list.tsx
New file
@@ -0,0 +1,91 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { RiDeleteBinLine, RiEditLine } from '@remixicon/react'
import type { AnnotationItem } from './type'
import RemoveAnnotationConfirmModal from './remove-annotation-confirm-modal'
import ActionButton from '@/app/components/base/action-button'
import useTimestamp from '@/hooks/use-timestamp'
import cn from '@/utils/classnames'
type Props = {
  list: AnnotationItem[]
  onRemove: (id: string) => void
  onView: (item: AnnotationItem) => void
}
const List: FC<Props> = ({
  list,
  onView,
  onRemove,
}) => {
  const { t } = useTranslation()
  const { formatTime } = useTimestamp()
  const [currId, setCurrId] = React.useState<string | null>(null)
  const [showConfirmDelete, setShowConfirmDelete] = React.useState(false)
  return (
    <div className='overflow-x-auto'>
      <table className={cn('mt-2 w-full min-w-[440px] border-collapse border-0')}>
        <thead className='system-xs-medium-uppercase text-text-tertiary'>
          <tr>
            <td className='w-5 whitespace-nowrap rounded-l-lg bg-background-section-burn pl-2 pr-1'>{t('appAnnotation.table.header.question')}</td>
            <td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t('appAnnotation.table.header.answer')}</td>
            <td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t('appAnnotation.table.header.createdAt')}</td>
            <td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t('appAnnotation.table.header.hits')}</td>
            <td className='w-[96px] whitespace-nowrap rounded-r-lg bg-background-section-burn py-1.5 pl-3'>{t('appAnnotation.table.header.actions')}</td>
          </tr>
        </thead>
        <tbody className="system-sm-regular text-text-secondary">
          {list.map(item => (
            <tr
              key={item.id}
              className='cursor-pointer border-b border-divider-subtle hover:bg-background-default-hover'
              onClick={
                () => {
                  onView(item)
                }
              }
            >
              <td
                className='max-w-[250px] overflow-hidden text-ellipsis whitespace-nowrap p-3 pr-2'
                title={item.question}
              >{item.question}</td>
              <td
                className='max-w-[250px] overflow-hidden text-ellipsis whitespace-nowrap p-3 pr-2'
                title={item.answer}
              >{item.answer}</td>
              <td className='p-3 pr-2'>{formatTime(item.created_at, t('appLog.dateTimeFormat') as string)}</td>
              <td className='p-3 pr-2'>{item.hit_count}</td>
              <td className='w-[96px] p-3 pr-2' onClick={e => e.stopPropagation()}>
                {/* Actions */}
                <div className='flex space-x-1 text-text-tertiary'>
                  <ActionButton onClick={() => onView(item)}>
                    <RiEditLine className='h-4 w-4' />
                  </ActionButton>
                  <ActionButton
                    onClick={() => {
                      setCurrId(item.id)
                      setShowConfirmDelete(true)
                    }}
                  >
                    <RiDeleteBinLine className='h-4 w-4' />
                  </ActionButton>
                </div>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
      <RemoveAnnotationConfirmModal
        isShow={showConfirmDelete}
        onHide={() => setShowConfirmDelete(false)}
        onRemove={() => {
          onRemove(currId as string)
          setShowConfirmDelete(false)
        }}
      />
    </div>
  )
}
export default React.memo(List)
app/components/app/annotation/remove-annotation-confirm-modal/index.tsx
New file
@@ -0,0 +1,29 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import Confirm from '@/app/components/base/confirm'
type Props = {
  isShow: boolean
  onHide: () => void
  onRemove: () => void
}
const RemoveAnnotationConfirmModal: FC<Props> = ({
  isShow,
  onHide,
  onRemove,
}) => {
  const { t } = useTranslation()
  return (
    <Confirm
      isShow={isShow}
      onCancel={onHide}
      onConfirm={onRemove}
      title={t('appDebug.feature.annotation.removeConfirm')}
    />
  )
}
export default React.memo(RemoveAnnotationConfirmModal)
app/components/app/annotation/type.ts
New file
@@ -0,0 +1,39 @@
export type AnnotationItemBasic = {
  message_id?: string
  question: string
  answer: string
}
export type AnnotationItem = {
  id: string
  question: string
  answer: string
  created_at: number
  hit_count: number
}
export type HitHistoryItem = {
  id: string
  question: string
  match: string
  response: string
  source: string
  score: number
  created_at: number
}
export type EmbeddingModelConfig = {
  embedding_provider_name: string
  embedding_model_name: string
}
export enum AnnotationEnableStatus {
  enable = 'enable',
  disable = 'disable',
}
export enum JobStatus {
  waiting = 'waiting',
  processing = 'processing',
  completed = 'completed',
}
app/components/app/annotation/view-annotation-modal/hit-history-no-data.tsx
New file
@@ -0,0 +1,19 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { ClockFastForward } from '@/app/components/base/icons/src/vender/line/time'
const HitHistoryNoData: FC = () => {
  const { t } = useTranslation()
  return (
    <div className='mx-auto mt-20 w-[480px] space-y-2 rounded-2xl bg-background-section-burn p-5'>
      <div className='inline-block rounded-lg border border-divider-subtle p-3'>
        <ClockFastForward className='h-5 w-5 text-text-tertiary' />
      </div>
      <div className='system-sm-regular text-text-tertiary'>{t('appAnnotation.viewModal.noHitHistory')}</div>
    </div>
  )
}
export default React.memo(HitHistoryNoData)
app/components/app/annotation/view-annotation-modal/index.tsx
New file
@@ -0,0 +1,215 @@
'use client'
import type { FC } from 'react'
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import EditItem, { EditItemType } from '../edit-annotation-modal/edit-item'
import type { AnnotationItem, HitHistoryItem } from '../type'
import HitHistoryNoData from './hit-history-no-data'
import Badge from '@/app/components/base/badge'
import Drawer from '@/app/components/base/drawer-plus'
import Pagination from '@/app/components/base/pagination'
import { MessageCheckRemove } from '@/app/components/base/icons/src/vender/line/communication'
import Confirm from '@/app/components/base/confirm'
import TabSlider from '@/app/components/base/tab-slider-plain'
import { fetchHitHistoryList } from '@/service/annotation'
import { APP_PAGE_LIMIT } from '@/config'
import useTimestamp from '@/hooks/use-timestamp'
import cn from '@/utils/classnames'
type Props = {
  appId: string
  isShow: boolean
  onHide: () => void
  item: AnnotationItem
  onSave: (editedQuery: string, editedAnswer: string) => void
  onRemove: () => void
}
enum TabType {
  annotation = 'annotation',
  hitHistory = 'hitHistory',
}
const ViewAnnotationModal: FC<Props> = ({
  appId,
  isShow,
  onHide,
  item,
  onSave,
  onRemove,
}) => {
  const { id, question, answer, created_at: createdAt } = item
  const [newQuestion, setNewQuery] = useState(question)
  const [newAnswer, setNewAnswer] = useState(answer)
  const { t } = useTranslation()
  const { formatTime } = useTimestamp()
  const [currPage, setCurrPage] = React.useState<number>(0)
  const [total, setTotal] = useState(0)
  const [hitHistoryList, setHitHistoryList] = useState<HitHistoryItem[]>([])
  const fetchHitHistory = async (page = 1) => {
    try {
      const { data, total }: any = await fetchHitHistoryList(appId, id, {
        page,
        limit: 10,
      })
      setHitHistoryList(data as HitHistoryItem[])
      setTotal(total)
    }
    catch {
    }
  }
  useEffect(() => {
    fetchHitHistory(currPage + 1)
  }, [currPage])
  const tabs = [
    { value: TabType.annotation, text: t('appAnnotation.viewModal.annotatedResponse') },
    {
      value: TabType.hitHistory,
      text: (
        hitHistoryList.length > 0
          ? (
            <div className='flex items-center space-x-1'>
              <div>{t('appAnnotation.viewModal.hitHistory')}</div>
              <Badge
                text={`${total} ${t(`appAnnotation.viewModal.hit${hitHistoryList.length > 1 ? 's' : ''}`)}`}
              />
            </div>
          )
          : t('appAnnotation.viewModal.hitHistory')
      ),
    },
  ]
  const [activeTab, setActiveTab] = useState(TabType.annotation)
  const handleSave = (type: EditItemType, editedContent: string) => {
    if (type === EditItemType.Query) {
      setNewQuery(editedContent)
      onSave(editedContent, newAnswer)
    }
    else {
      setNewAnswer(editedContent)
      onSave(newQuestion, editedContent)
    }
  }
  const [showModal, setShowModal] = useState(false)
  const annotationTab = (
    <>
      <EditItem
        type={EditItemType.Query}
        content={question}
        onSave={editedContent => handleSave(EditItemType.Query, editedContent)}
      />
      <EditItem
        type={EditItemType.Answer}
        content={answer}
        onSave={editedContent => handleSave(EditItemType.Answer, editedContent)}
      />
    </>
  )
  const hitHistoryTab = total === 0
    ? (<HitHistoryNoData />)
    : (
      <div>
        <table className={cn('w-full min-w-[440px] border-collapse border-0')} >
          <thead className="system-xs-medium-uppercase text-text-tertiary">
            <tr>
              <td className='w-5 whitespace-nowrap rounded-l-lg bg-background-section-burn pl-2 pr-1'>{t('appAnnotation.hitHistoryTable.query')}</td>
              <td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t('appAnnotation.hitHistoryTable.match')}</td>
              <td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t('appAnnotation.hitHistoryTable.response')}</td>
              <td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t('appAnnotation.hitHistoryTable.source')}</td>
              <td className='whitespace-nowrap bg-background-section-burn py-1.5 pl-3'>{t('appAnnotation.hitHistoryTable.score')}</td>
              <td className='w-[160px] whitespace-nowrap rounded-r-lg bg-background-section-burn py-1.5 pl-3'>{t('appAnnotation.hitHistoryTable.time')}</td>
            </tr>
          </thead>
          <tbody className="system-sm-regular text-text-secondary">
            {hitHistoryList.map(item => (
              <tr
                key={item.id}
                className={'cursor-pointer border-b border-divider-subtle hover:bg-background-default-hover'}
              >
                <td
                  className='max-w-[250px] overflow-hidden text-ellipsis whitespace-nowrap p-3 pr-2'
                  title={item.question}
                >{item.question}</td>
                <td
                  className='max-w-[250px] overflow-hidden text-ellipsis whitespace-nowrap p-3 pr-2'
                  title={item.match}
                >{item.match}</td>
                <td
                  className='max-w-[250px] overflow-hidden text-ellipsis whitespace-nowrap p-3 pr-2'
                  title={item.response}
                >{item.response}</td>
                <td className='p-3 pr-2'>{item.source}</td>
                <td className='p-3 pr-2'>{item.score ? item.score.toFixed(2) : '-'}</td>
                <td className='p-3 pr-2'>{formatTime(item.created_at, t('appLog.dateTimeFormat') as string)}</td>
              </tr>
            ))}
          </tbody>
        </table>
        {(total && total > APP_PAGE_LIMIT)
          ? <Pagination
            className='px-0'
            current={currPage}
            onChange={setCurrPage}
            total={total}
          />
          : null}
      </div>
    )
  return (
    <div>
      <Drawer
        isShow={isShow}
        onHide={onHide}
        maxWidthClassName='!max-w-[800px]'
        title={
          <TabSlider
            className='relative top-[9px] shrink-0'
            value={activeTab}
            onChange={v => setActiveTab(v as TabType)}
            options={tabs}
            noBorderBottom
            itemClassName='!pb-3.5'
          />
        }
        body={(
          <div>
            <div className='space-y-6 p-6 pb-4'>
              {activeTab === TabType.annotation ? annotationTab : hitHistoryTab}
            </div>
            <Confirm
              isShow={showModal}
              onCancel={() => setShowModal(false)}
              onConfirm={async () => {
                await onRemove()
                setShowModal(false)
                onHide()
              }}
              title={t('appDebug.feature.annotation.removeConfirm')}
            />
          </div>
        )}
        foot={id
          ? (
            <div className='system-sm-medium flex h-16 items-center justify-between rounded-bl-xl rounded-br-xl border-t border-divider-subtle bg-background-section-burn px-4 text-text-tertiary'>
              <div
                className='flex cursor-pointer items-center space-x-2 pl-3'
                onClick={() => setShowModal(true)}
              >
                <MessageCheckRemove />
                <div>{t('appAnnotation.editModal.removeThisCache')}</div>
              </div>
              <div>{t('appAnnotation.editModal.createdAt')}&nbsp;{formatTime(createdAt, t('appLog.dateTimeFormat') as string)}</div>
            </div>
          )
          : undefined}
      />
    </div>
  )
}
export default React.memo(ViewAnnotationModal)
app/components/app/app-publisher/features-wrapper.tsx
New file
@@ -0,0 +1,86 @@
import React, { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import produce from 'immer'
import type { AppPublisherProps } from '@/app/components/app/app-publisher'
import Confirm from '@/app/components/base/confirm'
import AppPublisher from '@/app/components/app/app-publisher'
import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks'
import type { ModelAndParameter } from '@/app/components/app/configuration/debug/types'
import type { FileUpload } from '@/app/components/base/features/types'
import { Resolution } from '@/types/app'
import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants'
import { SupportUploadFileTypes } from '@/app/components/workflow/types'
type Props = Omit<AppPublisherProps, 'onPublish'> & {
  onPublish?: (modelAndParameter?: ModelAndParameter, features?: any) => Promise<any> | any
  publishedConfig?: any
  resetAppConfig?: () => void
}
const FeaturesWrappedAppPublisher = (props: Props) => {
  const { t } = useTranslation()
  const features = useFeatures(s => s.features)
  const featuresStore = useFeaturesStore()
  const [restoreConfirmOpen, setRestoreConfirmOpen] = useState(false)
  const handleConfirm = useCallback(() => {
    props.resetAppConfig?.()
    const {
      features,
      setFeatures,
    } = featuresStore!.getState()
    const newFeatures = produce(features, (draft) => {
      draft.moreLikeThis = props.publishedConfig.modelConfig.more_like_this || { enabled: false }
      draft.opening = {
        enabled: !!props.publishedConfig.modelConfig.opening_statement,
        opening_statement: props.publishedConfig.modelConfig.opening_statement || '',
        suggested_questions: props.publishedConfig.modelConfig.suggested_questions || [],
      }
      draft.moderation = props.publishedConfig.modelConfig.sensitive_word_avoidance || { enabled: false }
      draft.speech2text = props.publishedConfig.modelConfig.speech_to_text || { enabled: false }
      draft.text2speech = props.publishedConfig.modelConfig.text_to_speech || { enabled: false }
      draft.suggested = props.publishedConfig.modelConfig.suggested_questions_after_answer || { enabled: false }
      draft.citation = props.publishedConfig.modelConfig.retriever_resource || { enabled: false }
      draft.annotationReply = props.publishedConfig.modelConfig.annotation_reply || { enabled: false }
      draft.file = {
        image: {
          detail: props.publishedConfig.modelConfig.file_upload?.image?.detail || Resolution.high,
          enabled: !!props.publishedConfig.modelConfig.file_upload?.image?.enabled,
          number_limits: props.publishedConfig.modelConfig.file_upload?.image?.number_limits || 3,
          transfer_methods: props.publishedConfig.modelConfig.file_upload?.image?.transfer_methods || ['local_file', 'remote_url'],
        },
        enabled: !!(props.publishedConfig.modelConfig.file_upload?.enabled || props.publishedConfig.modelConfig.file_upload?.image?.enabled),
        allowed_file_types: props.publishedConfig.modelConfig.file_upload?.allowed_file_types || [SupportUploadFileTypes.image],
        allowed_file_extensions: props.publishedConfig.modelConfig.file_upload?.allowed_file_extensions || FILE_EXTS[SupportUploadFileTypes.image].map(ext => `.${ext}`),
        allowed_file_upload_methods: props.publishedConfig.modelConfig.file_upload?.allowed_file_upload_methods || props.publishedConfig.modelConfig.file_upload?.image?.transfer_methods || ['local_file', 'remote_url'],
        number_limits: props.publishedConfig.modelConfig.file_upload?.number_limits || props.publishedConfig.modelConfig.file_upload?.image?.number_limits || 3,
      } as FileUpload
    })
    setFeatures(newFeatures)
    setRestoreConfirmOpen(false)
  }, [featuresStore, props])
  const handlePublish = useCallback((modelAndParameter?: ModelAndParameter) => {
    return props.onPublish?.(modelAndParameter, features)
  }, [features, props])
  return (
    <>
      <AppPublisher {...{
        ...props,
        onPublish: handlePublish,
        onRestore: () => setRestoreConfirmOpen(true),
      }}/>
      {restoreConfirmOpen && (
        <Confirm
          title={t('appDebug.resetConfig.title')}
          content={t('appDebug.resetConfig.message')}
          isShow={restoreConfirmOpen}
          onConfirm={handleConfirm}
          onCancel={() => setRestoreConfirmOpen(false)}
        />
      )}
    </>
  )
}
export default FeaturesWrappedAppPublisher
app/components/app/app-publisher/index.tsx
New file
@@ -0,0 +1,304 @@
import {
  memo,
  useCallback,
  useState,
} from 'react'
import { useTranslation } from 'react-i18next'
import dayjs from 'dayjs'
import {
  RiArrowDownSLine,
  RiPlanetLine,
  RiPlayCircleLine,
  RiPlayList2Line,
  RiTerminalBoxLine,
} from '@remixicon/react'
import { useKeyPress } from 'ahooks'
import Toast from '../../base/toast'
import type { ModelAndParameter } from '../configuration/debug/types'
import { getKeyboardKeyCodeBySystem } from '../../workflow/utils'
import SuggestedAction from './suggested-action'
import PublishWithMultipleModel from './publish-with-multiple-model'
import Button from '@/app/components/base/button'
import {
  PortalToFollowElem,
  PortalToFollowElemContent,
  PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import { WEB_PREFIX } from '@/config'
import { fetchInstalledAppList } from '@/service/explore'
import EmbeddedModal from '@/app/components/app/overview/embedded'
import { useStore as useAppStore } from '@/app/components/app/store'
import { useGetLanguage } from '@/context/i18n'
import { CodeBrowser } from '@/app/components/base/icons/src/vender/line/development'
import WorkflowToolConfigureButton from '@/app/components/tools/workflow-tool/configure-button'
import type { InputVar } from '@/app/components/workflow/types'
import { appDefaultIconBackground } from '@/config'
import type { PublishWorkflowParams } from '@/types/workflow'
export type AppPublisherProps = {
  disabled?: boolean
  publishDisabled?: boolean
  publishedAt?: number
  /** only needed in workflow / chatflow mode */
  draftUpdatedAt?: number
  debugWithMultipleModel?: boolean
  multipleModelConfigs?: ModelAndParameter[]
  /** modelAndParameter is passed when debugWithMultipleModel is true */
  onPublish?: (params?: any) => Promise<any> | any
  onRestore?: () => Promise<any> | any
  onToggle?: (state: boolean) => void
  crossAxisOffset?: number
  toolPublished?: boolean
  inputs?: InputVar[]
  onRefreshData?: () => void
}
const PUBLISH_SHORTCUT = ['⌘', '⇧', 'P']
const AppPublisher = ({
  disabled = false,
  publishDisabled = false,
  publishedAt,
  draftUpdatedAt,
  debugWithMultipleModel = false,
  multipleModelConfigs = [],
  onPublish,
  onRestore,
  onToggle,
  crossAxisOffset = 0,
  toolPublished,
  inputs,
  onRefreshData,
}: AppPublisherProps) => {
  const { t } = useTranslation()
  const [published, setPublished] = useState(false)
  const [open, setOpen] = useState(false)
  const appDetail = useAppStore(state => state.appDetail)
  const { app_base_url: appBaseURL = '', access_token: accessToken = '' } = appDetail?.site ?? {}
  const appMode = (appDetail?.mode !== 'completion' && appDetail?.mode !== 'workflow') ? 'chat' : appDetail.mode
  const appURL = `${appBaseURL}/${appMode}/${accessToken}`
  const isChatApp = ['chat', 'agent-chat', 'completion'].includes(appDetail?.mode || '')
  const language = useGetLanguage()
  const formatTimeFromNow = useCallback((time: number) => {
    return dayjs(time).locale(language === 'zh_Hans' ? 'zh-cn' : language.replace('_', '-')).fromNow()
  }, [language])
  const handlePublish = useCallback(async (params?: ModelAndParameter | PublishWorkflowParams) => {
    try {
      await onPublish?.(params)
      setPublished(true)
    }
    catch {
      setPublished(false)
    }
  }, [onPublish])
  const handleRestore = useCallback(async () => {
    try {
      await onRestore?.()
      setOpen(false)
    }
    catch {}
  }, [onRestore])
  const handleTrigger = useCallback(() => {
    const state = !open
    if (disabled) {
      setOpen(false)
      return
    }
    onToggle?.(state)
    setOpen(state)
    if (state)
      setPublished(false)
  }, [disabled, onToggle, open])
  const handleOpenInExplore = useCallback(async () => {
    try {
      const { installed_apps }: any = await fetchInstalledAppList(appDetail?.id) || {}
      if (installed_apps?.length > 0)
        window.open(`${WEB_PREFIX}/explore/installed/${installed_apps[0].id}`, '_blank')
      else
        throw new Error('No app found in Explore')
    }
    catch (e: any) {
      Toast.notify({ type: 'error', message: `${e.message || e}` })
    }
  }, [appDetail?.id])
  const [embeddingModalOpen, setEmbeddingModalOpen] = useState(false)
  useKeyPress(`${getKeyboardKeyCodeBySystem('ctrl')}.shift.p`, (e) => {
    e.preventDefault()
    if (publishDisabled || published)
      return
    handlePublish()
  },
  { exactMatch: true, useCapture: true })
  return (
    <>
      <PortalToFollowElem
        open={open}
        onOpenChange={setOpen}
        placement='bottom-end'
        offset={{
          mainAxis: 4,
          crossAxis: crossAxisOffset,
        }}
      >
        <PortalToFollowElemTrigger onClick={handleTrigger}>
          <Button
            variant='primary'
            className='p-2'
            disabled={disabled}
          >
            {t('workflow.common.publish')}
            <RiArrowDownSLine className='h-4 w-4 text-components-button-primary-text' />
          </Button>
        </PortalToFollowElemTrigger>
        <PortalToFollowElemContent className='z-[11]'>
          <div className='w-[320px] rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl shadow-shadow-shadow-5'>
            <div className='p-4 pt-3'>
              <div className='system-xs-medium-uppercase flex h-6 items-center text-text-tertiary'>
                {publishedAt ? t('workflow.common.latestPublished') : t('workflow.common.currentDraftUnpublished')}
              </div>
              {publishedAt
                ? (
                  <div className='flex items-center justify-between'>
                    <div className='system-sm-medium flex items-center text-text-secondary'>
                      {t('workflow.common.publishedAt')} {formatTimeFromNow(publishedAt)}
                    </div>
                    {isChatApp && <Button
                      variant='secondary-accent'
                      size='small'
                      onClick={handleRestore}
                      disabled={published}
                    >
                      {t('workflow.common.restore')}
                    </Button>}
                  </div>
                )
                : (
                  <div className='system-sm-medium flex items-center text-text-secondary'>
                    {t('workflow.common.autoSaved')} · {Boolean(draftUpdatedAt) && formatTimeFromNow(draftUpdatedAt!)}
                  </div>
                )}
              {debugWithMultipleModel
                ? (
                  <PublishWithMultipleModel
                    multipleModelConfigs={multipleModelConfigs}
                    onSelect={item => handlePublish(item)}
                  // textGenerationModelList={textGenerationModelList}
                  />
                )
                : (
                  <Button
                    variant='primary'
                    className='mt-3 w-full'
                    onClick={() => handlePublish()}
                    disabled={publishDisabled || published}
                  >
                    {
                      published
                        ? t('workflow.common.published')
                        : (
                          <div className='flex gap-1'>
                            <span>{t('workflow.common.publishUpdate')}</span>
                            <div className='flex gap-0.5'>
                              {PUBLISH_SHORTCUT.map(key => (
                                <span key={key} className='system-kbd h-4 w-4 rounded-[4px] bg-components-kbd-bg-white text-text-primary-on-surface'>
                                  {key}
                                </span>
                              ))}
                            </div>
                          </div>
                        )
                    }
                  </Button>
                )
              }
            </div>
            <div className='border-t-[0.5px] border-t-divider-regular p-4 pt-3'>
              <SuggestedAction
                disabled={!publishedAt}
                link={appURL}
                icon={<RiPlayCircleLine className='h-4 w-4' />}
              >
                {t('workflow.common.runApp')}
              </SuggestedAction>
              {appDetail?.mode === 'workflow' || appDetail?.mode === 'completion'
                ? (
                  <SuggestedAction
                    disabled={!publishedAt}
                    link={`${appURL}${appURL.includes('?') ? '&' : '?'}mode=batch`}
                    icon={<RiPlayList2Line className='h-4 w-4' />}
                  >
                    {t('workflow.common.batchRunApp')}
                  </SuggestedAction>
                )
                : (
                  <SuggestedAction
                    onClick={() => {
                      setEmbeddingModalOpen(true)
                      handleTrigger()
                    }}
                    disabled={!publishedAt}
                    icon={<CodeBrowser className='h-4 w-4' />}
                  >
                    {t('workflow.common.embedIntoSite')}
                  </SuggestedAction>
                )}
              <SuggestedAction
                onClick={() => {
                  publishedAt && handleOpenInExplore()
                }}
                disabled={!publishedAt}
                icon={<RiPlanetLine className='h-4 w-4' />}
              >
                {t('workflow.common.openInExplore')}
              </SuggestedAction>
              <SuggestedAction
                disabled={!publishedAt}
                link='./develop'
                icon={<RiTerminalBoxLine className='h-4 w-4' />}
              >
                {t('workflow.common.accessAPIReference')}
              </SuggestedAction>
              {appDetail?.mode === 'workflow' && (
                <WorkflowToolConfigureButton
                  disabled={!publishedAt}
                  published={!!toolPublished}
                  detailNeedUpdate={!!toolPublished && published}
                  workflowAppId={appDetail?.id}
                  icon={{
                    content: (appDetail.icon_type === 'image' ? '🤖' : appDetail?.icon) || '🤖',
                    background: (appDetail.icon_type === 'image' ? appDefaultIconBackground : appDetail?.icon_background) || appDefaultIconBackground,
                  }}
                  name={appDetail?.name}
                  description={appDetail?.description}
                  inputs={inputs}
                  handlePublish={handlePublish}
                  onRefreshData={onRefreshData}
                />
              )}
            </div>
          </div>
        </PortalToFollowElemContent>
        <EmbeddedModal
          siteInfo={appDetail?.site}
          isShow={embeddingModalOpen}
          onClose={() => setEmbeddingModalOpen(false)}
          appBaseUrl={appBaseURL}
          accessToken={accessToken}
        />
      </PortalToFollowElem >
    </>
  )
}
export default memo(AppPublisher)
app/components/app/app-publisher/publish-with-multiple-model.tsx
New file
@@ -0,0 +1,108 @@
import type { FC } from 'react'
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiArrowDownSLine } from '@remixicon/react'
import type { ModelAndParameter } from '../configuration/debug/types'
import ModelIcon from '../../header/account-setting/model-provider-page/model-icon'
import Button from '@/app/components/base/button'
import {
  PortalToFollowElem,
  PortalToFollowElemContent,
  PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import { useProviderContext } from '@/context/provider-context'
import type { Model, ModelItem } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks'
type PublishWithMultipleModelProps = {
  multipleModelConfigs: ModelAndParameter[]
  // textGenerationModelList?: Model[]
  onSelect: (v: ModelAndParameter) => void
}
const PublishWithMultipleModel: FC<PublishWithMultipleModelProps> = ({
  multipleModelConfigs,
  // textGenerationModelList = [],
  onSelect,
}) => {
  const { t } = useTranslation()
  const language = useLanguage()
  const { textGenerationModelList } = useProviderContext()
  const [open, setOpen] = useState(false)
  const validModelConfigs: (ModelAndParameter & { modelItem: ModelItem; providerItem: Model })[] = []
  multipleModelConfigs.forEach((item) => {
    const provider = textGenerationModelList.find(model => model.provider === item.provider)
    if (provider) {
      const model = provider.models.find(model => model.model === item.model)
      if (model) {
        validModelConfigs.push({
          id: item.id,
          model: item.model,
          provider: item.provider,
          modelItem: model,
          providerItem: provider,
          parameters: item.parameters,
        })
      }
    }
  })
  const handleToggle = () => {
    if (validModelConfigs.length)
      setOpen(v => !v)
  }
  const handleSelect = (item: ModelAndParameter) => {
    onSelect(item)
    setOpen(false)
  }
  return (
    <PortalToFollowElem
      open={open}
      onOpenChange={setOpen}
      placement='bottom-end'
    >
      <PortalToFollowElemTrigger className='w-full' onClick={handleToggle}>
        <Button
          variant='primary'
          disabled={!validModelConfigs.length}
          className='mt-3 w-full'
        >
          {t('appDebug.operation.applyConfig')}
          <RiArrowDownSLine className='ml-0.5 h-3 w-3' />
        </Button>
      </PortalToFollowElemTrigger>
      <PortalToFollowElemContent className='z-50 mt-1 w-[288px]'>
        <div className='rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg p-1 shadow-lg'>
          <div className='flex h-[22px] items-center px-3 text-xs font-medium text-text-tertiary'>
            {t('appDebug.publishAs')}
          </div>
          {
            validModelConfigs.map((item, index) => (
              <div
                key={item.id}
                className='flex h-8 cursor-pointer items-center rounded-lg px-3 text-sm text-text-tertiary hover:bg-state-base-hover'
                onClick={() => handleSelect(item)}
              >
                <span className='min-w-[18px] italic'>#{index + 1}</span>
                <ModelIcon modelName={item.model} provider={item.providerItem} className='ml-2' />
                <div
                  className='ml-1 truncate text-text-secondary'
                  title={item.modelItem.label[language]}
                >
                  {item.modelItem.label[language]}
                </div>
              </div>
            ))
          }
        </div>
      </PortalToFollowElemContent>
    </PortalToFollowElem>
  )
}
export default PublishWithMultipleModel
app/components/app/app-publisher/suggested-action.tsx
New file
@@ -0,0 +1,29 @@
import type { HTMLProps, PropsWithChildren } from 'react'
import { RiArrowRightUpLine } from '@remixicon/react'
import classNames from '@/utils/classnames'
export type SuggestedActionProps = PropsWithChildren<HTMLProps<HTMLAnchorElement> & {
  icon?: React.ReactNode
  link?: string
  disabled?: boolean
}>
const SuggestedAction = ({ icon, link, disabled, children, className, ...props }: SuggestedActionProps) => (
  <a
    href={disabled ? undefined : link}
    target='_blank'
    rel='noreferrer'
    className={classNames(
      'flex justify-start items-center gap-2 py-2 px-2.5 bg-background-section-burn rounded-lg transition-colors [&:not(:first-child)]:mt-1',
      disabled ? 'shadow-xs opacity-30 cursor-not-allowed' : 'text-text-secondary hover:bg-state-accent-hover hover:text-text-accent cursor-pointer',
      className,
    )}
    {...props}
  >
    <div className='relative h-4 w-4'>{icon}</div>
    <div className='system-sm-medium shrink grow basis-0'>{children}</div>
    <RiArrowRightUpLine className='h-3.5 w-3.5' />
  </a>
)
export default SuggestedAction
app/components/app/app-publisher/version-info-modal.tsx
New file
@@ -0,0 +1,112 @@
import React, { type FC, useCallback, useState } from 'react'
import Modal from '@/app/components/base/modal'
import type { VersionHistory } from '@/types/workflow'
import { useTranslation } from 'react-i18next'
import { RiCloseLine } from '@remixicon/react'
import Input from '../../base/input'
import Textarea from '../../base/textarea'
import Button from '../../base/button'
import Toast from '@/app/components/base/toast'
type VersionInfoModalProps = {
  isOpen: boolean
  versionInfo?: VersionHistory
  onClose: () => void
  onPublish: (params: { title: string; releaseNotes: string; id?: string }) => void
}
const TITLE_MAX_LENGTH = 15
const RELEASE_NOTES_MAX_LENGTH = 100
const VersionInfoModal: FC<VersionInfoModalProps> = ({
  isOpen,
  versionInfo,
  onClose,
  onPublish,
}) => {
  const { t } = useTranslation()
  const [title, setTitle] = useState(versionInfo?.marked_name || '')
  const [releaseNotes, setReleaseNotes] = useState(versionInfo?.marked_comment || '')
  const [titleError, setTitleError] = useState(false)
  const [releaseNotesError, setReleaseNotesError] = useState(false)
  const handlePublish = () => {
    if (title.length > TITLE_MAX_LENGTH) {
      setTitleError(true)
      Toast.notify({
        type: 'error',
        message: t('workflow.versionHistory.editField.titleLengthLimit', { limit: TITLE_MAX_LENGTH }),
      })
      return
    }
    else {
      titleError && setTitleError(false)
    }
    if (releaseNotes.length > RELEASE_NOTES_MAX_LENGTH) {
      setReleaseNotesError(true)
      Toast.notify({
        type: 'error',
        message: t('workflow.versionHistory.editField.releaseNotesLengthLimit', { limit: RELEASE_NOTES_MAX_LENGTH }),
      })
      return
    }
    else {
      releaseNotesError && setReleaseNotesError(false)
    }
    onPublish({ title, releaseNotes, id: versionInfo?.id })
    onClose()
  }
  const handleTitleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    setTitle(e.target.value)
  }, [])
  const handleDescriptionChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
    setReleaseNotes(e.target.value)
  }, [])
  return <Modal className='p-0' isShow={isOpen} onClose={onClose}>
    <div className='relative w-full p-6 pb-4 pr-14'>
      <div className='title-2xl-semi-bold text-text-primary first-letter:capitalize'>
        {versionInfo?.marked_name ? t('workflow.versionHistory.editVersionInfo') : t('workflow.versionHistory.nameThisVersion')}
      </div>
      <div className='absolute right-5 top-5 flex h-8 w-8 cursor-pointer items-center justify-center p-1.5' onClick={onClose}>
        <RiCloseLine className='h-[18px] w-[18px] text-text-tertiary' />
      </div>
    </div>
    <div className='flex flex-col gap-y-4 px-6 py-3'>
      <div className='flex flex-col gap-y-1'>
        <div className='system-sm-semibold flex h-6 items-center text-text-secondary'>
          {t('workflow.versionHistory.editField.title')}
        </div>
        <Input
          value={title}
          placeholder={`${t('workflow.versionHistory.nameThisVersion')}${t('workflow.panel.optional')}`}
          onChange={handleTitleChange}
          destructive={titleError}
        />
      </div>
      <div className='flex flex-col gap-y-1'>
        <div className='system-sm-semibold flex h-6 items-center text-text-secondary'>
          {t('workflow.versionHistory.editField.releaseNotes')}
        </div>
        <Textarea
          value={releaseNotes}
          placeholder={`${t('workflow.versionHistory.releaseNotesPlaceholder')}${t('workflow.panel.optional')}`}
          onChange={handleDescriptionChange}
          destructive={releaseNotesError}
        />
      </div>
    </div>
    <div className='flex justify-end p-6 pt-5'>
      <div className='flex items-center gap-x-3'>
        <Button onClick={onClose}>{t('common.operation.cancel')}</Button>
        <Button variant='primary' onClick={handlePublish}>{t('workflow.common.publish')}</Button>
      </div>
    </div>
  </Modal>
}
export default VersionInfoModal
app/components/app/configuration/base/feature-panel/index.tsx
New file
@@ -0,0 +1,48 @@
'use client'
import type { FC, ReactNode } from 'react'
import React from 'react'
import cn from '@/utils/classnames'
export type IFeaturePanelProps = {
  className?: string
  headerIcon?: ReactNode
  title: ReactNode
  headerRight?: ReactNode
  hasHeaderBottomBorder?: boolean
  noBodySpacing?: boolean
  children?: ReactNode
}
const FeaturePanel: FC<IFeaturePanelProps> = ({
  className,
  headerIcon,
  title,
  headerRight,
  hasHeaderBottomBorder,
  noBodySpacing,
  children,
}) => {
  return (
    <div className={cn('rounded-xl border-l-[0.5px] border-t-[0.5px] border-effects-highlight bg-background-section-burn pb-3', noBodySpacing && 'pb-0', className)}>
      {/* Header */}
      <div className={cn('px-3 pt-2', hasHeaderBottomBorder && 'border-b border-divider-subtle')}>
        <div className='flex h-8 items-center justify-between'>
          <div className='flex shrink-0 items-center space-x-1'>
            {headerIcon && <div className='flex h-6 w-6 items-center justify-center'>{headerIcon}</div>}
            <div className='system-sm-semibold text-text-secondary'>{title}</div>
          </div>
          <div className='flex items-center gap-2'>
            {headerRight && <div>{headerRight}</div>}
          </div>
        </div>
      </div>
      {/* Body */}
      {children && (
        <div className={cn(!noBodySpacing && 'mt-1 px-3')}>
          {children}
        </div>
      )}
    </div>
  )
}
export default React.memo(FeaturePanel)
app/components/app/configuration/base/group-name/index.tsx
New file
@@ -0,0 +1,24 @@
'use client'
import type { FC } from 'react'
import React from 'react'
export type IGroupNameProps = {
  name: string
}
const GroupName: FC<IGroupNameProps> = ({
  name,
}) => {
  return (
    <div className='mb-1 flex items-center'>
      <div className='mr-3 text-xs font-semibold uppercase leading-[18px] text-text-tertiary'>{name}</div>
      <div className='h-[1px] grow'
        style={{
          background: 'linear-gradient(270deg, rgba(243, 244, 246, 0) 0%, #F3F4F6 100%)',
        }}
      ></div>
    </div>
  )
}
export default React.memo(GroupName)
app/components/app/configuration/base/icons/citation.tsx
app/components/app/configuration/base/icons/more-like-this-icon.tsx
New file
@@ -0,0 +1,14 @@
'use client'
import type { FC } from 'react'
import React from 'react'
const MoreLikeThisIcon: FC = () => {
  return (
    <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path fillRule="evenodd" clipRule="evenodd" d="M5.83914 0.666748H10.1609C10.6975 0.666741 11.1404 0.666734 11.5012 0.696212C11.8759 0.726829 12.2204 0.792538 12.544 0.957399C13.0457 1.21306 13.4537 1.62101 13.7093 2.12277C13.8742 2.44633 13.9399 2.7908 13.9705 3.16553C14 3.52633 14 3.96923 14 4.50587V7.41171C14 7.62908 14 7.73776 13.9652 7.80784C13.9303 7.87806 13.8939 7.91566 13.8249 7.95288C13.756 7.99003 13.6262 7.99438 13.3665 8.00307C12.8879 8.01909 12.4204 8.14633 11.997 8.36429C10.9478 7.82388 9.62021 7.82912 8.53296 8.73228C7.15064 9.88056 6.92784 11.8645 8.0466 13.2641C8.36602 13.6637 8.91519 14.1949 9.40533 14.6492C9.49781 14.7349 9.54405 14.7777 9.5632 14.8041C9.70784 15.003 9.5994 15.2795 9.35808 15.3271C9.32614 15.3334 9.26453 15.3334 9.14129 15.3334H5.83912C5.30248 15.3334 4.85958 15.3334 4.49878 15.304C4.12405 15.2733 3.77958 15.2076 3.45603 15.0428C2.95426 14.7871 2.54631 14.3792 2.29065 13.8774C2.12579 13.5538 2.06008 13.2094 2.02946 12.8346C1.99999 12.4738 1.99999 12.0309 2 11.4943V4.50587C1.99999 3.96924 1.99999 3.52632 2.02946 3.16553C2.06008 2.7908 2.12579 2.44633 2.29065 2.12277C2.54631 1.62101 2.95426 1.21306 3.45603 0.957399C3.77958 0.792538 4.12405 0.726829 4.49878 0.696212C4.85957 0.666734 5.3025 0.666741 5.83914 0.666748ZM4.66667 5.33342C4.29848 5.33342 4 5.63189 4 6.00008C4 6.36827 4.29848 6.66675 4.66667 6.66675H8.66667C9.03486 6.66675 9.33333 6.36827 9.33333 6.00008C9.33333 5.63189 9.03486 5.33342 8.66667 5.33342H4.66667ZM4 8.66675C4 8.29856 4.29848 8.00008 4.66667 8.00008H6C6.36819 8.00008 6.66667 8.29856 6.66667 8.66675C6.66667 9.03494 6.36819 9.33342 6 9.33342H4.66667C4.29848 9.33342 4 9.03494 4 8.66675ZM4.66667 2.66675C4.29848 2.66675 4 2.96523 4 3.33342C4 3.7016 4.29848 4.00008 4.66667 4.00008H10.6667C11.0349 4.00008 11.3333 3.7016 11.3333 3.33342C11.3333 2.96523 11.0349 2.66675 10.6667 2.66675H4.66667Z" fill="#DD2590" />
      <path d="M11.9977 10.0256C11.3313 9.26808 10.2199 9.06432 9.3849 9.75796C8.54988 10.4516 8.43232 11.6113 9.08807 12.4317C9.58479 13.0531 10.9986 14.3025 11.655 14.8719C11.7744 14.9754 11.8341 15.0272 11.9037 15.0477C11.9642 15.0654 12.0312 15.0654 12.0917 15.0477C12.1613 15.0272 12.221 14.9754 12.3404 14.8719C12.9968 14.3025 14.4106 13.0531 14.9074 12.4317C15.5631 11.6113 15.4599 10.4443 14.6105 9.75796C13.7612 9.07161 12.6642 9.26808 11.9977 10.0256Z" fill="#DD2590" />
    </svg>
  )
}
export default React.memo(MoreLikeThisIcon)
app/components/app/configuration/base/icons/remove-icon/index.tsx
New file
@@ -0,0 +1,31 @@
'use client'
import React, { useState } from 'react'
import cn from '@/utils/classnames'
type IRemoveIconProps = {
  className?: string
  isHoverStatus?: boolean
  onClick: () => void
}
const RemoveIcon = ({
  className,
  isHoverStatus,
  onClick,
}: IRemoveIconProps) => {
  const [isHovered, setIsHovered] = useState(false)
  const computedIsHovered = isHoverStatus || isHovered
  return (
    <div
      className={cn(className, computedIsHovered && 'bg-[#FEE4E2]', 'flex h-6 w-6 cursor-pointer items-center justify-center rounded-md hover:bg-[#FEE4E2]')}
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => setIsHovered(false)}
      onClick={onClick}
    >
      <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M10 6H14M6 8H18M16.6667 8L16.1991 15.0129C16.129 16.065 16.0939 16.5911 15.8667 16.99C15.6666 17.3412 15.3648 17.6235 15.0011 17.7998C14.588 18 14.0607 18 13.0062 18H10.9938C9.93927 18 9.41202 18 8.99889 17.7998C8.63517 17.6235 8.33339 17.3412 8.13332 16.99C7.90607 16.5911 7.871 16.065 7.80086 15.0129L7.33333 8M10.6667 11V14.3333M13.3333 11V14.3333" stroke={computedIsHovered ? '#D92D20' : '#667085'} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
      </svg>
    </div>
  )
}
export default React.memo(RemoveIcon)
app/components/app/configuration/base/icons/remove-icon/style.module.css
app/components/app/configuration/base/icons/suggested-questions-after-answer-icon.tsx
New file
@@ -0,0 +1,12 @@
'use client'
import type { FC } from 'react'
import React from 'react'
const SuggestedQuestionsAfterAnswerIcon: FC = () => {
  return (
    <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path fillRule="evenodd" clipRule="evenodd" d="M10.8275 1.33325H5.17245C4.63581 1.33324 4.19289 1.33324 3.8321 1.36272C3.45737 1.39333 3.1129 1.45904 2.78934 1.6239C2.28758 1.87956 1.87963 2.28751 1.62397 2.78928C1.45911 3.11284 1.3934 3.4573 1.36278 3.83204C1.3333 4.19283 1.33331 4.63574 1.33332 5.17239L1.33328 9.42497C1.333 9.95523 1.33278 10.349 1.42418 10.6901C1.67076 11.6103 2.38955 12.3291 3.3098 12.5757C3.51478 12.6306 3.73878 12.6525 3.99998 12.6611L3.99998 13.5806C3.99995 13.7374 3.99992 13.8973 4.01182 14.0283C4.0232 14.1536 4.05333 14.3901 4.21844 14.5969C4.40843 14.8349 4.69652 14.9734 5.00106 14.973C5.26572 14.9728 5.46921 14.8486 5.57416 14.7792C5.6839 14.7066 5.80872 14.6067 5.93117 14.5087L7.53992 13.2217C7.88564 12.9451 7.98829 12.8671 8.09494 12.8126C8.20192 12.7579 8.3158 12.718 8.43349 12.6938C8.55081 12.6697 8.67974 12.6666 9.12248 12.6666H10.8275C11.3642 12.6666 11.8071 12.6666 12.1679 12.6371C12.5426 12.6065 12.8871 12.5408 13.2106 12.3759C13.7124 12.1203 14.1203 11.7123 14.376 11.2106C14.5409 10.887 14.6066 10.5425 14.6372 10.1678C14.6667 9.80701 14.6667 9.36411 14.6667 8.82747V5.17237C14.6667 4.63573 14.6667 4.19283 14.6372 3.83204C14.6066 3.4573 14.5409 3.11284 14.376 2.78928C14.1203 2.28751 13.7124 1.87956 13.2106 1.6239C12.8871 1.45904 12.5426 1.39333 12.1679 1.36272C11.8071 1.33324 11.3642 1.33324 10.8275 1.33325ZM8.99504 4.99992C8.99504 4.44763 9.44275 3.99992 9.99504 3.99992C10.5473 3.99992 10.995 4.44763 10.995 4.99992C10.995 5.5522 10.5473 5.99992 9.99504 5.99992C9.44275 5.99992 8.99504 5.5522 8.99504 4.99992ZM4.92837 7.79996C5.222 7.57974 5.63816 7.63837 5.85961 7.93051C5.90071 7.98295 5.94593 8.03229 5.99199 8.08035C6.09019 8.18282 6.23775 8.32184 6.42882 8.4608C6.81353 8.74059 7.3454 8.99996 7.99504 8.99996C8.64469 8.99996 9.17655 8.74059 9.56126 8.4608C9.75233 8.32184 9.89989 8.18282 9.99809 8.08035C10.0441 8.0323 10.0894 7.98294 10.1305 7.93051C10.3519 7.63837 10.7681 7.57974 11.0617 7.79996C11.3563 8.02087 11.416 8.43874 11.195 8.73329C11.1967 8.73112 11.1928 8.7361 11.186 8.74466C11.1697 8.7651 11.1372 8.80597 11.1261 8.81916C11.087 8.86575 11.0317 8.92884 10.9607 9.00289C10.8194 9.15043 10.6128 9.34474 10.3455 9.53912C9.81353 9.92599 9.01206 10.3333 7.99504 10.3333C6.97802 10.3333 6.17655 9.92599 5.64459 9.53912C5.37733 9.34474 5.17072 9.15043 5.02934 9.00289C4.95837 8.92884 4.90305 8.86575 4.86395 8.81916C4.84438 8.79585 4.82881 8.77659 4.81731 8.76207C4.58702 8.46455 4.61798 8.03275 4.92837 7.79996ZM5.99504 3.99992C5.44275 3.99992 4.99504 4.44763 4.99504 4.99992C4.99504 5.5522 5.44275 5.99992 5.99504 5.99992C6.54732 5.99992 6.99504 5.5522 6.99504 4.99992C6.99504 4.44763 6.54732 3.99992 5.99504 3.99992Z" fill="#06AED4" />
    </svg>
  )
}
export default React.memo(SuggestedQuestionsAfterAnswerIcon)
app/components/app/configuration/base/operation-btn/index.tsx
New file
@@ -0,0 +1,44 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
  RiAddLine,
  RiEditLine,
} from '@remixicon/react'
import cn from '@/utils/classnames'
import { noop } from 'lodash-es'
export type IOperationBtnProps = {
  className?: string
  type: 'add' | 'edit'
  actionName?: string
  onClick?: () => void
}
const iconMap = {
  add: <RiAddLine className='h-3.5 w-3.5' />,
  edit: <RiEditLine className='h-3.5 w-3.5' />,
}
const OperationBtn: FC<IOperationBtnProps> = ({
  className,
  type,
  actionName,
  onClick = noop,
}) => {
  const { t } = useTranslation()
  return (
    <div
      className={cn('flex h-7 cursor-pointer select-none items-center space-x-1 rounded-md px-3 text-text-secondary hover:bg-state-base-hover', className)}
      onClick={onClick}>
      <div>
        {iconMap[type]}
      </div>
      <div className='text-xs font-medium'>
        {actionName || t(`common.operation.${type}`)}
      </div>
    </div>
  )
}
export default React.memo(OperationBtn)
app/components/app/configuration/base/var-highlight/index.tsx
New file
@@ -0,0 +1,37 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import s from './style.module.css'
export type IVarHighlightProps = {
  name: string
  className?: string
}
const VarHighlight: FC<IVarHighlightProps> = ({
  name,
  className = '',
}) => {
  return (
    <div
      key={name}
      className={`${s.item} ${className} mb-2 flex h-5 items-center justify-center rounded-md px-1 text-xs font-medium text-primary-600`}
    >
      <span className='opacity-60'>{'{{'}</span>
      <span>{name}</span>
      <span className='opacity-60'>{'}}'}</span>
    </div>
  )
}
export const varHighlightHTML = ({ name, className = '' }: IVarHighlightProps) => {
  const html = `<div class="${s.item} ${className} inline-flex mb-2 items-center justify-center px-1 rounded-md h-5 text-xs font-medium text-primary-600">
  <span class='opacity-60'>{{</span>
  <span>${name}</span>
  <span class='opacity-60'>}}</span>
</div>`
  return html
}
export default React.memo(VarHighlight)
app/components/app/configuration/base/var-highlight/style.module.css
New file
@@ -0,0 +1,3 @@
.item {
  background-color: rgba(21, 94, 239, 0.05);
}
app/components/app/configuration/base/warning-mask/cannot-query-dataset.tsx
New file
@@ -0,0 +1,31 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import WarningMask from '.'
import Button from '@/app/components/base/button'
export type IFormattingChangedProps = {
  onConfirm: () => void
}
const FormattingChanged: FC<IFormattingChangedProps> = ({
  onConfirm,
}) => {
  const { t } = useTranslation()
  return (
    <WarningMask
      title={t('appDebug.feature.dataSet.queryVariable.unableToQueryDataSet')}
      description={t('appDebug.feature.dataSet.queryVariable.unableToQueryDataSetTip')}
      footer={
        <div className='flex space-x-2'>
          <Button variant='primary' className='flex !w-[96px] justify-start' onClick={onConfirm}>
            <span className='text-[13px] font-medium'>{t('appDebug.feature.dataSet.queryVariable.ok')}</span>
          </Button>
        </div>
      }
    />
  )
}
export default React.memo(FormattingChanged)
app/components/app/configuration/base/warning-mask/formatting-changed.tsx
New file
@@ -0,0 +1,41 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import WarningMask from '.'
import Button from '@/app/components/base/button'
export type IFormattingChangedProps = {
  onConfirm: () => void
  onCancel: () => void
}
const icon = (
  <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M1.33337 6.66667C1.33337 6.66667 2.67003 4.84548 3.75593 3.75883C4.84183 2.67218 6.34244 2 8.00004 2C11.3137 2 14 4.68629 14 8C14 11.3137 11.3137 14 8.00004 14C5.26465 14 2.95678 12.1695 2.23455 9.66667M1.33337 6.66667V2.66667M1.33337 6.66667H5.33337" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
  </svg>
)
const FormattingChanged: FC<IFormattingChangedProps> = ({
  onConfirm,
  onCancel,
}) => {
  const { t } = useTranslation()
  return (
    <WarningMask
      title={t('appDebug.formattingChangedTitle')}
      description={t('appDebug.formattingChangedText')}
      footer={
        <div className='flex space-x-2'>
          <Button variant='primary' className='flex space-x-2' onClick={onConfirm}>
            {icon}
            <span>{t('common.operation.refresh')}</span>
          </Button>
          <Button onClick={onCancel}>{t('common.operation.cancel') as string}</Button>
        </div>
      }
    />
  )
}
export default React.memo(FormattingChanged)
app/components/app/configuration/base/warning-mask/has-not-set-api.tsx
New file
@@ -0,0 +1,38 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import WarningMask from '.'
import Button from '@/app/components/base/button'
export type IHasNotSetAPIProps = {
  isTrailFinished: boolean
  onSetting: () => void
}
const icon = (
  <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M14 6.00001L14 2.00001M14 2.00001H9.99999M14 2.00001L8 8M6.66667 2H5.2C4.0799 2 3.51984 2 3.09202 2.21799C2.71569 2.40973 2.40973 2.71569 2.21799 3.09202C2 3.51984 2 4.07989 2 5.2V10.8C2 11.9201 2 12.4802 2.21799 12.908C2.40973 13.2843 2.71569 13.5903 3.09202 13.782C3.51984 14 4.07989 14 5.2 14H10.8C11.9201 14 12.4802 14 12.908 13.782C13.2843 13.5903 13.5903 13.2843 13.782 12.908C14 12.4802 14 11.9201 14 10.8V9.33333" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
  </svg>
)
const HasNotSetAPI: FC<IHasNotSetAPIProps> = ({
  isTrailFinished,
  onSetting,
}) => {
  const { t } = useTranslation()
  return (
    <WarningMask
      title={isTrailFinished ? t('appDebug.notSetAPIKey.trailFinished') : t('appDebug.notSetAPIKey.title')}
      description={t('appDebug.notSetAPIKey.description')}
      footer={
        <Button variant='primary' className='flex space-x-2' onClick={onSetting}>
          <span>{t('appDebug.notSetAPIKey.settingBtn')}</span>
          {icon}
        </Button>}
    />
  )
}
export default React.memo(HasNotSetAPI)
app/components/app/configuration/base/warning-mask/index.tsx
New file
@@ -0,0 +1,43 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import s from './style.module.css'
export type IWarningMaskProps = {
  title: string
  description: string
  footer: React.ReactNode
}
const warningIcon = (
  <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M9.99996 13.3334V10.0001M9.99996 6.66675H10.0083M18.3333 10.0001C18.3333 14.6025 14.6023 18.3334 9.99996 18.3334C5.39759 18.3334 1.66663 14.6025 1.66663 10.0001C1.66663 5.39771 5.39759 1.66675 9.99996 1.66675C14.6023 1.66675 18.3333 5.39771 18.3333 10.0001Z" stroke="#F79009" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
  </svg>
)
const WarningMask: FC<IWarningMaskProps> = ({
  title,
  description,
  footer,
}) => {
  return (
    <div className={`${s.mask} absolute inset-0 z-10 pt-16`}
    >
      <div className='mx-auto px-10'>
        <div className={`${s.icon} flex h-11 w-11 items-center justify-center rounded-xl bg-white`}>{warningIcon}</div>
        <div className='mt-4 text-[24px] font-semibold leading-normal text-gray-800'>
          {title}
        </div>
        <div className='mt-3 text-base text-gray-500'>
          {description}
        </div>
        <div className='mt-6'>
          {footer}
        </div>
      </div>
    </div>
  )
}
export default React.memo(WarningMask)
app/components/app/configuration/base/warning-mask/style.module.css
New file
@@ -0,0 +1,8 @@
.mask {
  background-color: rgba(239, 244, 255, 0.9);
  backdrop-filter: blur(2px);
}
.icon {
  box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03);
}
app/components/app/configuration/config-prompt/advanced-prompt-input.tsx
New file
@@ -0,0 +1,275 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import copy from 'copy-to-clipboard'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { useBoolean } from 'ahooks'
import produce from 'immer'
import {
  RiDeleteBinLine,
  RiErrorWarningFill,
} from '@remixicon/react'
import s from './style.module.css'
import MessageTypeSelector from './message-type-selector'
import ConfirmAddVar from './confirm-add-var'
import PromptEditorHeightResizeWrap from './prompt-editor-height-resize-wrap'
import cn from '@/utils/classnames'
import type { PromptRole, PromptVariable } from '@/models/debug'
import {
  Clipboard,
  ClipboardCheck,
} from '@/app/components/base/icons/src/vender/line/files'
import Button from '@/app/components/base/button'
import Tooltip from '@/app/components/base/tooltip'
import PromptEditor from '@/app/components/base/prompt-editor'
import ConfigContext from '@/context/debug-configuration'
import { getNewVar, getVars } from '@/utils/var'
import { AppType } from '@/types/app'
import { useModalContext } from '@/context/modal-context'
import type { ExternalDataTool } from '@/models/common'
import { useToastContext } from '@/app/components/base/toast'
import { useEventEmitterContextContext } from '@/context/event-emitter'
import { ADD_EXTERNAL_DATA_TOOL } from '@/app/components/app/configuration/config-var'
import { INSERT_VARIABLE_VALUE_BLOCK_COMMAND } from '@/app/components/base/prompt-editor/plugins/variable-block'
type Props = {
  type: PromptRole
  isChatMode: boolean
  value: string
  onTypeChange: (value: PromptRole) => void
  onChange: (value: string) => void
  canDelete: boolean
  onDelete: () => void
  promptVariables: PromptVariable[]
  isContextMissing: boolean
  onHideContextMissingTip: () => void
  noResize?: boolean
}
const AdvancedPromptInput: FC<Props> = ({
  type,
  isChatMode,
  value,
  onChange,
  onTypeChange,
  canDelete,
  onDelete,
  promptVariables,
  isContextMissing,
  onHideContextMissingTip,
  noResize,
}) => {
  const { t } = useTranslation()
  const { eventEmitter } = useEventEmitterContextContext()
  const {
    mode,
    hasSetBlockStatus,
    modelConfig,
    setModelConfig,
    conversationHistoriesRole,
    showHistoryModal,
    dataSets,
    showSelectDataSet,
    externalDataToolsConfig,
  } = useContext(ConfigContext)
  const { notify } = useToastContext()
  const { setShowExternalDataToolModal } = useModalContext()
  const handleOpenExternalDataToolModal = () => {
    setShowExternalDataToolModal({
      payload: {},
      onSaveCallback: (newExternalDataTool: ExternalDataTool) => {
        eventEmitter?.emit({
          type: ADD_EXTERNAL_DATA_TOOL,
          payload: newExternalDataTool,
        } as any)
        eventEmitter?.emit({
          type: INSERT_VARIABLE_VALUE_BLOCK_COMMAND,
          payload: newExternalDataTool.variable,
        } as any)
      },
      onValidateBeforeSaveCallback: (newExternalDataTool: ExternalDataTool) => {
        for (let i = 0; i < promptVariables.length; i++) {
          if (promptVariables[i].key === newExternalDataTool.variable) {
            notify({ type: 'error', message: t('appDebug.varKeyError.keyAlreadyExists', { key: promptVariables[i].key }) })
            return false
          }
        }
        return true
      },
    })
  }
  const isChatApp = mode !== AppType.completion
  const [isCopied, setIsCopied] = React.useState(false)
  const promptVariablesObj = (() => {
    const obj: Record<string, boolean> = {}
    promptVariables.forEach((item) => {
      obj[item.key] = true
    })
    return obj
  })()
  const [newPromptVariables, setNewPromptVariables] = React.useState<PromptVariable[]>(promptVariables)
  const [isShowConfirmAddVar, { setTrue: showConfirmAddVar, setFalse: hideConfirmAddVar }] = useBoolean(false)
  const handlePromptChange = (newValue: string) => {
    if (value === newValue)
      return
    onChange(newValue)
  }
  const handleBlur = () => {
    const keys = getVars(value)
    const newPromptVariables = keys.filter(key => !(key in promptVariablesObj) && !externalDataToolsConfig.find(item => item.variable === key)).map(key => getNewVar(key, ''))
    if (newPromptVariables.length > 0) {
      setNewPromptVariables(newPromptVariables)
      showConfirmAddVar()
    }
  }
  const handleAutoAdd = (isAdd: boolean) => {
    return () => {
      if (isAdd) {
        const newModelConfig = produce(modelConfig, (draft) => {
          draft.configs.prompt_variables = [...draft.configs.prompt_variables, ...newPromptVariables]
        })
        setModelConfig(newModelConfig)
      }
      hideConfirmAddVar()
    }
  }
  const minHeight = 102
  const [editorHeight, setEditorHeight] = React.useState(isChatMode ? 200 : 508)
  const contextMissing = (
    <div
      className='flex h-11 items-center justify-between rounded-tl-xl rounded-tr-xl pb-1 pl-4 pr-3 pt-2'
      style={{
        background: 'linear-gradient(180deg, #FEF0C7 0%, rgba(254, 240, 199, 0) 100%)',
      }}
    >
      <div className='flex items-center pr-2' >
        <RiErrorWarningFill className='mr-1 h-4 w-4 text-[#F79009]' />
        <div className='text-[13px] font-medium leading-[18px] text-[#DC6803]'>{t('appDebug.promptMode.contextMissing')}</div>
      </div>
      <Button
        size='small'
        variant='secondary-accent'
        onClick={onHideContextMissingTip}
      >{t('common.operation.ok')}</Button>
    </div>
  )
  return (
    <div className={`rounded-xl bg-gradient-to-r from-components-input-border-active-prompt-1 to-components-input-border-active-prompt-2 p-0.5 shadow-xs ${!isContextMissing ? '' : s.warningBorder}`}>
      <div className='rounded-xl bg-background-default'>
        {isContextMissing
          ? contextMissing
          : (
            <div className={cn(s.boxHeader, 'flex h-11 items-center justify-between rounded-tl-xl rounded-tr-xl bg-background-default pb-1 pl-4 pr-3 pt-2 hover:shadow-xs')}>
              {isChatMode
                ? (
                  <MessageTypeSelector value={type} onChange={onTypeChange} />
                )
                : (
                  <div className='flex items-center space-x-1'>
                    <div className='text-sm font-semibold uppercase text-indigo-800'>{t('appDebug.pageTitle.line1')}
                    </div>
                    <Tooltip
                      popupContent={
                        <div className='w-[180px]'>
                          {t('appDebug.promptTip')}
                        </div>
                      }
                    />
                  </div>)}
              <div className={cn(s.optionWrap, 'items-center space-x-1')}>
                {canDelete && (
                  <RiDeleteBinLine onClick={onDelete} className='h-6 w-6 cursor-pointer p-1 text-text-tertiary' />
                )}
                {!isCopied
                  ? (
                    <Clipboard className='h-6 w-6 cursor-pointer p-1 text-text-tertiary' onClick={() => {
                      copy(value)
                      setIsCopied(true)
                    }} />
                  )
                  : (
                    <ClipboardCheck className='h-6 w-6 p-1 text-text-tertiary' />
                  )}
              </div>
            </div>
          )}
        <PromptEditorHeightResizeWrap
          className='min-h-[102px] overflow-y-auto px-4 text-sm text-text-secondary'
          height={editorHeight}
          minHeight={minHeight}
          onHeightChange={setEditorHeight}
          footer={(
            <div className='flex pb-2 pl-4'>
              <div className="h-[18px] rounded-md bg-divider-regular px-1 text-xs leading-[18px] text-text-tertiary">{value.length}</div>
            </div>
          )}
          hideResize={noResize}
        >
          <PromptEditor
            className='min-h-[84px]'
            value={value}
            contextBlock={{
              show: true,
              selectable: !hasSetBlockStatus.context,
              datasets: dataSets.map(item => ({
                id: item.id,
                name: item.name,
                type: item.data_source_type,
              })),
              onAddContext: showSelectDataSet,
            }}
            variableBlock={{
              show: true,
              variables: modelConfig.configs.prompt_variables.filter(item => item.type !== 'api').map(item => ({
                name: item.name,
                value: item.key,
              })),
            }}
            externalToolBlock={{
              externalTools: modelConfig.configs.prompt_variables.filter(item => item.type === 'api').map(item => ({
                name: item.name,
                variableName: item.key,
                icon: item.icon,
                icon_background: item.icon_background,
              })),
              onAddExternalTool: handleOpenExternalDataToolModal,
            }}
            historyBlock={{
              show: !isChatMode && isChatApp,
              selectable: !hasSetBlockStatus.history,
              history: {
                user: conversationHistoriesRole?.user_prefix,
                assistant: conversationHistoriesRole?.assistant_prefix,
              },
              onEditRole: showHistoryModal,
            }}
            queryBlock={{
              show: !isChatMode && isChatApp,
              selectable: !hasSetBlockStatus.query,
            }}
            onChange={handlePromptChange}
            onBlur={handleBlur}
          />
        </PromptEditorHeightResizeWrap>
      </div>
      {isShowConfirmAddVar && (
        <ConfirmAddVar
          varNameArr={newPromptVariables.map(v => v.name)}
          onConfirm={handleAutoAdd(true)}
          onCancel={handleAutoAdd(false)}
          onHide={hideConfirmAddVar}
        />
      )}
    </div>
  )
}
export default React.memo(AdvancedPromptInput)
app/components/app/configuration/config-prompt/confirm-add-var/index.tsx
New file
@@ -0,0 +1,69 @@
'use client'
import type { FC } from 'react'
import React, { useRef } from 'react'
import { useTranslation } from 'react-i18next'
import VarHighlight from '../../base/var-highlight'
import Button from '@/app/components/base/button'
export type IConfirmAddVarProps = {
  varNameArr: string[]
  onConfirm: () => void
  onCancel: () => void
  onHide: () => void
}
const VarIcon = (
  <svg width="16" height="14" viewBox="0 0 16 14" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M13.8683 0.704745C13.7051 0.374685 13.3053 0.239393 12.9752 0.402563C12.6452 0.565732 12.5099 0.965573 12.673 1.29563C13.5221 3.01316 13.9999 4.94957 13.9999 7.00019C13.9999 9.05081 13.5221 10.9872 12.673 12.7047C12.5099 13.0348 12.6452 13.4346 12.9752 13.5978C13.3053 13.761 13.7051 13.6257 13.8683 13.2956C14.8063 11.3983 15.3333 9.26009 15.3333 7.00019C15.3333 4.74029 14.8063 2.60209 13.8683 0.704745Z" fill="#FD853A" />
    <path d="M3.32687 1.29563C3.49004 0.965573 3.35475 0.565732 3.02469 0.402563C2.69463 0.239393 2.29479 0.374685 2.13162 0.704745C1.19364 2.60209 0.666626 4.74029 0.666626 7.00019C0.666626 9.26009 1.19364 11.3983 2.13162 13.2956C2.29479 13.6257 2.69463 13.761 3.02469 13.5978C3.35475 13.4346 3.49004 13.0348 3.32687 12.7047C2.47779 10.9872 1.99996 9.05081 1.99996 7.00019C1.99996 4.94957 2.47779 3.01316 3.32687 1.29563Z" fill="#FD853A" />
    <path d="M9.33238 4.8413C9.74208 4.36081 10.3411 4.08337 10.9726 4.08337H11.0324C11.4006 4.08337 11.6991 4.38185 11.6991 4.75004C11.6991 5.11823 11.4006 5.41671 11.0324 5.41671H10.9726C10.7329 5.41671 10.5042 5.52196 10.347 5.7064L8.78693 7.536L9.28085 9.27382C9.29145 9.31112 9.32388 9.33337 9.35696 9.33337H10.2864C10.6545 9.33337 10.953 9.63185 10.953 10C10.953 10.3682 10.6545 10.6667 10.2864 10.6667H9.35696C8.72382 10.6667 8.17074 10.245 7.99832 9.63834L7.74732 8.75524L6.76373 9.90878C6.35403 10.3893 5.75501 10.6667 5.1235 10.6667H5.06372C4.69553 10.6667 4.39705 10.3682 4.39705 10C4.39705 9.63185 4.69553 9.33337 5.06372 9.33337H5.1235C5.3632 9.33337 5.59189 9.22812 5.74915 9.04368L7.30926 7.21399L6.81536 5.47626C6.80476 5.43897 6.77233 5.41671 6.73925 5.41671H5.80986C5.44167 5.41671 5.14319 5.11823 5.14319 4.75004C5.14319 4.38185 5.44167 4.08337 5.80986 4.08337H6.73925C7.37239 4.08337 7.92547 4.50508 8.0979 5.11174L8.34887 5.99475L9.33238 4.8413Z" fill="#FD853A" />
  </svg>
)
const ConfirmAddVar: FC<IConfirmAddVarProps> = ({
  varNameArr,
  onConfirm,
  onCancel,
  // onHide,
}) => {
  const { t } = useTranslation()
  const mainContentRef = useRef<HTMLDivElement>(null)
  // new prompt editor blur trigger click...
  // useClickAway(() => {
  //   onHide()
  // }, mainContentRef)
  return (
    <div className='absolute inset-0  flex items-center justify-center rounded-xl'
      style={{
        backgroundColor: 'rgba(35, 56, 118, 0.2)',
      }}>
      <div
        ref={mainContentRef}
        className='w-[420px] rounded-xl bg-components-panel-bg p-6'
        style={{
          boxShadow: '0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03)',
        }}
      >
        <div className='flex items-start space-x-3'>
          <div
            className='flex h-10 w-10 shrink-0 items-center justify-center rounded-xl border border-components-card-border bg-components-card-bg-alt shadow-lg'
          >{VarIcon}</div>
          <div className='grow-1'>
            <div className='text-sm font-medium text-text-primary'>{t('appDebug.autoAddVar')}</div>
            <div className='mt-[15px] flex max-h-[66px] flex-wrap space-x-1 overflow-y-auto px-1'>
              {varNameArr.map(name => (
                <VarHighlight key={name} name={name} />
              ))}
            </div>
          </div>
        </div>
        <div className='mt-7 flex justify-end space-x-2'>
          <Button onClick={onCancel}>{t('common.operation.cancel')}</Button>
          <Button variant='primary' onClick={onConfirm}>{t('common.operation.add')}</Button>
        </div>
      </div>
    </div>
  )
}
export default React.memo(ConfirmAddVar)
app/components/app/configuration/config-prompt/conversation-history/edit-modal.tsx
New file
@@ -0,0 +1,58 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import Modal from '@/app/components/base/modal'
import type { ConversationHistoriesRole } from '@/models/debug'
import Button from '@/app/components/base/button'
type Props = {
  isShow: boolean
  saveLoading: boolean
  data: ConversationHistoriesRole
  onClose: () => void
  onSave: (data: any) => void
}
const EditModal: FC<Props> = ({
  isShow,
  saveLoading,
  data,
  onClose,
  onSave,
}) => {
  const { t } = useTranslation()
  const [tempData, setTempData] = useState(data)
  return (
    <Modal
      title={t('appDebug.feature.conversationHistory.editModal.title')}
      isShow={isShow}
      onClose={onClose}
    >
      <div className={'mt-6 text-sm font-medium leading-[21px] text-text-primary'}>{t('appDebug.feature.conversationHistory.editModal.userPrefix')}</div>
      <input className={'mt-2 box-border h-10 w-full rounded-lg bg-components-input-bg-normal px-3 text-sm leading-10'}
        value={tempData.user_prefix}
        onChange={e => setTempData({
          ...tempData,
          user_prefix: e.target.value,
        })}
      />
      <div className={'mt-6 text-sm font-medium leading-[21px] text-text-primary'}>{t('appDebug.feature.conversationHistory.editModal.assistantPrefix')}</div>
      <input className={'mt-2 box-border h-10 w-full rounded-lg bg-components-input-bg-normal px-3 text-sm leading-10'}
        value={tempData.assistant_prefix}
        onChange={e => setTempData({
          ...tempData,
          assistant_prefix: e.target.value,
        })}
        placeholder={t('common.chat.conversationNamePlaceholder') || ''}
      />
      <div className='mt-10 flex justify-end'>
        <Button className='mr-2 shrink-0' onClick={onClose}>{t('common.operation.cancel')}</Button>
        <Button variant='primary' className='shrink-0' onClick={() => onSave(tempData)} loading={saveLoading}>{t('common.operation.save')}</Button>
      </div>
    </Modal>
  )
}
export default React.memo(EditModal)
app/components/app/configuration/config-prompt/conversation-history/history-panel.tsx
New file
@@ -0,0 +1,60 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useContext } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import OperationBtn from '@/app/components/app/configuration/base/operation-btn'
import Panel from '@/app/components/app/configuration/base/feature-panel'
import { MessageClockCircle } from '@/app/components/base/icons/src/vender/solid/general'
import I18n from '@/context/i18n'
import { LanguagesSupported } from '@/i18n/language'
type Props = {
  showWarning: boolean
  onShowEditModal: () => void
}
const HistoryPanel: FC<Props> = ({
  showWarning,
  onShowEditModal,
}) => {
  const { t } = useTranslation()
  const { locale } = useContext(I18n)
  return (
    <Panel
      className='mt-2'
      title={
        <div className='flex items-center gap-2'>
          <div>{t('appDebug.feature.conversationHistory.title')}</div>
        </div>
      }
      headerIcon={
        <div className='rounded-md p-1 shadow-xs'>
          <MessageClockCircle className='h-4 w-4 text-[#DD2590]' />
        </div>}
      headerRight={
        <div className='flex items-center'>
          <div className='text-xs text-text-tertiary'>{t('appDebug.feature.conversationHistory.description')}</div>
          <div className='ml-3 h-[14px] w-[1px] bg-divider-regular'></div>
          <OperationBtn type="edit" onClick={onShowEditModal} />
        </div>
      }
      noBodySpacing
    >
      {showWarning && (
        <div className='flex justify-between rounded-b-xl bg-background-section-burn px-3 py-2 text-xs text-text-secondary'>
          <div>{t('appDebug.feature.conversationHistory.tip')}
            <a href={`${locale === LanguagesSupported[1]
              ? 'https://docs.dify.ai/zh-hans/learn-more/extended-reading/prompt-engineering/README'
              : 'https://docs.dify.ai/en/features/prompt-engineering'}`}
            target='_blank' rel='noopener noreferrer'
            className='text-[#155EEF]'>{t('appDebug.feature.conversationHistory.learnMore')}
            </a>
          </div>
        </div>
      )}
    </Panel>
  )
}
export default React.memo(HistoryPanel)
app/components/app/configuration/config-prompt/index.tsx
New file
@@ -0,0 +1,170 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useContext } from 'use-context-selector'
import produce from 'immer'
import {
  RiAddLine,
} from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import SimplePromptInput from './simple-prompt-input'
import Button from '@/app/components/base/button'
import AdvancedMessageInput from '@/app/components/app/configuration/config-prompt/advanced-prompt-input'
import { PromptRole } from '@/models/debug'
import type { PromptItem, PromptVariable } from '@/models/debug'
import { type AppType, ModelModeType } from '@/types/app'
import ConfigContext from '@/context/debug-configuration'
import { MAX_PROMPT_MESSAGE_LENGTH } from '@/config'
export type IPromptProps = {
  mode: AppType
  promptTemplate: string
  promptVariables: PromptVariable[]
  readonly?: boolean
  noTitle?: boolean
  gradientBorder?: boolean
  editorHeight?: number
  noResize?: boolean
  onChange?: (prompt: string, promptVariables: PromptVariable[]) => void
}
const Prompt: FC<IPromptProps> = ({
  mode,
  promptTemplate,
  promptVariables,
  noTitle,
  gradientBorder,
  readonly = false,
  editorHeight,
  noResize,
  onChange,
}) => {
  const { t } = useTranslation()
  const {
    isAdvancedMode,
    currentAdvancedPrompt,
    setCurrentAdvancedPrompt,
    modelModeType,
    dataSets,
    hasSetBlockStatus,
  } = useContext(ConfigContext)
  const handleMessageTypeChange = (index: number, role: PromptRole) => {
    const newPrompt = produce(currentAdvancedPrompt as PromptItem[], (draft) => {
      draft[index].role = role
    })
    setCurrentAdvancedPrompt(newPrompt)
  }
  const handleValueChange = (value: string, index?: number) => {
    if (modelModeType === ModelModeType.chat) {
      const newPrompt = produce(currentAdvancedPrompt as PromptItem[], (draft) => {
        draft[index as number].text = value
      })
      setCurrentAdvancedPrompt(newPrompt, true)
    }
    else {
      const prompt = currentAdvancedPrompt as PromptItem
      setCurrentAdvancedPrompt({
        ...prompt,
        text: value,
      }, true)
    }
  }
  const handleAddMessage = () => {
    const currentAdvancedPromptList = currentAdvancedPrompt as PromptItem[]
    if (currentAdvancedPromptList.length === 0) {
      setCurrentAdvancedPrompt([{
        role: PromptRole.system,
        text: '',
      }])
      return
    }
    const lastMessageType = currentAdvancedPromptList[currentAdvancedPromptList.length - 1]?.role
    const appendMessage = {
      role: lastMessageType === PromptRole.user ? PromptRole.assistant : PromptRole.user,
      text: '',
    }
    setCurrentAdvancedPrompt([...currentAdvancedPromptList, appendMessage])
  }
  const handlePromptDelete = (index: number) => {
    const currentAdvancedPromptList = currentAdvancedPrompt as PromptItem[]
    const newPrompt = produce(currentAdvancedPromptList, (draft) => {
      draft.splice(index, 1)
    })
    setCurrentAdvancedPrompt(newPrompt)
  }
  const isContextMissing = dataSets.length > 0 && !hasSetBlockStatus.context
  const [isHideContextMissTip, setIsHideContextMissTip] = React.useState(false)
  if (!isAdvancedMode) {
    return (
      <SimplePromptInput
        mode={mode}
        promptTemplate={promptTemplate}
        promptVariables={promptVariables}
        readonly={readonly}
        onChange={onChange}
        noTitle={noTitle}
        gradientBorder={gradientBorder}
        editorHeight={editorHeight}
        noResize={noResize}
      />
    )
  }
  return (
    <div>
      <div className='space-y-3'>
        {modelModeType === ModelModeType.chat
          ? (
            (currentAdvancedPrompt as PromptItem[]).map((item, index) => (
              <AdvancedMessageInput
                key={index}
                isChatMode
                type={item.role as PromptRole}
                value={item.text}
                onTypeChange={type => handleMessageTypeChange(index, type)}
                canDelete={(currentAdvancedPrompt as PromptItem[]).length > 1}
                onDelete={() => handlePromptDelete(index)}
                onChange={value => handleValueChange(value, index)}
                promptVariables={promptVariables}
                isContextMissing={isContextMissing && !isHideContextMissTip}
                onHideContextMissingTip={() => setIsHideContextMissTip(true)}
                noResize={noResize}
              />
            ))
          )
          : (
            <AdvancedMessageInput
              type={(currentAdvancedPrompt as PromptItem).role as PromptRole}
              isChatMode={false}
              value={(currentAdvancedPrompt as PromptItem).text}
              onTypeChange={type => handleMessageTypeChange(0, type)}
              canDelete={false}
              onDelete={() => handlePromptDelete(0)}
              onChange={value => handleValueChange(value)}
              promptVariables={promptVariables}
              isContextMissing={isContextMissing && !isHideContextMissTip}
              onHideContextMissingTip={() => setIsHideContextMissTip(true)}
              noResize={noResize}
            />
          )
        }
      </div>
      {(modelModeType === ModelModeType.chat && (currentAdvancedPrompt as PromptItem[]).length < MAX_PROMPT_MESSAGE_LENGTH) && (
        <Button
          onClick={handleAddMessage}
          className='mt-3 w-full'>
          <RiAddLine className='mr-2 h-4 w-4' />
          <div>{t('appDebug.promptMode.operation.addMessage')}</div>
        </Button>
      )}
    </div>
  )
}
export default React.memo(Prompt)
app/components/app/configuration/config-prompt/message-type-selector.tsx
New file
@@ -0,0 +1,50 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useBoolean, useClickAway } from 'ahooks'
import cn from '@/utils/classnames'
import { PromptRole } from '@/models/debug'
import { ChevronSelectorVertical } from '@/app/components/base/icons/src/vender/line/arrows'
type Props = {
  value: PromptRole
  onChange: (value: PromptRole) => void
}
const allTypes = [PromptRole.system, PromptRole.user, PromptRole.assistant]
const MessageTypeSelector: FC<Props> = ({
  value,
  onChange,
}) => {
  const [showOption, { setFalse: setHide, toggle: toggleShow }] = useBoolean(false)
  const ref = React.useRef(null)
  useClickAway(() => {
    setHide()
  }, ref)
  return (
    <div className='relative left-[-8px]' ref={ref}>
      <div
        onClick={toggleShow}
        className={cn(showOption && 'bg-indigo-100', 'flex h-7 cursor-pointer items-center space-x-0.5 rounded-lg pl-1.5 pr-1 text-indigo-800')}>
        <div className='text-sm font-semibold uppercase'>{value}</div>
        <ChevronSelectorVertical className='h-3 w-3 ' />
      </div>
      {showOption && (
        <div className='absolute top-[30px] z-10 rounded-lg border border-components-panel-border bg-components-panel-bg p-1 shadow-lg'>
          {allTypes.map(type => (
            <div
              key={type}
              onClick={() => {
                setHide()
                onChange(type)
              }}
              className='flex h-9 min-w-[44px] cursor-pointer items-center rounded-lg px-3 text-sm font-medium uppercase text-text-secondary hover:bg-state-base-hover'
            >{type}</div>
          ))
          }
        </div>
      )
      }
    </div>
  )
}
export default React.memo(MessageTypeSelector)
app/components/app/configuration/config-prompt/prompt-editor-height-resize-wrap.tsx
New file
@@ -0,0 +1,96 @@
'use client'
import React, { useCallback, useEffect, useState } from 'react'
import type { FC } from 'react'
import { useDebounceFn } from 'ahooks'
import cn from '@/utils/classnames'
type Props = {
  className?: string
  height: number
  minHeight: number
  onHeightChange: (height: number) => void
  children: React.JSX.Element
  footer?: React.JSX.Element
  hideResize?: boolean
}
const PromptEditorHeightResizeWrap: FC<Props> = ({
  className,
  height,
  minHeight,
  onHeightChange,
  children,
  footer,
  hideResize,
}) => {
  const [clientY, setClientY] = useState(0)
  const [isResizing, setIsResizing] = useState(false)
  const [prevUserSelectStyle, setPrevUserSelectStyle] = useState(getComputedStyle(document.body).userSelect)
  const [oldHeight, setOldHeight] = useState(height)
  const handleStartResize = useCallback((e: React.MouseEvent<HTMLElement>) => {
    setClientY(e.clientY)
    setIsResizing(true)
    setOldHeight(height)
    setPrevUserSelectStyle(getComputedStyle(document.body).userSelect)
    document.body.style.userSelect = 'none'
  }, [height])
  const handleStopResize = useCallback(() => {
    setIsResizing(false)
    document.body.style.userSelect = prevUserSelectStyle
  }, [prevUserSelectStyle])
  const { run: didHandleResize } = useDebounceFn((e) => {
    if (!isResizing)
      return
    const offset = e.clientY - clientY
    let newHeight = oldHeight + offset
    if (newHeight < minHeight)
      newHeight = minHeight
    onHeightChange(newHeight)
  }, {
    wait: 0,
  })
  const handleResize = useCallback(didHandleResize, [isResizing, height, minHeight, clientY])
  useEffect(() => {
    document.addEventListener('mousemove', handleResize)
    return () => {
      document.removeEventListener('mousemove', handleResize)
    }
  }, [handleResize])
  useEffect(() => {
    document.addEventListener('mouseup', handleStopResize)
    return () => {
      document.removeEventListener('mouseup', handleStopResize)
    }
  }, [handleStopResize])
  return (
    <div
      className='relative'
    >
      <div className={cn(className, 'overflow-y-auto')}
        style={{
          height,
        }}
      >
        {children}
      </div>
      {/* resize handler */}
      {footer}
      {!hideResize && (
        <div
          className='absolute bottom-0 left-0 flex h-2 w-full cursor-row-resize justify-center'
          onMouseDown={handleStartResize}>
          <div className='h-[3px] w-5 rounded-sm bg-gray-300'></div>
        </div>
      )}
    </div>
  )
}
export default React.memo(PromptEditorHeightResizeWrap)
app/components/app/configuration/config-prompt/simple-prompt-input.tsx
New file
@@ -0,0 +1,284 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import produce from 'immer'
import { useContext } from 'use-context-selector'
import ConfirmAddVar from './confirm-add-var'
import PromptEditorHeightResizeWrap from './prompt-editor-height-resize-wrap'
import cn from '@/utils/classnames'
import type { PromptVariable } from '@/models/debug'
import Tooltip from '@/app/components/base/tooltip'
import type { CompletionParams } from '@/types/app'
import { AppType } from '@/types/app'
import { getNewVar, getVars } from '@/utils/var'
import AutomaticBtn from '@/app/components/app/configuration/config/automatic/automatic-btn'
import type { AutomaticRes } from '@/service/debug'
import GetAutomaticResModal from '@/app/components/app/configuration/config/automatic/get-automatic-res'
import PromptEditor from '@/app/components/base/prompt-editor'
import ConfigContext from '@/context/debug-configuration'
import { useModalContext } from '@/context/modal-context'
import type { ExternalDataTool } from '@/models/common'
import { useToastContext } from '@/app/components/base/toast'
import { useEventEmitterContextContext } from '@/context/event-emitter'
import { ADD_EXTERNAL_DATA_TOOL } from '@/app/components/app/configuration/config-var'
import { INSERT_VARIABLE_VALUE_BLOCK_COMMAND } from '@/app/components/base/prompt-editor/plugins/variable-block'
import { PROMPT_EDITOR_UPDATE_VALUE_BY_EVENT_EMITTER } from '@/app/components/base/prompt-editor/plugins/update-block'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import { useFeaturesStore } from '@/app/components/base/features/hooks'
import { noop } from 'lodash-es'
export type ISimplePromptInput = {
  mode: AppType
  promptTemplate: string
  promptVariables: PromptVariable[]
  readonly?: boolean
  onChange?: (prompt: string, promptVariables: PromptVariable[]) => void
  noTitle?: boolean
  gradientBorder?: boolean
  editorHeight?: number
  noResize?: boolean
}
const Prompt: FC<ISimplePromptInput> = ({
  mode,
  promptTemplate,
  promptVariables,
  readonly = false,
  onChange,
  noTitle,
  editorHeight: initEditorHeight,
  noResize,
}) => {
  const { t } = useTranslation()
  const media = useBreakpoints()
  const isMobile = media === MediaType.mobile
  const featuresStore = useFeaturesStore()
  const {
    features,
    setFeatures,
  } = featuresStore!.getState()
  const { eventEmitter } = useEventEmitterContextContext()
  const {
    modelConfig,
    completionParams,
    dataSets,
    setModelConfig,
    setPrevPromptConfig,
    setIntroduction,
    hasSetBlockStatus,
    showSelectDataSet,
    externalDataToolsConfig,
  } = useContext(ConfigContext)
  const { notify } = useToastContext()
  const { setShowExternalDataToolModal } = useModalContext()
  const handleOpenExternalDataToolModal = () => {
    setShowExternalDataToolModal({
      payload: {},
      onSaveCallback: (newExternalDataTool: ExternalDataTool) => {
        eventEmitter?.emit({
          type: ADD_EXTERNAL_DATA_TOOL,
          payload: newExternalDataTool,
        } as any)
        eventEmitter?.emit({
          type: INSERT_VARIABLE_VALUE_BLOCK_COMMAND,
          payload: newExternalDataTool.variable,
        } as any)
      },
      onValidateBeforeSaveCallback: (newExternalDataTool: ExternalDataTool) => {
        for (let i = 0; i < promptVariables.length; i++) {
          if (promptVariables[i].key === newExternalDataTool.variable) {
            notify({ type: 'error', message: t('appDebug.varKeyError.keyAlreadyExists', { key: promptVariables[i].key }) })
            return false
          }
        }
        return true
      },
    })
  }
  const promptVariablesObj = (() => {
    const obj: Record<string, boolean> = {}
    promptVariables.forEach((item) => {
      obj[item.key] = true
    })
    return obj
  })()
  const [newPromptVariables, setNewPromptVariables] = React.useState<PromptVariable[]>(promptVariables)
  const [newTemplates, setNewTemplates] = React.useState('')
  const [isShowConfirmAddVar, { setTrue: showConfirmAddVar, setFalse: hideConfirmAddVar }] = useBoolean(false)
  const handleChange = (newTemplates: string, keys: string[]) => {
    const newPromptVariables = keys.filter(key => !(key in promptVariablesObj) && !externalDataToolsConfig.find(item => item.variable === key)).map(key => getNewVar(key, ''))
    if (newPromptVariables.length > 0) {
      setNewPromptVariables(newPromptVariables)
      setNewTemplates(newTemplates)
      showConfirmAddVar()
      return
    }
    onChange?.(newTemplates, [])
  }
  const handleAutoAdd = (isAdd: boolean) => {
    return () => {
      onChange?.(newTemplates, isAdd ? newPromptVariables : [])
      hideConfirmAddVar()
    }
  }
  const [showAutomatic, { setTrue: showAutomaticTrue, setFalse: showAutomaticFalse }] = useBoolean(false)
  const handleAutomaticRes = (res: AutomaticRes) => {
    // put eventEmitter in first place to prevent overwrite the configs.prompt_variables.But another problem is that prompt won't hight the prompt_variables.
    eventEmitter?.emit({
      type: PROMPT_EDITOR_UPDATE_VALUE_BY_EVENT_EMITTER,
      payload: res.prompt,
    } as any)
    const newModelConfig = produce(modelConfig, (draft) => {
      draft.configs.prompt_template = res.prompt
      draft.configs.prompt_variables = res.variables.map(key => ({ key, name: key, type: 'string', required: true }))
    })
    setModelConfig(newModelConfig)
    setPrevPromptConfig(modelConfig.configs)
    if (mode !== AppType.completion) {
      setIntroduction(res.opening_statement)
      const newFeatures = produce(features, (draft) => {
        draft.opening = {
          ...draft.opening,
          enabled: !!res.opening_statement,
          opening_statement: res.opening_statement,
        }
      })
      setFeatures(newFeatures)
    }
    showAutomaticFalse()
  }
  const minHeight = initEditorHeight || 228
  const [editorHeight, setEditorHeight] = useState(minHeight)
  return (
    <div className={cn('relative rounded-xl bg-gradient-to-r from-components-input-border-active-prompt-1 to-components-input-border-active-prompt-2 p-0.5 shadow-xs')}>
      <div className='rounded-xl bg-background-section-burn'>
        {!noTitle && (
          <div className="flex h-11 items-center justify-between pl-3 pr-2.5">
            <div className="flex items-center space-x-1">
              <div className='h2 system-sm-semibold-uppercase text-text-secondary'>{mode !== AppType.completion ? t('appDebug.chatSubTitle') : t('appDebug.completionSubTitle')}</div>
              {!readonly && (
                <Tooltip
                  popupContent={
                    <div className='w-[180px]'>
                      {t('appDebug.promptTip')}
                    </div>
                  }
                />
              )}
            </div>
            <div className='flex items-center'>
              {!readonly && !isMobile && (
                <AutomaticBtn onClick={showAutomaticTrue} />
              )}
            </div>
          </div>
        )}
        <PromptEditorHeightResizeWrap
          className='min-h-[228px] rounded-t-xl bg-background-default px-4 pt-2 text-sm text-text-secondary'
          height={editorHeight}
          minHeight={minHeight}
          onHeightChange={setEditorHeight}
          hideResize={noResize}
          footer={(
            <div className='flex rounded-b-xl bg-background-default pb-2 pl-4'>
              <div className="h-[18px] rounded-md bg-components-badge-bg-gray-soft px-1 text-xs leading-[18px] text-text-tertiary">{promptTemplate.length}</div>
            </div>
          )}
        >
          <PromptEditor
            className='min-h-[210px]'
            compact
            value={promptTemplate}
            contextBlock={{
              show: false,
              selectable: !hasSetBlockStatus.context,
              datasets: dataSets.map(item => ({
                id: item.id,
                name: item.name,
                type: item.data_source_type,
              })),
              onAddContext: showSelectDataSet,
            }}
            variableBlock={{
              show: true,
              variables: modelConfig.configs.prompt_variables.filter(item => item.type !== 'api').map(item => ({
                name: item.name,
                value: item.key,
              })),
            }}
            externalToolBlock={{
              show: true,
              externalTools: modelConfig.configs.prompt_variables.filter(item => item.type === 'api').map(item => ({
                name: item.name,
                variableName: item.key,
                icon: item.icon,
                icon_background: item.icon_background,
              })),
              onAddExternalTool: handleOpenExternalDataToolModal,
            }}
            historyBlock={{
              show: false,
              selectable: false,
              history: {
                user: '',
                assistant: '',
              },
              onEditRole: noop,
            }}
            queryBlock={{
              show: false,
              selectable: !hasSetBlockStatus.query,
            }}
            onChange={(value) => {
              if (handleChange)
                handleChange(value, [])
            }}
            onBlur={() => {
              handleChange(promptTemplate, getVars(promptTemplate))
            }}
            editable={!readonly}
          />
        </PromptEditorHeightResizeWrap>
      </div>
      {isShowConfirmAddVar && (
        <ConfirmAddVar
          varNameArr={newPromptVariables.map(v => v.name)}
          onConfirm={handleAutoAdd(true)}
          onCancel={handleAutoAdd(false)}
          onHide={hideConfirmAddVar}
        />
      )}
      {showAutomatic && (
        <GetAutomaticResModal
          mode={mode as AppType}
          model={
            {
              provider: modelConfig.provider,
              name: modelConfig.model_id,
              mode: modelConfig.mode,
              completion_params: completionParams as CompletionParams,
            }
          }
          isShow={showAutomatic}
          onClose={showAutomaticFalse}
          onFinished={handleAutomaticRes}
        />
      )}
    </div>
  )
}
export default React.memo(Prompt)
app/components/app/configuration/config-prompt/style.module.css
New file
@@ -0,0 +1,28 @@
.gradientBorder {
  background: radial-gradient(circle at 100% 100%, #fcfcfd 0, #fcfcfd 10px, transparent 10px) 0% 0%/12px 12px no-repeat,
            radial-gradient(circle at 0 100%, #fcfcfd 0, #fcfcfd 10px, transparent 10px) 100% 0%/12px 12px no-repeat,
            radial-gradient(circle at 100% 0, #fcfcfd 0, #fcfcfd 10px, transparent 10px) 0% 100%/12px 12px no-repeat,
            radial-gradient(circle at 0 0, #fcfcfd 0, #fcfcfd 10px, transparent 10px) 100% 100%/12px 12px no-repeat,
            linear-gradient(#fcfcfd, #fcfcfd) 50% 50%/calc(100% - 4px) calc(100% - 24px) no-repeat,
            linear-gradient(#fcfcfd, #fcfcfd) 50% 50%/calc(100% - 24px) calc(100% - 4px) no-repeat,
            radial-gradient(at 100% 100%, rgba(45,13,238,0.8) 0%, transparent 70%),
            radial-gradient(at 100% 0%, rgba(45,13,238,0.8) 0%, transparent 70%),
            radial-gradient(at 0% 0%, rgba(42,135,245,0.8) 0%, transparent 70%),
            radial-gradient(at 0% 100%, rgba(42,135,245,0.8) 0%, transparent 70%);
  border-radius: 12px;
  padding: 2px;
  box-sizing: border-box;
}
.warningBorder {
  border: 2px solid #F79009;
  border-radius: 12px;
}
.optionWrap {
  display: none;
}
.boxHeader:hover .optionWrap {
  display: flex;
}
app/components/app/configuration/config-var/config-modal/field.tsx
New file
@@ -0,0 +1,24 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import cn from '@/utils/classnames'
type Props = {
  className?: string
  title: string
  children: React.JSX.Element
}
const Field: FC<Props> = ({
  className,
  title,
  children,
}) => {
  return (
    <div className={cn(className)}>
      <div className='system-sm-semibold leading-8 text-text-secondary'>{title}</div>
      <div>{children}</div>
    </div>
  )
}
export default React.memo(Field)
app/components/app/configuration/config-var/config-modal/index.tsx
New file
@@ -0,0 +1,249 @@
'use client'
import type { FC } from 'react'
import React, { useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import produce from 'immer'
import ModalFoot from '../modal-foot'
import ConfigSelect from '../config-select'
import ConfigString from '../config-string'
import SelectTypeItem from '../select-type-item'
import Field from './field'
import Input from '@/app/components/base/input'
import Toast from '@/app/components/base/toast'
import { checkKeys, getNewVarInWorkflow } from '@/utils/var'
import ConfigContext from '@/context/debug-configuration'
import type { InputVar, MoreInfo, UploadFileSetting } from '@/app/components/workflow/types'
import Modal from '@/app/components/base/modal'
import { ChangeType, InputVarType, SupportUploadFileTypes } from '@/app/components/workflow/types'
import FileUploadSetting from '@/app/components/workflow/nodes/_base/components/file-upload-setting'
import Checkbox from '@/app/components/base/checkbox'
import { DEFAULT_FILE_UPLOAD_SETTING } from '@/app/components/workflow/constants'
import { DEFAULT_VALUE_MAX_LEN } from '@/config'
const TEXT_MAX_LENGTH = 256
export type IConfigModalProps = {
  isCreate?: boolean
  payload?: InputVar
  isShow: boolean
  varKeys?: string[]
  onClose: () => void
  onConfirm: (newValue: InputVar, moreInfo?: MoreInfo) => void
  supportFile?: boolean
}
const ConfigModal: FC<IConfigModalProps> = ({
  isCreate,
  payload,
  isShow,
  onClose,
  onConfirm,
  supportFile,
}) => {
  const { modelConfig } = useContext(ConfigContext)
  const { t } = useTranslation()
  const [tempPayload, setTempPayload] = useState<InputVar>(payload || getNewVarInWorkflow('') as any)
  const { type, label, variable, options, max_length } = tempPayload
  const modalRef = useRef<HTMLDivElement>(null)
  useEffect(() => {
    // To fix the first input element auto focus, then directly close modal will raise error
    if (isShow)
      modalRef.current?.focus()
  }, [isShow])
  const isStringInput = type === InputVarType.textInput || type === InputVarType.paragraph
  const checkVariableName = useCallback((value: string, canBeEmpty?: boolean) => {
    const { isValid, errorMessageKey } = checkKeys([value], canBeEmpty)
    if (!isValid) {
      Toast.notify({
        type: 'error',
        message: t(`appDebug.varKeyError.${errorMessageKey}`, { key: t('appDebug.variableConfig.varName') }),
      })
      return false
    }
    return true
  }, [t])
  const handlePayloadChange = useCallback((key: string) => {
    return (value: any) => {
      setTempPayload((prev) => {
        const newPayload = {
          ...prev,
          [key]: value,
        }
        return newPayload
      })
    }
  }, [])
  const handleTypeChange = useCallback((type: InputVarType) => {
    return () => {
      const newPayload = produce(tempPayload, (draft) => {
        draft.type = type
        if ([InputVarType.singleFile, InputVarType.multiFiles].includes(type)) {
          (Object.keys(DEFAULT_FILE_UPLOAD_SETTING)).forEach((key) => {
            if (key !== 'max_length')
              (draft as any)[key] = (DEFAULT_FILE_UPLOAD_SETTING as any)[key]
          })
          if (type === InputVarType.multiFiles)
            draft.max_length = DEFAULT_FILE_UPLOAD_SETTING.max_length
        }
        if (type === InputVarType.paragraph)
          draft.max_length = DEFAULT_VALUE_MAX_LEN
      })
      setTempPayload(newPayload)
    }
  }, [tempPayload])
  const handleVarKeyBlur = useCallback((e: any) => {
    const varName = e.target.value
    if (!checkVariableName(varName, true) || tempPayload.label)
      return
    setTempPayload((prev) => {
      return {
        ...prev,
        label: varName,
      }
    })
  }, [checkVariableName, tempPayload.label])
  const handleConfirm = () => {
    const moreInfo = tempPayload.variable === payload?.variable
      ? undefined
      : {
        type: ChangeType.changeVarName,
        payload: { beforeKey: payload?.variable || '', afterKey: tempPayload.variable },
      }
    const isVariableNameValid = checkVariableName(tempPayload.variable)
    if (!isVariableNameValid)
      return
    // TODO: check if key already exists. should the consider the edit case
    // if (varKeys.map(key => key?.trim()).includes(tempPayload.variable.trim())) {
    //   Toast.notify({
    //     type: 'error',
    //     message: t('appDebug.varKeyError.keyAlreadyExists', { key: tempPayload.variable }),
    //   })
    //   return
    // }
    if (!tempPayload.label) {
      Toast.notify({ type: 'error', message: t('appDebug.variableConfig.errorMsg.labelNameRequired') })
      return
    }
    if (isStringInput || type === InputVarType.number) {
      onConfirm(tempPayload, moreInfo)
    }
    else if (type === InputVarType.select) {
      if (options?.length === 0) {
        Toast.notify({ type: 'error', message: t('appDebug.variableConfig.errorMsg.atLeastOneOption') })
        return
      }
      const obj: Record<string, boolean> = {}
      let hasRepeatedItem = false
      options?.forEach((o) => {
        if (obj[o]) {
          hasRepeatedItem = true
          return
        }
        obj[o] = true
      })
      if (hasRepeatedItem) {
        Toast.notify({ type: 'error', message: t('appDebug.variableConfig.errorMsg.optionRepeat') })
        return
      }
      onConfirm(tempPayload, moreInfo)
    }
    else if ([InputVarType.singleFile, InputVarType.multiFiles].includes(type)) {
      if (tempPayload.allowed_file_types?.length === 0) {
        const errorMessages = t('workflow.errorMsg.fieldRequired', { field: t('appDebug.variableConfig.file.supportFileTypes') })
        Toast.notify({ type: 'error', message: errorMessages })
        return
      }
      if (tempPayload.allowed_file_types?.includes(SupportUploadFileTypes.custom) && !tempPayload.allowed_file_extensions?.length) {
        const errorMessages = t('workflow.errorMsg.fieldRequired', { field: t('appDebug.variableConfig.file.custom.name') })
        Toast.notify({ type: 'error', message: errorMessages })
        return
      }
      onConfirm(tempPayload, moreInfo)
    }
    else {
      onConfirm(tempPayload, moreInfo)
    }
  }
  return (
    <Modal
      title={t(`appDebug.variableConfig.${isCreate ? 'addModalTitle' : 'editModalTitle'}`)}
      isShow={isShow}
      onClose={onClose}
    >
      <div className='mb-8' ref={modalRef} tabIndex={-1}>
        <div className='space-y-2'>
          <Field title={t('appDebug.variableConfig.fieldType')}>
            <div className='grid grid-cols-3 gap-2'>
              <SelectTypeItem type={InputVarType.textInput} selected={type === InputVarType.textInput} onClick={handleTypeChange(InputVarType.textInput)} />
              <SelectTypeItem type={InputVarType.paragraph} selected={type === InputVarType.paragraph} onClick={handleTypeChange(InputVarType.paragraph)} />
              <SelectTypeItem type={InputVarType.select} selected={type === InputVarType.select} onClick={handleTypeChange(InputVarType.select)} />
              <SelectTypeItem type={InputVarType.number} selected={type === InputVarType.number} onClick={handleTypeChange(InputVarType.number)} />
              {supportFile && <>
                <SelectTypeItem type={InputVarType.singleFile} selected={type === InputVarType.singleFile} onClick={handleTypeChange(InputVarType.singleFile)} />
                <SelectTypeItem type={InputVarType.multiFiles} selected={type === InputVarType.multiFiles} onClick={handleTypeChange(InputVarType.multiFiles)} />
              </>}
            </div>
          </Field>
          <Field title={t('appDebug.variableConfig.varName')}>
            <Input
              value={variable}
              onChange={e => handlePayloadChange('variable')(e.target.value)}
              onBlur={handleVarKeyBlur}
              placeholder={t('appDebug.variableConfig.inputPlaceholder')!}
            />
          </Field>
          <Field title={t('appDebug.variableConfig.labelName')}>
            <Input
              value={label as string}
              onChange={e => handlePayloadChange('label')(e.target.value)}
              placeholder={t('appDebug.variableConfig.inputPlaceholder')!}
            />
          </Field>
          {isStringInput && (
            <Field title={t('appDebug.variableConfig.maxLength')}>
              <ConfigString maxLength={type === InputVarType.textInput ? TEXT_MAX_LENGTH : Infinity} modelId={modelConfig.model_id} value={max_length} onChange={handlePayloadChange('max_length')} />
            </Field>
          )}
          {type === InputVarType.select && (
            <Field title={t('appDebug.variableConfig.options')}>
              <ConfigSelect options={options || []} onChange={handlePayloadChange('options')} />
            </Field>
          )}
          {[InputVarType.singleFile, InputVarType.multiFiles].includes(type) && (
            <FileUploadSetting
              payload={tempPayload as UploadFileSetting}
              onChange={(p: UploadFileSetting) => setTempPayload(p as InputVar)}
              isMultiple={type === InputVarType.multiFiles}
            />
          )}
          <div className='!mt-5 flex h-6 items-center space-x-2'>
            <Checkbox checked={tempPayload.required} onCheck={() => handlePayloadChange('required')(!tempPayload.required)} />
            <span className='system-sm-semibold text-text-secondary'>{t('appDebug.variableConfig.required')}</span>
          </div>
        </div>
      </div>
      <ModalFoot
        onConfirm={handleConfirm}
        onCancel={onClose}
      />
    </Modal>
  )
}
export default React.memo(ConfigModal)
app/components/app/configuration/config-var/config-select/index.spec.tsx
New file
@@ -0,0 +1,82 @@
import { fireEvent, render, screen } from '@testing-library/react'
import ConfigSelect from './index'
jest.mock('react-sortablejs', () => ({
  ReactSortable: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
}))
jest.mock('react-i18next', () => ({
  useTranslation: () => ({
    t: (key: string) => key,
  }),
}))
describe('ConfigSelect Component', () => {
  const defaultProps = {
    options: ['Option 1', 'Option 2'],
    onChange: jest.fn(),
  }
  afterEach(() => {
    jest.clearAllMocks()
  })
  it('renders all options', () => {
    render(<ConfigSelect {...defaultProps} />)
    defaultProps.options.forEach((option) => {
      expect(screen.getByDisplayValue(option)).toBeInTheDocument()
    })
  })
  it('renders add button', () => {
    render(<ConfigSelect {...defaultProps} />)
    expect(screen.getByText('appDebug.variableConfig.addOption')).toBeInTheDocument()
  })
  it('handles option deletion', () => {
    render(<ConfigSelect {...defaultProps} />)
    const optionContainer = screen.getByDisplayValue('Option 1').closest('div')
    const deleteButton = optionContainer?.querySelector('div[role="button"]')
    if (!deleteButton) return
    fireEvent.click(deleteButton)
    expect(defaultProps.onChange).toHaveBeenCalledWith(['Option 2'])
  })
  it('handles adding new option', () => {
    render(<ConfigSelect {...defaultProps} />)
    const addButton = screen.getByText('appDebug.variableConfig.addOption')
    fireEvent.click(addButton)
    expect(defaultProps.onChange).toHaveBeenCalledWith([...defaultProps.options, ''])
  })
  it('applies focus styles on input focus', () => {
    render(<ConfigSelect {...defaultProps} />)
    const firstInput = screen.getByDisplayValue('Option 1')
    fireEvent.focus(firstInput)
    expect(firstInput.closest('div')).toHaveClass('border-components-input-border-active')
  })
  it('applies delete hover styles', () => {
    render(<ConfigSelect {...defaultProps} />)
    const optionContainer = screen.getByDisplayValue('Option 1').closest('div')
    const deleteButton = optionContainer?.querySelector('div[role="button"]')
    if (!deleteButton) return
    fireEvent.mouseEnter(deleteButton)
    expect(optionContainer).toHaveClass('border-components-input-border-destructive')
  })
  it('renders empty state correctly', () => {
    render(<ConfigSelect options={[]} onChange={defaultProps.onChange} />)
    expect(screen.queryByRole('textbox')).not.toBeInTheDocument()
    expect(screen.getByText('appDebug.variableConfig.addOption')).toBeInTheDocument()
  })
})
app/components/app/configuration/config-var/config-select/index.tsx
New file
@@ -0,0 +1,96 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import { RiAddLine, RiDeleteBinLine, RiDraggable } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import { ReactSortable } from 'react-sortablejs'
import cn from '@/utils/classnames'
export type Options = string[]
export type IConfigSelectProps = {
  options: Options
  onChange: (options: Options) => void
}
const ConfigSelect: FC<IConfigSelectProps> = ({
  options,
  onChange,
}) => {
  const { t } = useTranslation()
  const [focusID, setFocusID] = useState<number | null>(null)
  const [deletingID, setDeletingID] = useState<number | null>(null)
  const optionList = options.map((content, index) => {
    return ({
      id: index,
      name: content,
    })
  })
  return (
    <div>
      {options.length > 0 && (
        <div className='mb-1'>
          <ReactSortable
            className="space-y-1"
            list={optionList}
            setList={list => onChange(list.map(item => item.name))}
            handle='.handle'
            ghostClass="opacity-50"
            animation={150}
          >
            {options.map((o, index) => (
              <div
                className={cn(
                  'group relative flex items-center rounded-lg border border-components-panel-border-subtle bg-components-panel-on-panel-item-bg pl-2.5 hover:bg-components-panel-on-panel-item-bg-hover',
                  focusID === index && 'border-components-input-border-active bg-components-input-bg-active hover:border-components-input-border-active hover:bg-components-input-bg-active',
                  deletingID === index && 'border-components-input-border-destructive bg-state-destructive-hover hover:border-components-input-border-destructive hover:bg-state-destructive-hover',
                )}
                key={index}
              >
                <RiDraggable className='handle h-4 w-4 cursor-grab text-text-quaternary' />
                <input
                  key={index}
                  type='input'
                  value={o || ''}
                  onChange={(e) => {
                    const value = e.target.value
                    onChange(options.map((item, i) => {
                      if (index === i)
                        return value
                      return item
                    }))
                  }}
                  className={'h-9 w-full grow cursor-pointer overflow-x-auto rounded-lg border-0 bg-transparent pl-1.5 pr-8 text-sm leading-9 text-text-secondary focus:outline-none'}
                  onFocus={() => setFocusID(index)}
                  onBlur={() => setFocusID(null)}
                />
                <div
                  role='button'
                  className='absolute right-1.5 top-1/2 block translate-y-[-50%] cursor-pointer rounded-md p-1 text-text-tertiary hover:bg-state-destructive-hover hover:text-text-destructive'
                  onClick={() => {
                    onChange(options.filter((_, i) => index !== i))
                  }}
                  onMouseEnter={() => setDeletingID(index)}
                  onMouseLeave={() => setDeletingID(null)}
                >
                  <RiDeleteBinLine className='h-3.5 w-3.5' />
                </div>
              </div>
            ))}
          </ReactSortable>
        </div>
      )}
      <div
        onClick={() => { onChange([...options, '']) }}
        className='mt-1 flex h-9 cursor-pointer items-center gap-2 rounded-lg bg-components-button-tertiary-bg px-3  text-components-button-tertiary-text hover:bg-components-button-tertiary-bg-hover'>
        <RiAddLine className='h-4 w-4' />
        <div className='system-sm-medium text-[13px]'>{t('appDebug.variableConfig.addOption')}</div>
      </div>
    </div>
  )
}
export default React.memo(ConfigSelect)
app/components/app/configuration/config-var/config-string/index.tsx
New file
@@ -0,0 +1,45 @@
'use client'
import type { FC } from 'react'
import React, { useEffect } from 'react'
import Input from '@/app/components/base/input'
export type IConfigStringProps = {
  value: number | undefined
  maxLength: number
  modelId: string
  onChange: (value: number | undefined) => void
}
const ConfigString: FC<IConfigStringProps> = ({
  value,
  onChange,
  maxLength,
}) => {
  useEffect(() => {
    if (value && value > maxLength)
      onChange(maxLength)
  }, [value, maxLength, onChange])
  return (
    <div>
      <Input
        type="number"
        max={maxLength}
        min={1}
        value={value || ''}
        onChange={(e) => {
          let value = Number.parseInt(e.target.value, 10)
          if (value > maxLength)
            value = maxLength
          else if (value < 1)
            value = 1
          onChange(value)
        }}
      />
    </div>
  )
}
export default React.memo(ConfigString)
app/components/app/configuration/config-var/index.tsx
New file
@@ -0,0 +1,271 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import { useContext } from 'use-context-selector'
import produce from 'immer'
import Panel from '../base/feature-panel'
import EditModal from './config-modal'
import VarItem from './var-item'
import SelectVarType from './select-var-type'
import Tooltip from '@/app/components/base/tooltip'
import type { PromptVariable } from '@/models/debug'
import { DEFAULT_VALUE_MAX_LEN } from '@/config'
import { getNewVar } from '@/utils/var'
import Toast from '@/app/components/base/toast'
import Confirm from '@/app/components/base/confirm'
import ConfigContext from '@/context/debug-configuration'
import { AppType } from '@/types/app'
import type { ExternalDataTool } from '@/models/common'
import { useModalContext } from '@/context/modal-context'
import { useEventEmitterContextContext } from '@/context/event-emitter'
import type { InputVar } from '@/app/components/workflow/types'
import { InputVarType } from '@/app/components/workflow/types'
export const ADD_EXTERNAL_DATA_TOOL = 'ADD_EXTERNAL_DATA_TOOL'
type ExternalDataToolParams = {
  key: string
  type: string
  index: number
  name: string
  config?: Record<string, any>
  icon?: string
  icon_background?: string
}
export type IConfigVarProps = {
  promptVariables: PromptVariable[]
  readonly?: boolean
  onPromptVariablesChange?: (promptVariables: PromptVariable[]) => void
}
const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVariablesChange }) => {
  const { t } = useTranslation()
  const {
    mode,
    dataSets,
  } = useContext(ConfigContext)
  const { eventEmitter } = useEventEmitterContextContext()
  const hasVar = promptVariables.length > 0
  const [currIndex, setCurrIndex] = useState<number>(-1)
  const currItem = currIndex !== -1 ? promptVariables[currIndex] : null
  const currItemToEdit: InputVar | null = (() => {
    if (!currItem)
      return null
    return {
      ...currItem,
      label: currItem.name,
      variable: currItem.key,
      type: currItem.type === 'string' ? InputVarType.textInput : currItem.type,
    } as InputVar
  })()
  const updatePromptVariableItem = (payload: InputVar) => {
    const newPromptVariables = produce(promptVariables, (draft) => {
      const { variable, label, type, ...rest } = payload
      draft[currIndex] = {
        ...rest,
        type: type === InputVarType.textInput ? 'string' : type,
        key: variable,
        name: label as string,
      }
      if (payload.type === InputVarType.textInput)
        draft[currIndex].max_length = draft[currIndex].max_length || DEFAULT_VALUE_MAX_LEN
      if (payload.type !== InputVarType.select)
        delete draft[currIndex].options
    })
    onPromptVariablesChange?.(newPromptVariables)
  }
  const { setShowExternalDataToolModal } = useModalContext()
  const handleOpenExternalDataToolModal = (
    { key, type, index, name, config, icon, icon_background }: ExternalDataToolParams,
    oldPromptVariables: PromptVariable[],
  ) => {
    setShowExternalDataToolModal({
      payload: {
        type,
        variable: key,
        label: name,
        config,
        icon,
        icon_background,
      },
      onSaveCallback: (newExternalDataTool: ExternalDataTool) => {
        const newPromptVariables = oldPromptVariables.map((item, i) => {
          if (i === index) {
            return {
              key: newExternalDataTool.variable as string,
              name: newExternalDataTool.label as string,
              enabled: newExternalDataTool.enabled,
              type: newExternalDataTool.type as string,
              config: newExternalDataTool.config,
              required: item.required,
              icon: newExternalDataTool.icon,
              icon_background: newExternalDataTool.icon_background,
            }
          }
          return item
        })
        onPromptVariablesChange?.(newPromptVariables)
      },
      onCancelCallback: () => {
        if (!key)
          onPromptVariablesChange?.(promptVariables.filter((_, i) => i !== index))
      },
      onValidateBeforeSaveCallback: (newExternalDataTool: ExternalDataTool) => {
        for (let i = 0; i < promptVariables.length; i++) {
          if (promptVariables[i].key === newExternalDataTool.variable && i !== index) {
            Toast.notify({ type: 'error', message: t('appDebug.varKeyError.keyAlreadyExists', { key: promptVariables[i].key }) })
            return false
          }
        }
        return true
      },
    })
  }
  const handleAddVar = (type: string) => {
    const newVar = getNewVar('', type)
    const newPromptVariables = [...promptVariables, newVar]
    onPromptVariablesChange?.(newPromptVariables)
    if (type === 'api') {
      handleOpenExternalDataToolModal({
        type,
        key: newVar.key,
        name: newVar.name,
        index: promptVariables.length,
      }, newPromptVariables)
    }
  }
  eventEmitter?.useSubscription((v: any) => {
    if (v.type === ADD_EXTERNAL_DATA_TOOL) {
      const payload = v.payload
      onPromptVariablesChange?.([
        ...promptVariables,
        {
          key: payload.variable as string,
          name: payload.label as string,
          enabled: payload.enabled,
          type: payload.type as string,
          config: payload.config,
          required: true,
          icon: payload.icon,
          icon_background: payload.icon_background,
        },
      ])
    }
  })
  const [isShowDeleteContextVarModal, { setTrue: showDeleteContextVarModal, setFalse: hideDeleteContextVarModal }] = useBoolean(false)
  const [removeIndex, setRemoveIndex] = useState<number | null>(null)
  const didRemoveVar = (index: number) => {
    onPromptVariablesChange?.(promptVariables.filter((_, i) => i !== index))
  }
  const handleRemoveVar = (index: number) => {
    const removeVar = promptVariables[index]
    if (mode === AppType.completion && dataSets.length > 0 && removeVar.is_context_var) {
      showDeleteContextVarModal()
      setRemoveIndex(index)
      return
    }
    didRemoveVar(index)
  }
  // const [currKey, setCurrKey] = useState<string | null>(null)
  const [isShowEditModal, { setTrue: showEditModal, setFalse: hideEditModal }] = useBoolean(false)
  const handleConfig = ({ key, type, index, name, config, icon, icon_background }: ExternalDataToolParams) => {
    // setCurrKey(key)
    setCurrIndex(index)
    if (type !== 'string' && type !== 'paragraph' && type !== 'select' && type !== 'number') {
      handleOpenExternalDataToolModal({ key, type, index, name, config, icon, icon_background }, promptVariables)
      return
    }
    showEditModal()
  }
  return (
    <Panel
      className="mt-2"
      title={
        <div className='flex items-center'>
          <div className='mr-1'>{t('appDebug.variableTitle')}</div>
          {!readonly && (
            <Tooltip
              popupContent={
                <div className='w-[180px]'>
                  {t('appDebug.variableTip')}
                </div>
              }
            />
          )}
        </div>
      }
      headerRight={!readonly ? <SelectVarType onChange={handleAddVar} /> : null}
      noBodySpacing
    >
      {!hasVar && (
        <div className='mt-1 px-3 pb-3'>
          <div className='pb-1 pt-2 text-xs text-text-tertiary'>{t('appDebug.notSetVar')}</div>
        </div>
      )}
      {hasVar && (
        <div className='mt-1 px-3 pb-3'>
          {promptVariables.map(({ key, name, type, required, config, icon, icon_background }, index) => (
            <VarItem
              key={index}
              readonly={readonly}
              name={key}
              label={name}
              required={!!required}
              type={type}
              onEdit={() => handleConfig({ type, key, index, name, config, icon, icon_background })}
              onRemove={() => handleRemoveVar(index)}
            />
          ))}
        </div>
      )}
      {isShowEditModal && (
        <EditModal
          payload={currItemToEdit!}
          isShow={isShowEditModal}
          onClose={hideEditModal}
          onConfirm={(item) => {
            updatePromptVariableItem(item)
            hideEditModal()
          }}
          varKeys={promptVariables.map(v => v.key)}
        />
      )}
      {isShowDeleteContextVarModal && (
        <Confirm
          isShow={isShowDeleteContextVarModal}
          title={t('appDebug.feature.dataSet.queryVariable.deleteContextVarTitle', { varName: promptVariables[removeIndex as number]?.name })}
          content={t('appDebug.feature.dataSet.queryVariable.deleteContextVarTip')}
          onConfirm={() => {
            didRemoveVar(removeIndex as number)
            hideDeleteContextVarModal()
          }}
          onCancel={hideDeleteContextVarModal}
        />
      )}
    </Panel>
  )
}
export default React.memo(ConfigVar)
app/components/app/configuration/config-var/input-type-icon.tsx
New file
@@ -0,0 +1,44 @@
'use client'
import React from 'react'
import type { FC } from 'react'
import { ApiConnection } from '@/app/components/base/icons/src/vender/solid/development'
import InputVarTypeIcon from '@/app/components/workflow/nodes/_base/components/input-var-type-icon'
import { InputVarType } from '@/app/components/workflow/types'
export type IInputTypeIconProps = {
  type: 'string' | 'select'
  className: string
}
const IconMap = (type: IInputTypeIconProps['type'], className: string) => {
  const classNames = `w-3.5 h-3.5 ${className}`
  const icons = {
    string: (
      <InputVarTypeIcon type={InputVarType.textInput} className={classNames} />
    ),
    paragraph: (
      <InputVarTypeIcon type={InputVarType.paragraph} className={classNames} />
    ),
    select: (
      <InputVarTypeIcon type={InputVarType.select} className={classNames} />
    ),
    number: (
      <InputVarTypeIcon type={InputVarType.number} className={classNames} />
    ),
    api: (
      <ApiConnection className={classNames} />
    ),
  }
  return icons[type]
}
const InputTypeIcon: FC<IInputTypeIconProps> = ({
  type,
  className,
}) => {
  const Icon = IconMap(type, className)
  return Icon
}
export default React.memo(InputTypeIcon)
app/components/app/configuration/config-var/modal-foot.tsx
New file
@@ -0,0 +1,24 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import Button from '@/app/components/base/button'
export type IModalFootProps = {
  onConfirm: () => void
  onCancel: () => void
}
const ModalFoot: FC<IModalFootProps> = ({
  onConfirm,
  onCancel,
}) => {
  const { t } = useTranslation()
  return (
    <div className='flex justify-end gap-2'>
      <Button onClick={onCancel}>{t('common.operation.cancel')}</Button>
      <Button variant='primary' onClick={onConfirm}>{t('common.operation.save')}</Button>
    </div>
  )
}
export default React.memo(ModalFoot)
app/components/app/configuration/config-var/select-type-item/index.tsx
New file
@@ -0,0 +1,41 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import cn from '@/utils/classnames'
import type { InputVarType } from '@/app/components/workflow/types'
import InputVarTypeIcon from '@/app/components/workflow/nodes/_base/components/input-var-type-icon'
export type ISelectTypeItemProps = {
  type: InputVarType
  selected: boolean
  onClick: () => void
}
const i18nFileTypeMap: Record<string, string> = {
  'file': 'single-file',
  'file-list': 'multi-files',
}
const SelectTypeItem: FC<ISelectTypeItemProps> = ({
  type,
  selected,
  onClick,
}) => {
  const { t } = useTranslation()
  const typeName = t(`appDebug.variableConfig.${i18nFileTypeMap[type] || type}`)
  return (
    <div
      className={cn(
        'flex h-[58px] flex-col items-center justify-center space-y-1 rounded-lg border border-components-option-card-option-border bg-components-option-card-option-bg text-text-secondary',
        selected ? 'system-xs-medium border-[1.5px] border-components-option-card-option-selected-border bg-components-option-card-option-selected-bg shadow-xs' : ' system-xs-regular cursor-pointer hover:border-components-option-card-option-border-hover hover:bg-components-option-card-option-bg-hover hover:shadow-xs')}
      onClick={onClick}
    >
      <div className='shrink-0'>
        <InputVarTypeIcon type={type} className='h-5 w-5' />
      </div>
      <span>{typeName}</span>
    </div>
  )
}
export default React.memo(SelectTypeItem)
app/components/app/configuration/config-var/select-var-type.tsx
New file
@@ -0,0 +1,79 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import cn from '@/utils/classnames'
import OperationBtn from '@/app/components/app/configuration/base/operation-btn'
import {
  PortalToFollowElem,
  PortalToFollowElemContent,
  PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import { ApiConnection } from '@/app/components/base/icons/src/vender/solid/development'
import InputVarTypeIcon from '@/app/components/workflow/nodes/_base/components/input-var-type-icon'
import { InputVarType } from '@/app/components/workflow/types'
type Props = {
  onChange: (value: string) => void
}
type ItemProps = {
  text: string
  value: string
  Icon?: any
  type?: InputVarType
  onClick: (value: string) => void
}
const SelectItem: FC<ItemProps> = ({ text, type, value, Icon, onClick }) => {
  return (
    <div
      className='flex h-8 cursor-pointer items-center rounded-lg px-3 hover:bg-gray-50'
      onClick={() => onClick(value)}
    >
      {Icon ? <Icon className='h-4 w-4 text-gray-500' /> : <InputVarTypeIcon type={type!} className='h-4 w-4 text-gray-500' />}
      <div className='ml-2 truncate text-xs text-gray-600'>{text}</div>
    </div>
  )
}
const SelectVarType: FC<Props> = ({
  onChange,
}) => {
  const { t } = useTranslation()
  const [open, setOpen] = useState(false)
  const handleChange = (value: string) => {
    onChange(value)
    setOpen(false)
  }
  return (
    <PortalToFollowElem
      open={open}
      onOpenChange={setOpen}
      placement='bottom-end'
      offset={{
        mainAxis: 8,
        crossAxis: -2,
      }}
    >
      <PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}>
        <OperationBtn type='add' className={cn(open && 'bg-gray-200')} />
      </PortalToFollowElemTrigger>
      <PortalToFollowElemContent style={{ zIndex: 1000 }}>
        <div className='min-w-[192px] rounded-lg border border-gray-200 bg-white shadow-lg'>
          <div className='p-1'>
            <SelectItem type={InputVarType.textInput} value='string' text={t('appDebug.variableConfig.string')} onClick={handleChange}></SelectItem>
            <SelectItem type={InputVarType.paragraph} value='paragraph' text={t('appDebug.variableConfig.paragraph')} onClick={handleChange}></SelectItem>
            <SelectItem type={InputVarType.select} value='select' text={t('appDebug.variableConfig.select')} onClick={handleChange}></SelectItem>
            <SelectItem type={InputVarType.number} value='number' text={t('appDebug.variableConfig.number')} onClick={handleChange}></SelectItem>
          </div>
          <div className='h-[1px] bg-gray-100'></div>
          <div className='p-1'>
            <SelectItem Icon={ApiConnection} value='api' text={t('appDebug.variableConfig.apiBasedVar')} onClick={handleChange}></SelectItem>
          </div>
        </div>
      </PortalToFollowElemContent>
    </PortalToFollowElem>
  )
}
export default React.memo(SelectVarType)
app/components/app/configuration/config-var/var-item.tsx
New file
@@ -0,0 +1,72 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import {
  RiDeleteBinLine,
  RiEditLine,
} from '@remixicon/react'
import type { IInputTypeIconProps } from './input-type-icon'
import IconTypeIcon from './input-type-icon'
import { BracketsX as VarIcon } from '@/app/components/base/icons/src/vender/line/development'
import Badge from '@/app/components/base/badge'
import cn from '@/utils/classnames'
type ItemProps = {
  readonly?: boolean
  name: string
  label: string
  required: boolean
  type: string
  onEdit: () => void
  onRemove: () => void
}
const VarItem: FC<ItemProps> = ({
  readonly,
  name,
  label,
  required,
  type,
  onEdit,
  onRemove,
}) => {
  const [isDeleting, setIsDeleting] = useState(false)
  return (
    <div className={cn('group relative mb-1 flex h-[34px] w-full items-center  rounded-lg border-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg pl-2.5 pr-3 shadow-xs last-of-type:mb-0 hover:bg-components-panel-on-panel-item-bg-hover hover:shadow-sm', isDeleting && 'border-state-destructive-border hover:bg-state-destructive-hover', readonly && 'cursor-not-allowed opacity-30')}>
      <VarIcon className='mr-1 h-4 w-4 shrink-0 text-text-accent' />
      <div className='flex w-0 grow items-center'>
        <div className='truncate' title={`${name} · ${label}`}>
          <span className='system-sm-medium text-text-secondary'>{name}</span>
          <span className='system-xs-regular px-1 text-text-quaternary'>·</span>
          <span className='system-xs-medium text-text-tertiary'>{label}</span>
        </div>
      </div>
      <div className='shrink-0'>
        <div className={cn('flex items-center', !readonly && 'group-hover:hidden')}>
          {required && <Badge text='required' />}
          <span className='system-xs-regular pl-2 pr-1 text-text-tertiary'>{type}</span>
          <IconTypeIcon type={type as IInputTypeIconProps['type']} className='text-text-tertiary' />
        </div>
        <div className={cn('hidden items-center justify-end rounded-lg', !readonly && 'group-hover:flex')}>
          <div
            className='mr-1 flex h-6 w-6 cursor-pointer items-center justify-center rounded-md hover:bg-black/5'
            onClick={onEdit}
          >
            <RiEditLine className='h-4 w-4 text-text-tertiary' />
          </div>
          <div
            className='flex h-6 w-6 cursor-pointer items-center  justify-center text-text-tertiary hover:text-text-destructive'
            onClick={onRemove}
            onMouseOver={() => setIsDeleting(true)}
            onMouseLeave={() => setIsDeleting(false)}
          >
            <RiDeleteBinLine className='h-4 w-4' />
          </div>
        </div>
      </div>
    </div>
  )
}
export default VarItem
app/components/app/configuration/config-vision/index.tsx
New file
@@ -0,0 +1,112 @@
'use client'
import type { FC } from 'react'
import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import produce from 'immer'
import { useContext } from 'use-context-selector'
import ParamConfig from './param-config'
import { Vision } from '@/app/components/base/icons/src/vender/features'
import Tooltip from '@/app/components/base/tooltip'
// import OptionCard from '@/app/components/workflow/nodes/_base/components/option-card'
import ConfigContext from '@/context/debug-configuration'
// import { Resolution } from '@/types/app'
import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks'
import Switch from '@/app/components/base/switch'
import { SupportUploadFileTypes } from '@/app/components/workflow/types'
const ConfigVision: FC = () => {
  const { t } = useTranslation()
  const { isShowVisionConfig, isAllowVideoUpload } = useContext(ConfigContext)
  const file = useFeatures(s => s.features.file)
  const featuresStore = useFeaturesStore()
  const isImageEnabled = file?.allowed_file_types?.includes(SupportUploadFileTypes.image) ?? false
  const handleChange = useCallback((value: boolean) => {
    const {
      features,
      setFeatures,
    } = featuresStore!.getState()
    const newFeatures = produce(features, (draft) => {
      if (value) {
        draft.file!.allowed_file_types = Array.from(new Set([
          ...(draft.file?.allowed_file_types || []),
          SupportUploadFileTypes.image,
          ...(isAllowVideoUpload ? [SupportUploadFileTypes.video] : []),
        ]))
      }
      else {
        draft.file!.allowed_file_types = draft.file!.allowed_file_types?.filter(
          type => type !== SupportUploadFileTypes.image && (isAllowVideoUpload ? type !== SupportUploadFileTypes.video : true),
        )
      }
      if (draft.file) {
        draft.file.enabled = (draft.file.allowed_file_types?.length ?? 0) > 0
        draft.file.image = {
          ...(draft.file.image || {}),
          enabled: value,
        }
      }
    })
    setFeatures(newFeatures)
  }, [featuresStore, isAllowVideoUpload])
  if (!isShowVisionConfig)
    return null
  return (
    <div className='mt-2 flex items-center gap-2 rounded-xl border-l-[0.5px] border-t-[0.5px] border-effects-highlight bg-background-section-burn p-2'>
      <div className='shrink-0 p-1'>
        <div className='rounded-lg border-[0.5px] border-divider-subtle bg-util-colors-indigo-indigo-600 p-1 shadow-xs'>
          <Vision className='h-4 w-4 text-text-primary-on-surface' />
        </div>
      </div>
      <div className='flex grow items-center'>
        <div className='system-sm-semibold mr-1 text-text-secondary'>{t('appDebug.vision.name')}</div>
        <Tooltip
          popupContent={
            <div className='w-[180px]' >
              {t('appDebug.vision.description')}
            </div>
          }
        />
      </div>
      <div className='flex shrink-0 items-center'>
        {/* <div className='mr-2 flex items-center gap-0.5'>
          <div className='text-text-tertiary system-xs-medium-uppercase'>{t('appDebug.vision.visionSettings.resolution')}</div>
          <Tooltip
            popupContent={
              <div className='w-[180px]' >
                {t('appDebug.vision.visionSettings.resolutionTooltip').split('\n').map(item => (
                  <div key={item}>{item}</div>
                ))}
              </div>
            }
          />
        </div> */}
        {/* <div className='flex items-center gap-1'>
          <OptionCard
            title={t('appDebug.vision.visionSettings.high')}
            selected={file?.image?.detail === Resolution.high}
            onSelect={() => handleChange(Resolution.high)}
          />
          <OptionCard
            title={t('appDebug.vision.visionSettings.low')}
            selected={file?.image?.detail === Resolution.low}
            onSelect={() => handleChange(Resolution.low)}
          />
        </div> */}
        <ParamConfig />
        <div className='ml-1 mr-3 h-3.5 w-[1px] bg-divider-regular'></div>
        <Switch
          defaultValue={isImageEnabled}
          onChange={handleChange}
          size='md'
        />
      </div>
    </div>
  )
}
export default React.memo(ConfigVision)
app/components/app/configuration/config-vision/param-config-content.tsx
New file
@@ -0,0 +1,142 @@
'use client'
import type { FC } from 'react'
import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import produce from 'immer'
import OptionCard from '@/app/components/workflow/nodes/_base/components/option-card'
import { Resolution, TransferMethod } from '@/types/app'
import ParamItem from '@/app/components/base/param-item'
import Tooltip from '@/app/components/base/tooltip'
import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks'
import type { FileUpload } from '@/app/components/base/features/types'
const MIN = 1
const MAX = 6
const ParamConfigContent: FC = () => {
  const { t } = useTranslation()
  const file = useFeatures(s => s.features.file)
  const featuresStore = useFeaturesStore()
  const handleChange = useCallback((data: FileUpload) => {
    const {
      features,
      setFeatures,
    } = featuresStore!.getState()
    const newFeatures = produce(features, (draft) => {
      draft.file = {
        ...draft.file,
        allowed_file_upload_methods: data.allowed_file_upload_methods,
        number_limits: data.number_limits,
        image: {
          enabled: data.enabled,
          detail: data.image?.detail,
          transfer_methods: data.allowed_file_upload_methods,
          number_limits: data.number_limits,
        },
      }
    })
    setFeatures(newFeatures)
  }, [featuresStore])
  return (
    <div>
      <div className='text-base font-semibold leading-6 text-text-primary'>{t('appDebug.vision.visionSettings.title')}</div>
      <div className='space-y-6 pt-3'>
        <div>
          <div className='mb-2 flex items-center  space-x-1'>
            <div className='text-[13px] font-semibold leading-[18px] text-text-secondary'>{t('appDebug.vision.visionSettings.resolution')}</div>
            <Tooltip
              popupContent={
                <div className='w-[180px]' >
                  {t('appDebug.vision.visionSettings.resolutionTooltip').split('\n').map(item => (
                    <div key={item}>{item}</div>
                  ))}
                </div>
              }
            />
          </div>
          <div className='flex items-center gap-1'>
            <OptionCard
              className='grow'
              title={t('appDebug.vision.visionSettings.high')}
              selected={file?.image?.detail === Resolution.high}
              onSelect={() => handleChange({
                ...file,
                image: { detail: Resolution.high },
              })}
            />
            <OptionCard
              className='grow'
              title={t('appDebug.vision.visionSettings.low')}
              selected={file?.image?.detail === Resolution.low}
              onSelect={() => handleChange({
                ...file,
                image: { detail: Resolution.low },
              })}
            />
          </div>
        </div>
        <div>
          <div className='mb-2 text-[13px] font-semibold leading-[18px] text-text-secondary'>{t('appDebug.vision.visionSettings.uploadMethod')}</div>
          <div className='flex items-center gap-1'>
            <OptionCard
              className='grow'
              title={t('appDebug.vision.visionSettings.both')}
              selected={!!file?.allowed_file_upload_methods?.includes(TransferMethod.local_file) && !!file?.allowed_file_upload_methods?.includes(TransferMethod.remote_url)}
              onSelect={() => handleChange({
                ...file,
                allowed_file_upload_methods: [TransferMethod.local_file, TransferMethod.remote_url],
              })}
            />
            <OptionCard
              className='grow'
              title={t('appDebug.vision.visionSettings.localUpload')}
              selected={!!file?.allowed_file_upload_methods?.includes(TransferMethod.local_file) && file?.allowed_file_upload_methods?.length === 1}
              onSelect={() => handleChange({
                ...file,
                allowed_file_upload_methods: [TransferMethod.local_file],
              })}
            />
            <OptionCard
              className='grow'
              title={t('appDebug.vision.visionSettings.url')}
              selected={!!file?.allowed_file_upload_methods?.includes(TransferMethod.remote_url) && file?.allowed_file_upload_methods?.length === 1}
              onSelect={() => handleChange({
                ...file,
                allowed_file_upload_methods: [TransferMethod.remote_url],
              })}
            />
          </div>
        </div>
        <div>
          <ParamItem
            id='upload_limit'
            className=''
            name={t('appDebug.vision.visionSettings.uploadLimit')}
            noTooltip
            {...{
              default: 2,
              step: 1,
              min: MIN,
              max: MAX,
            }}
            value={file?.number_limits || 3}
            enable={true}
            onChange={(_key: string, value: number) => {
              if (!value)
                return
              handleChange({
                ...file,
                number_limits: value,
              })
            }}
          />
        </div>
      </div>
    </div>
  )
}
export default React.memo(ParamConfigContent)
app/components/app/configuration/config-vision/param-config.tsx
New file
@@ -0,0 +1,42 @@
'use client'
import type { FC } from 'react'
import { memo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiSettings2Line } from '@remixicon/react'
import ParamConfigContent from './param-config-content'
import Button from '@/app/components/base/button'
import {
  PortalToFollowElem,
  PortalToFollowElemContent,
  PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import cn from '@/utils/classnames'
const ParamsConfig: FC = () => {
  const { t } = useTranslation()
  const [open, setOpen] = useState(false)
  return (
    <PortalToFollowElem
      open={open}
      onOpenChange={setOpen}
      placement='bottom-end'
      offset={{
        mainAxis: 4,
      }}
    >
      <PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}>
        <Button variant='ghost' size='small' className={cn('')}>
          <RiSettings2Line className='h-3.5 w-3.5' />
          <div className='ml-1'>{t('appDebug.voice.settings')}</div>
        </Button>
      </PortalToFollowElemTrigger>
      <PortalToFollowElemContent style={{ zIndex: 50 }}>
        <div className='w-80 space-y-3 rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg p-4 shadow-lg sm:w-[412px]'>
          <ParamConfigContent />
        </div>
      </PortalToFollowElemContent>
    </PortalToFollowElem>
  )
}
export default memo(ParamsConfig)
app/components/app/configuration/config/agent-setting-button.tsx
New file
@@ -0,0 +1,47 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiSettings2Line } from '@remixicon/react'
import AgentSetting from './agent/agent-setting'
import Button from '@/app/components/base/button'
import type { AgentConfig } from '@/models/debug'
type Props = {
  isFunctionCall: boolean
  isChatModel: boolean
  agentConfig?: AgentConfig
  onAgentSettingChange: (payload: AgentConfig) => void
}
const AgentSettingButton: FC<Props> = ({
  onAgentSettingChange,
  isFunctionCall,
  isChatModel,
  agentConfig,
}) => {
  const { t } = useTranslation()
  const [isShowAgentSetting, setIsShowAgentSetting] = useState(false)
  return (
    <>
      <Button onClick={() => setIsShowAgentSetting(true)} className='mr-2 shrink-0'>
        <RiSettings2Line className='mr-1 h-4 w-4 text-text-tertiary' />
        {t('appDebug.agent.setting.name')}
      </Button>
      {isShowAgentSetting && (
        <AgentSetting
          isFunctionCall={isFunctionCall}
          payload={agentConfig as AgentConfig}
          isChatModel={isChatModel}
          onSave={(payloadNew) => {
            onAgentSettingChange(payloadNew)
            setIsShowAgentSetting(false)
          }}
          onCancel={() => setIsShowAgentSetting(false)}
        />
      )}
    </>
  )
}
export default React.memo(AgentSettingButton)
app/components/app/configuration/config/agent/agent-setting/index.tsx
New file
@@ -0,0 +1,165 @@
'use client'
import type { FC } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiCloseLine } from '@remixicon/react'
import { useClickAway } from 'ahooks'
import ItemPanel from './item-panel'
import Button from '@/app/components/base/button'
import { CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication'
import { Unblur } from '@/app/components/base/icons/src/vender/solid/education'
import Slider from '@/app/components/base/slider'
import type { AgentConfig } from '@/models/debug'
import { DEFAULT_AGENT_PROMPT, MAX_ITERATIONS_NUM } from '@/config'
type Props = {
  isChatModel: boolean
  payload: AgentConfig
  isFunctionCall: boolean
  onCancel: () => void
  onSave: (payload: any) => void
}
const maxIterationsMin = 1
const AgentSetting: FC<Props> = ({
  isChatModel,
  payload,
  isFunctionCall,
  onCancel,
  onSave,
}) => {
  const { t } = useTranslation()
  const [tempPayload, setTempPayload] = useState(payload)
  const ref = useRef(null)
  const [mounted, setMounted] = useState(false)
  useClickAway(() => {
    if (mounted)
      onCancel()
  }, ref)
  useEffect(() => {
    setMounted(true)
  }, [])
  const handleSave = () => {
    onSave(tempPayload)
  }
  return (
    <div className='fixed inset-0 z-[100] flex justify-end overflow-hidden p-2'
      style={{
        backgroundColor: 'rgba(16, 24, 40, 0.20)',
      }}
    >
      <div
        ref={ref}
        className='flex h-full w-[640px] flex-col overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-xl'
      >
        <div className='flex h-14 shrink-0 items-center justify-between border-b border-divider-regular pl-6 pr-5'>
          <div className='flex flex-col text-base font-semibold text-text-primary'>
            <div className='leading-6'>{t('appDebug.agent.setting.name')}</div>
          </div>
          <div className='flex items-center'>
            <div
              onClick={onCancel}
              className='flex h-6 w-6 cursor-pointer items-center justify-center'
            >
              <RiCloseLine className='h-4 w-4 text-text-tertiary' />
            </div>
          </div>
        </div>
        {/* Body */}
        <div className='grow overflow-y-auto border-b p-6 pb-[68px] pt-5' style={{
          borderBottom: 'rgba(0, 0, 0, 0.05)',
        }}>
          {/* Agent Mode */}
          <ItemPanel
            className='mb-4'
            icon={
              <CuteRobot className='h-4 w-4 text-indigo-600' />
            }
            name={t('appDebug.agent.agentMode')}
            description={t('appDebug.agent.agentModeDes')}
          >
            <div className='text-[13px] font-medium leading-[18px] text-text-primary'>{isFunctionCall ? t('appDebug.agent.agentModeType.functionCall') : t('appDebug.agent.agentModeType.ReACT')}</div>
          </ItemPanel>
          <ItemPanel
            className='mb-4'
            icon={
              <Unblur className='h-4 w-4 text-[#FB6514]' />
            }
            name={t('appDebug.agent.setting.maximumIterations.name')}
            description={t('appDebug.agent.setting.maximumIterations.description')}
          >
            <div className='flex items-center'>
              <Slider
                className='mr-3 w-[156px]'
                min={maxIterationsMin}
                max={MAX_ITERATIONS_NUM}
                value={tempPayload.max_iteration}
                onChange={(value) => {
                  setTempPayload({
                    ...tempPayload,
                    max_iteration: value,
                  })
                }}
              />
              <input
                type="number"
                min={maxIterationsMin}
                max={MAX_ITERATIONS_NUM} step={1}
                className="block h-7 w-11 rounded-lg border-0 bg-components-input-bg-normal px-1.5 pl-1 leading-7 text-text-primary placeholder:text-text-tertiary focus:ring-1 focus:ring-inset focus:ring-primary-600"
                value={tempPayload.max_iteration}
                onChange={(e) => {
                  let value = Number.parseInt(e.target.value, 10)
                  if (value < maxIterationsMin)
                    value = maxIterationsMin
                  if (value > MAX_ITERATIONS_NUM)
                    value = MAX_ITERATIONS_NUM
                  setTempPayload({
                    ...tempPayload,
                    max_iteration: value,
                  })
                }} />
            </div>
          </ItemPanel>
          {!isFunctionCall && (
            <div className='rounded-xl bg-background-section-burn py-2 shadow-xs'>
              <div className='flex h-8 items-center px-4 text-sm font-semibold leading-6 text-text-secondary'>{t('tools.builtInPromptTitle')}</div>
              <div className='h-[396px] overflow-y-auto whitespace-pre-line px-4 text-sm font-normal leading-5 text-text-secondary'>
                {isChatModel ? DEFAULT_AGENT_PROMPT.chat : DEFAULT_AGENT_PROMPT.completion}
              </div>
              <div className='px-4'>
                <div className='inline-flex h-5 items-center rounded-md bg-components-input-bg-normal px-1 text-xs font-medium leading-[18px] text-text-tertiary'>{(isChatModel ? DEFAULT_AGENT_PROMPT.chat : DEFAULT_AGENT_PROMPT.completion).length}</div>
              </div>
            </div>
          )}
        </div>
        <div
          className='sticky bottom-0 z-[5] flex w-full justify-end border-t border-divider-regular bg-background-section-burn px-6 py-4'
        >
          <Button
            onClick={onCancel}
            className='mr-2'
          >
            {t('common.operation.cancel')}
          </Button>
          <Button
            variant='primary'
            onClick={handleSave}
          >
            {t('common.operation.save')}
          </Button>
        </div>
      </div>
    </div>
  )
}
export default React.memo(AgentSetting)
app/components/app/configuration/config/agent/agent-setting/item-panel.tsx
New file
@@ -0,0 +1,41 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import cn from '@/utils/classnames'
import Tooltip from '@/app/components/base/tooltip'
type Props = {
  className?: string
  icon: React.JSX.Element
  name: string
  description: string
  children: React.JSX.Element
}
const ItemPanel: FC<Props> = ({
  className,
  icon,
  name,
  description,
  children,
}) => {
  return (
    <div className={cn(className, 'flex h-12 items-center justify-between rounded-lg bg-background-section-burn px-3')}>
      <div className='flex items-center'>
        {icon}
        <div className='ml-3 mr-1 text-sm font-semibold leading-6 text-text-secondary'>{name}</div>
        <Tooltip
          popupContent={
            <div className='w-[180px]'>
              {description}
            </div>
          }
        >
        </Tooltip>
      </div>
      <div>
        {children}
      </div>
    </div>
  )
}
export default React.memo(ItemPanel)
app/components/app/configuration/config/agent/agent-tools/index.tsx
New file
@@ -0,0 +1,302 @@
'use client'
import type { FC } from 'react'
import React, { useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import copy from 'copy-to-clipboard'
import produce from 'immer'
import {
  RiDeleteBinLine,
  RiEqualizer2Line,
  RiInformation2Line,
} from '@remixicon/react'
import { useFormattingChangedDispatcher } from '../../../debug/hooks'
import SettingBuiltInTool from './setting-built-in-tool'
import Panel from '@/app/components/app/configuration/base/feature-panel'
import OperationBtn from '@/app/components/app/configuration/base/operation-btn'
import AppIcon from '@/app/components/base/app-icon'
import Button from '@/app/components/base/button'
import Indicator from '@/app/components/header/indicator'
import Switch from '@/app/components/base/switch'
import Toast from '@/app/components/base/toast'
import ConfigContext from '@/context/debug-configuration'
import type { AgentTool } from '@/types/app'
import { type Collection, CollectionType } from '@/app/components/tools/types'
import { MAX_TOOLS_NUM } from '@/config'
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
import Tooltip from '@/app/components/base/tooltip'
import { DefaultToolIcon } from '@/app/components/base/icons/src/public/other'
import ConfigCredential from '@/app/components/tools/setting/build-in/config-credentials'
import { updateBuiltInToolCredential } from '@/service/tools'
import cn from '@/utils/classnames'
import ToolPicker from '@/app/components/workflow/block-selector/tool-picker'
import type { ToolDefaultValue } from '@/app/components/workflow/block-selector/types'
import { canFindTool } from '@/utils'
type AgentToolWithMoreInfo = AgentTool & { icon: any; collection?: Collection } | null
const AgentTools: FC = () => {
  const { t } = useTranslation()
  const [isShowChooseTool, setIsShowChooseTool] = useState(false)
  const { modelConfig, setModelConfig, collectionList } = useContext(ConfigContext)
  const formattingChangedDispatcher = useFormattingChangedDispatcher()
  const [currentTool, setCurrentTool] = useState<AgentToolWithMoreInfo>(null)
  const currentCollection = useMemo(() => {
    if (!currentTool) return null
    const collection = collectionList.find(collection => canFindTool(collection.id, currentTool?.provider_id) && collection.type === currentTool?.provider_type)
    return collection
  }, [currentTool, collectionList])
  const [isShowSettingTool, setIsShowSettingTool] = useState(false)
  const [isShowSettingAuth, setShowSettingAuth] = useState(false)
  const tools = (modelConfig?.agentConfig?.tools as AgentTool[] || []).map((item) => {
    const collection = collectionList.find(
      collection =>
        canFindTool(collection.id, item.provider_id)
        && collection.type === item.provider_type,
    )
    const icon = collection?.icon
    return {
      ...item,
      icon,
      collection,
    }
  })
  const handleToolSettingChange = (value: Record<string, any>) => {
    const newModelConfig = produce(modelConfig, (draft) => {
      const tool = (draft.agentConfig.tools).find((item: any) => item.provider_id === currentTool?.collection?.id && item.tool_name === currentTool?.tool_name)
      if (tool)
        (tool as AgentTool).tool_parameters = value
    })
    setModelConfig(newModelConfig)
    setIsShowSettingTool(false)
    formattingChangedDispatcher()
  }
  const handleToolAuthSetting = (value: AgentToolWithMoreInfo) => {
    const newModelConfig = produce(modelConfig, (draft) => {
      const tool = (draft.agentConfig.tools).find((item: any) => item.provider_id === value?.collection?.id && item.tool_name === value?.tool_name)
      if (tool)
        (tool as AgentTool).notAuthor = false
    })
    setModelConfig(newModelConfig)
    setIsShowSettingTool(false)
    formattingChangedDispatcher()
  }
  const [isDeleting, setIsDeleting] = useState<number>(-1)
  const handleSelectTool = (tool: ToolDefaultValue) => {
    const newModelConfig = produce(modelConfig, (draft) => {
      draft.agentConfig.tools.push({
        provider_id: tool.provider_id,
        provider_type: tool.provider_type as CollectionType,
        provider_name: tool.provider_name,
        tool_name: tool.tool_name,
        tool_label: tool.tool_label,
        tool_parameters: tool.params,
        notAuthor: !tool.is_team_authorization,
        enabled: true,
      })
    })
    setModelConfig(newModelConfig)
  }
  return (
    <>
      <Panel
        className={cn('mt-2', tools.length === 0 && 'pb-2')}
        noBodySpacing={tools.length === 0}
        title={
          <div className='flex items-center'>
            <div className='mr-1'>{t('appDebug.agent.tools.name')}</div>
            <Tooltip
              popupContent={
                <div className='w-[180px]'>
                  {t('appDebug.agent.tools.description')}
                </div>
              }
            />
          </div>
        }
        headerRight={
          <div className='flex items-center'>
            <div className='text-xs font-normal leading-[18px] text-text-tertiary'>{tools.filter(item => !!item.enabled).length}/{tools.length}&nbsp;{t('appDebug.agent.tools.enabled')}</div>
            {tools.length < MAX_TOOLS_NUM && (
              <>
                <div className='ml-3 mr-1 h-3.5 w-px bg-divider-regular'></div>
                <ToolPicker
                  trigger={<OperationBtn type="add" />}
                  isShow={isShowChooseTool}
                  onShowChange={setIsShowChooseTool}
                  disabled={false}
                  supportAddCustomTool
                  onSelect={handleSelectTool}
                  selectedTools={tools}
                />
              </>
            )}
          </div>
        }
      >
        <div className='grid grid-cols-1 flex-wrap items-center justify-between gap-1 2xl:grid-cols-2'>
          {tools.map((item: AgentTool & { icon: any; collection?: Collection }, index) => (
            <div key={index}
              className={cn(
                'cursor group relative flex w-full items-center justify-between rounded-lg border-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg p-1.5 pr-2 shadow-xs last-of-type:mb-0 hover:bg-components-panel-on-panel-item-bg-hover hover:shadow-sm',
                isDeleting === index && 'border-state-destructive-border hover:bg-state-destructive-hover',
              )}
            >
              <div className='flex w-0 grow items-center'>
                {item.isDeleted && <DefaultToolIcon className='h-5 w-5' />}
                {!item.isDeleted && (
                  <div className={cn((item.notAuthor || !item.enabled) && 'opacity-50')}>
                    {typeof item.icon === 'string' && <div className='h-5 w-5 rounded-md bg-cover bg-center' style={{ backgroundImage: `url(${item.icon})` }} />}
                    {typeof item.icon !== 'string' && <AppIcon className='rounded-md' size='xs' icon={item.icon?.content} background={item.icon?.background} />}
                  </div>
                )}
                <div
                  className={cn(
                    'system-xs-regular ml-1.5 flex w-0 grow items-center truncate',
                    (item.isDeleted || item.notAuthor || !item.enabled) ? 'opacity-50' : '',
                  )}
                >
                  <span className='system-xs-medium pr-1.5 text-text-secondary'>{item.provider_type === CollectionType.builtIn ? item.provider_name.split('/').pop() : item.tool_label}</span>
                  <span className='text-text-tertiary'>{item.tool_label}</span>
                  {!item.isDeleted && (
                    <Tooltip
                      needsDelay
                      popupContent={
                        <div className='w-[180px]'>
                          <div className='mb-1.5 text-text-secondary'>{item.tool_name}</div>
                          <div className='mb-1.5 text-text-tertiary'>{t('tools.toolNameUsageTip')}</div>
                          <div className='cursor-pointer text-text-accent' onClick={() => copy(item.tool_name)}>{t('tools.copyToolName')}</div>
                        </div>
                      }
                    >
                      <div className='h-4 w-4'>
                        <div className='ml-0.5 hidden group-hover:inline-block'>
                          <RiInformation2Line className='h-4 w-4 text-text-tertiary' />
                        </div>
                      </div>
                    </Tooltip>
                  )}
                </div>
              </div>
              <div className='ml-1 flex shrink-0 items-center'>
                {item.isDeleted && (
                  <div className='mr-2 flex items-center'>
                    <Tooltip
                      popupContent={t('tools.toolRemoved')}
                      needsDelay
                    >
                      <div className='mr-1 cursor-pointer rounded-md p-1 hover:bg-black/5'>
                        <AlertTriangle className='h-4 w-4 text-[#F79009]' />
                      </div>
                    </Tooltip>
                    <div
                      className='cursor-pointer rounded-md p-1 text-text-tertiary hover:text-text-destructive'
                      onClick={() => {
                        const newModelConfig = produce(modelConfig, (draft) => {
                          draft.agentConfig.tools.splice(index, 1)
                        })
                        setModelConfig(newModelConfig)
                        formattingChangedDispatcher()
                      }}
                      onMouseOver={() => setIsDeleting(index)}
                      onMouseLeave={() => setIsDeleting(-1)}
                    >
                      <RiDeleteBinLine className='h-4 w-4' />
                    </div>
                  </div>
                )}
                {!item.isDeleted && (
                  <div className='mr-2 hidden items-center gap-1 group-hover:flex'>
                    {!item.notAuthor && (
                      <Tooltip
                        popupContent={t('tools.setBuiltInTools.infoAndSetting')}
                        needsDelay
                      >
                        <div className='cursor-pointer rounded-md p-1  hover:bg-black/5' onClick={() => {
                          setCurrentTool(item)
                          setIsShowSettingTool(true)
                        }}>
                          <RiEqualizer2Line className='h-4 w-4 text-text-tertiary' />
                        </div>
                      </Tooltip>
                    )}
                    <div
                      className='cursor-pointer rounded-md p-1 text-text-tertiary hover:text-text-destructive'
                      onClick={() => {
                        const newModelConfig = produce(modelConfig, (draft) => {
                          draft.agentConfig.tools.splice(index, 1)
                        })
                        setModelConfig(newModelConfig)
                        formattingChangedDispatcher()
                      }}
                      onMouseOver={() => setIsDeleting(index)}
                      onMouseLeave={() => setIsDeleting(-1)}
                    >
                      <RiDeleteBinLine className='h-4 w-4' />
                    </div>
                  </div>
                )}
                <div className={cn(item.isDeleted && 'opacity-50')}>
                  {!item.notAuthor && (
                    <Switch
                      defaultValue={item.isDeleted ? false : item.enabled}
                      disabled={item.isDeleted}
                      size='md'
                      onChange={(enabled) => {
                        const newModelConfig = produce(modelConfig, (draft) => {
                          (draft.agentConfig.tools[index] as any).enabled = enabled
                        })
                        setModelConfig(newModelConfig)
                        formattingChangedDispatcher()
                      }} />
                  )}
                  {item.notAuthor && (
                    <Button variant='secondary' size='small' onClick={() => {
                      setCurrentTool(item)
                      setShowSettingAuth(true)
                    }}>
                      {t('tools.notAuthorized')}
                      <Indicator className='ml-2' color='orange' />
                    </Button>
                  )}
                </div>
              </div>
            </div>
          ))}
        </div >
      </Panel >
      {isShowSettingTool && (
        <SettingBuiltInTool
          toolName={currentTool?.tool_name as string}
          setting={currentTool?.tool_parameters}
          collection={currentTool?.collection as Collection}
          isBuiltIn={currentTool?.collection?.type === CollectionType.builtIn}
          isModel={currentTool?.collection?.type === CollectionType.model}
          onSave={handleToolSettingChange}
          onHide={() => setIsShowSettingTool(false)}
        />
      )}
      {isShowSettingAuth && (
        <ConfigCredential
          collection={currentCollection as any}
          onCancel={() => setShowSettingAuth(false)}
          onSaved={async (value) => {
            await updateBuiltInToolCredential((currentCollection as any).name, value)
            Toast.notify({
              type: 'success',
              message: t('common.api.actionSuccess'),
            })
            handleToolAuthSetting(currentTool)
            setShowSettingAuth(false)
          }}
        />
      )}
    </>
  )
}
export default React.memo(AgentTools)
app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx
New file
@@ -0,0 +1,238 @@
'use client'
import type { FC } from 'react'
import React, { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import {
  RiArrowLeftLine,
  RiCloseLine,
} from '@remixicon/react'
import Drawer from '@/app/components/base/drawer'
import Loading from '@/app/components/base/loading'
import ActionButton from '@/app/components/base/action-button'
import Icon from '@/app/components/plugins/card/base/card-icon'
import OrgInfo from '@/app/components/plugins/card/base/org-info'
import Description from '@/app/components/plugins/card/base/description'
import TabSlider from '@/app/components/base/tab-slider-plain'
import Button from '@/app/components/base/button'
import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form'
import { addDefaultValue, toolParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema'
import type { Collection, Tool } from '@/app/components/tools/types'
import { CollectionType } from '@/app/components/tools/types'
import { fetchBuiltInToolList, fetchCustomToolList, fetchModelToolList, fetchWorkflowToolList } from '@/service/tools'
import I18n from '@/context/i18n'
import { getLanguage } from '@/i18n/language'
import cn from '@/utils/classnames'
type Props = {
  showBackButton?: boolean
  collection: Collection
  isBuiltIn?: boolean
  isModel?: boolean
  toolName: string
  setting?: Record<string, any>
  readonly?: boolean
  onHide: () => void
  onSave?: (value: Record<string, any>) => void
}
const SettingBuiltInTool: FC<Props> = ({
  showBackButton = false,
  collection,
  isBuiltIn = true,
  isModel = true,
  toolName,
  setting = {},
  readonly,
  onHide,
  onSave,
}) => {
  const { locale } = useContext(I18n)
  const language = getLanguage(locale)
  const { t } = useTranslation()
  const [isLoading, setIsLoading] = useState(true)
  const [tools, setTools] = useState<Tool[]>([])
  const currTool = tools.find(tool => tool.name === toolName)
  const formSchemas = currTool ? toolParametersToFormSchemas(currTool.parameters) : []
  const infoSchemas = formSchemas.filter(item => item.form === 'llm')
  const settingSchemas = formSchemas.filter(item => item.form !== 'llm')
  const hasSetting = settingSchemas.length > 0
  const [tempSetting, setTempSetting] = useState(setting)
  const [currType, setCurrType] = useState('info')
  const isInfoActive = currType === 'info'
  useEffect(() => {
    if (!collection)
      return
    (async () => {
      setIsLoading(true)
      try {
        const list = await new Promise<Tool[]>((resolve) => {
          (async function () {
            if (isModel)
              resolve(await fetchModelToolList(collection.name))
            else if (isBuiltIn)
              resolve(await fetchBuiltInToolList(collection.name))
            else if (collection.type === CollectionType.workflow)
              resolve(await fetchWorkflowToolList(collection.id))
            else
              resolve(await fetchCustomToolList(collection.name))
          }())
        })
        setTools(list)
        const currTool = list.find(tool => tool.name === toolName)
        if (currTool) {
          const formSchemas = toolParametersToFormSchemas(currTool.parameters)
          setTempSetting(addDefaultValue(setting, formSchemas))
        }
      }
      catch { }
      setIsLoading(false)
    })()
  }, [collection?.name, collection?.id, collection?.type])
  useEffect(() => {
    setCurrType((!readonly && hasSetting) ? 'setting' : 'info')
  }, [hasSetting])
  const isValid = (() => {
    let valid = true
    settingSchemas.forEach((item) => {
      if (item.required && !tempSetting[item.name])
        valid = false
    })
    return valid
  })()
  const getType = (type: string) => {
    if (type === 'number-input')
      return t('tools.setBuiltInTools.number')
    if (type === 'text-input')
      return t('tools.setBuiltInTools.string')
    if (type === 'file')
      return t('tools.setBuiltInTools.file')
    return type
  }
  const infoUI = (
    <div className=''>
      {infoSchemas.length > 0 && (
        <div className='space-y-1 py-2'>
          {infoSchemas.map((item, index) => (
            <div key={index} className='py-1'>
              <div className='flex items-center gap-2'>
                <div className='code-sm-semibold text-text-secondary'>{item.label[language]}</div>
                <div className='system-xs-regular text-text-tertiary'>
                  {getType(item.type)}
                </div>
                {item.required && (
                  <div className='system-xs-medium text-text-warning-secondary'>{t('tools.setBuiltInTools.required')}</div>
                )}
              </div>
              {item.human_description && (
                <div className='system-xs-regular mt-0.5 text-text-tertiary'>
                  {item.human_description?.[language]}
                </div>
              )}
            </div>
          ))}
        </div>
      )}
    </div>
  )
  const settingUI = (
    <Form
      value={tempSetting}
      onChange={setTempSetting}
      formSchemas={settingSchemas}
      isEditMode={false}
      showOnVariableMap={{}}
      validating={false}
      readonly={readonly}
    />
  )
  return (
    <Drawer
      isOpen
      clickOutsideNotOpen={false}
      onClose={onHide}
      footer={null}
      mask={false}
      positionCenter={false}
      panelClassName={cn('mb-2 mr-2 mt-[64px] !w-[420px] !max-w-[420px] justify-start rounded-2xl border-[0.5px] border-components-panel-border !bg-components-panel-bg !p-0 shadow-xl')}
    >
      <>
        {isLoading && <Loading type='app' />}
        {!isLoading && (
          <>
            {/* header */}
            <div className='relative border-b border-divider-subtle p-4 pb-3'>
              <div className='absolute right-3 top-3'>
                <ActionButton onClick={onHide}>
                  <RiCloseLine className='h-4 w-4' />
                </ActionButton>
              </div>
              {showBackButton && (
                <div
                  className='system-xs-semibold-uppercase mb-2 flex cursor-pointer items-center gap-1 text-text-accent-secondary'
                  onClick={onHide}
                >
                  <RiArrowLeftLine className='h-4 w-4' />
                  BACK
                </div>
              )}
              <div className='flex items-center gap-1'>
                <Icon size='tiny' className='h-6 w-6' src={collection.icon} />
                <OrgInfo
                  packageNameClassName='w-auto'
                  orgName={collection.author}
                  packageName={collection.name.split('/').pop() || ''}
                />
              </div>
              <div className='system-md-semibold mt-1 text-text-primary'>{currTool?.label[language]}</div>
              {!!currTool?.description[language] && (
                <Description className='mt-3' text={currTool.description[language]} descriptionLineRows={2}></Description>
              )}
            </div>
            {/* form */}
            <div className='h-full'>
              <div className='flex h-full flex-col'>
                {(hasSetting && !readonly) ? (
                  <TabSlider
                    className='mt-1 shrink-0 px-4'
                    itemClassName='py-3'
                    noBorderBottom
                    value={currType}
                    onChange={(value) => {
                      setCurrType(value)
                    }}
                    options={[
                      { value: 'info', text: t('tools.setBuiltInTools.parameters')! },
                      { value: 'setting', text: t('tools.setBuiltInTools.setting')! },
                    ]}
                  />
                ) : (
                  <div className='system-sm-semibold-uppercase p-4 pb-1 text-text-primary'>{t('tools.setBuiltInTools.parameters')}</div>
                )}
                <div className='h-0 grow overflow-y-auto px-4'>
                  {isInfoActive ? infoUI : settingUI}
                </div>
                {!readonly && !isInfoActive && (
                  <div className='mt-2 flex shrink-0 justify-end space-x-2 rounded-b-[10px]  border-t border-divider-regular bg-components-panel-bg px-6 py-4'>
                    <Button className='flex h-8 items-center !px-3 !text-[13px] font-medium ' onClick={onHide}>{t('common.operation.cancel')}</Button>
                    <Button className='flex h-8 items-center !px-3 !text-[13px] font-medium' variant='primary' disabled={!isValid} onClick={() => onSave?.(addDefaultValue(tempSetting, formSchemas))}>{t('common.operation.save')}</Button>
                  </div>
                )}
              </div>
            </div>
          </>
        )}
      </>
    </Drawer>
  )
}
export default React.memo(SettingBuiltInTool)
app/components/app/configuration/config/agent/prompt-editor.tsx
New file
@@ -0,0 +1,149 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import copy from 'copy-to-clipboard'
import { useContext } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import cn from '@/utils/classnames'
import {
  Clipboard,
  ClipboardCheck,
} from '@/app/components/base/icons/src/vender/line/files'
import PromptEditor from '@/app/components/base/prompt-editor'
import type { ExternalDataTool } from '@/models/common'
import ConfigContext from '@/context/debug-configuration'
import { useModalContext } from '@/context/modal-context'
import { useToastContext } from '@/app/components/base/toast'
import s from '@/app/components/app/configuration/config-prompt/style.module.css'
import { noop } from 'lodash-es'
type Props = {
  className?: string
  type: 'first-prompt' | 'next-iteration'
  value: string
  onChange: (value: string) => void
}
const Editor: FC<Props> = ({
  className,
  type,
  value,
  onChange,
}) => {
  const { t } = useTranslation()
  const { notify } = useToastContext()
  const [isCopied, setIsCopied] = React.useState(false)
  const {
    modelConfig,
    hasSetBlockStatus,
    dataSets,
    showSelectDataSet,
    externalDataToolsConfig,
    setExternalDataToolsConfig,
  } = useContext(ConfigContext)
  const promptVariables = modelConfig.configs.prompt_variables
  const { setShowExternalDataToolModal } = useModalContext()
  const isFirstPrompt = type === 'first-prompt'
  const editorHeight = isFirstPrompt ? 'h-[336px]' : 'h-[52px]'
  const handleOpenExternalDataToolModal = () => {
    setShowExternalDataToolModal({
      payload: {},
      onSaveCallback: (newExternalDataTool: ExternalDataTool) => {
        setExternalDataToolsConfig([...externalDataToolsConfig, newExternalDataTool])
      },
      onValidateBeforeSaveCallback: (newExternalDataTool: ExternalDataTool) => {
        for (let i = 0; i < promptVariables.length; i++) {
          if (promptVariables[i].key === newExternalDataTool.variable) {
            notify({ type: 'error', message: t('appDebug.varKeyError.keyAlreadyExists', { key: promptVariables[i].key }) })
            return false
          }
        }
        for (let i = 0; i < externalDataToolsConfig.length; i++) {
          if (externalDataToolsConfig[i].variable === newExternalDataTool.variable) {
            notify({ type: 'error', message: t('appDebug.varKeyError.keyAlreadyExists', { key: externalDataToolsConfig[i].variable }) })
            return false
          }
        }
        return true
      },
    })
  }
  return (
    <div className={cn(className, s.gradientBorder, 'relative')}>
      <div className='rounded-xl bg-white'>
        <div className={cn(s.boxHeader, 'flex h-11 items-center justify-between rounded-tl-xl rounded-tr-xl bg-white pb-1 pl-4 pr-3 pt-2 hover:shadow-xs')}>
          <div className='text-sm font-semibold uppercase text-indigo-800'>{t(`appDebug.agent.${isFirstPrompt ? 'firstPrompt' : 'nextIteration'}`)}</div>
          <div className={cn(s.optionWrap, 'items-center space-x-1')}>
            {!isCopied
              ? (
                <Clipboard className='h-6 w-6 cursor-pointer p-1 text-gray-500' onClick={() => {
                  copy(value)
                  setIsCopied(true)
                }} />
              )
              : (
                <ClipboardCheck className='h-6 w-6 p-1 text-gray-500' />
              )}
          </div>
        </div>
        <div className={cn(editorHeight, ' min-h-[102px] overflow-y-auto px-4 text-sm text-gray-700')}>
          <PromptEditor
            className={editorHeight}
            value={value}
            contextBlock={{
              show: true,
              selectable: !hasSetBlockStatus.context,
              datasets: dataSets.map(item => ({
                id: item.id,
                name: item.name,
                type: item.data_source_type,
              })),
              onAddContext: showSelectDataSet,
            }}
            variableBlock={{
              show: true,
              variables: modelConfig.configs.prompt_variables.map(item => ({
                name: item.name,
                value: item.key,
              })),
            }}
            externalToolBlock={{
              show: true,
              externalTools: externalDataToolsConfig.map(item => ({
                name: item.label!,
                variableName: item.variable!,
                icon: item.icon,
                icon_background: item.icon_background,
              })),
              onAddExternalTool: handleOpenExternalDataToolModal,
            }}
            historyBlock={{
              show: false,
              selectable: false,
              history: {
                user: '',
                assistant: '',
              },
              onEditRole: noop,
            }}
            queryBlock={{
              show: false,
              selectable: false,
            }}
            onChange={onChange}
            onBlur={noop}
          />
        </div>
        <div className='flex pb-2 pl-4'>
          <div className="h-[18px] rounded-md bg-gray-100 px-1 text-xs leading-[18px] text-gray-500">{value.length}</div>
        </div>
      </div>
    </div>
  )
}
export default React.memo(Editor)
app/components/app/configuration/config/assistant-type-picker/index.tsx
New file
@@ -0,0 +1,165 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { RiArrowDownSLine } from '@remixicon/react'
import AgentSetting from '../agent/agent-setting'
import cn from '@/utils/classnames'
import {
  PortalToFollowElem,
  PortalToFollowElemContent,
  PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import { BubbleText } from '@/app/components/base/icons/src/vender/solid/education'
import Radio from '@/app/components/base/radio/ui'
import { CuteRobot } from '@/app/components/base/icons/src/vender/solid/communication'
import { Settings04 } from '@/app/components/base/icons/src/vender/line/general'
import { ArrowUpRight } from '@/app/components/base/icons/src/vender/line/arrows'
import type { AgentConfig } from '@/models/debug'
type Props = {
  value: string
  disabled: boolean
  onChange: (value: string) => void
  isFunctionCall: boolean
  isChatModel: boolean
  agentConfig?: AgentConfig
  onAgentSettingChange: (payload: AgentConfig) => void
}
type ItemProps = {
  text: string
  disabled: boolean
  value: string
  isChecked: boolean
  description: string
  Icon: any
  onClick: (value: string) => void
}
const SelectItem: FC<ItemProps> = ({ text, value, Icon, isChecked, description, onClick, disabled }) => {
  return (
    <div
      className={cn(disabled ? 'opacity-50' : 'cursor-pointer', isChecked ? 'border-[2px] border-indigo-600 shadow-sm' : 'border border-gray-100', 'mb-2 rounded-xl bg-gray-25 p-3 pr-4 hover:bg-gray-50')}
      onClick={() => !disabled && onClick(value)}
    >
      <div className='flex items-center justify-between'>
        <div className='flex items-center '>
          <div className='mr-3 rounded-lg bg-indigo-50 p-1'>
            <Icon className='h-4 w-4 text-indigo-600' />
          </div>
          <div className='text-sm font-medium leading-5 text-gray-900'>{text}</div>
        </div>
        <Radio isChecked={isChecked} />
      </div>
      <div className='ml-9 text-xs font-normal leading-[18px] text-gray-500'>{description}</div>
    </div>
  )
}
const AssistantTypePicker: FC<Props> = ({
  value,
  disabled,
  onChange,
  onAgentSettingChange,
  isFunctionCall,
  isChatModel,
  agentConfig,
}) => {
  const { t } = useTranslation()
  const [open, setOpen] = useState(false)
  const handleChange = (chosenValue: string) => {
    if (value === chosenValue)
      return
    onChange(chosenValue)
    if (chosenValue !== 'agent')
      setOpen(false)
  }
  const isAgent = value === 'agent'
  const [isShowAgentSetting, setIsShowAgentSetting] = useState(false)
  const agentConfigUI = (
    <>
      <div className='my-4 h-[1px] bg-gray-100'></div>
      <div
        className={cn(isAgent ? 'group cursor-pointer hover:bg-primary-50' : 'opacity-30', 'rounded-xl bg-gray-50 p-3 pr-4 ')}
        onClick={() => {
          if (isAgent) {
            setOpen(false)
            setIsShowAgentSetting(true)
          }
        }}
      >
        <div className='flex items-center justify-between'>
          <div className='flex items-center '>
            <div className='mr-3 rounded-lg bg-gray-200 p-1 group-hover:bg-white'>
              <Settings04 className='h-4 w-4 text-gray-600 group-hover:text-[#155EEF]' />
            </div>
            <div className='text-sm font-medium leading-5 text-gray-900 group-hover:text-[#155EEF]'>{t('appDebug.agent.setting.name')}</div>
          </div>
          <ArrowUpRight className='h-4 w-4 text-gray-500 group-hover:text-[#155EEF]' />
        </div>
        <div className='ml-9 text-xs font-normal leading-[18px] text-gray-500'>{t('appDebug.agent.setting.description')}</div>
      </div>
    </>
  )
  return (
    <>
      <PortalToFollowElem
        open={open}
        onOpenChange={setOpen}
        placement='bottom-end'
        offset={{
          mainAxis: 8,
          crossAxis: -2,
        }}
      >
        <PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}>
          <div className={cn(open && 'bg-gray-50', 'flex h-8 cursor-pointer select-none items-center space-x-1 rounded-lg border border-black/5 px-3 text-indigo-600')}>
            {isAgent ? <BubbleText className='h-3 w-3' /> : <CuteRobot className='h-3 w-3' />}
            <div className='text-xs font-medium'>{t(`appDebug.assistantType.${isAgent ? 'agentAssistant' : 'chatAssistant'}.name`)}</div>
            <RiArrowDownSLine className='h-3 w-3' />
          </div>
        </PortalToFollowElemTrigger>
        <PortalToFollowElemContent style={{ zIndex: 1000 }}>
          <div className='relative left-0.5 w-[480px] rounded-xl border border-black/8 bg-white p-6 shadow-lg'>
            <div className='mb-2 text-sm font-semibold leading-5 text-gray-900'>{t('appDebug.assistantType.name')}</div>
            <SelectItem
              Icon={BubbleText}
              value='chat'
              disabled={disabled}
              text={t('appDebug.assistantType.chatAssistant.name')}
              description={t('appDebug.assistantType.chatAssistant.description')}
              isChecked={!isAgent}
              onClick={handleChange}
            />
            <SelectItem
              Icon={CuteRobot}
              value='agent'
              disabled={disabled}
              text={t('appDebug.assistantType.agentAssistant.name')}
              description={t('appDebug.assistantType.agentAssistant.description')}
              isChecked={isAgent}
              onClick={handleChange}
            />
            {!disabled && agentConfigUI}
          </div>
        </PortalToFollowElemContent>
      </PortalToFollowElem>
      {isShowAgentSetting && (
        <AgentSetting
          isFunctionCall={isFunctionCall}
          payload={agentConfig as AgentConfig}
          isChatModel={isChatModel}
          onSave={(payloadNew) => {
            onAgentSettingChange(payloadNew)
            setIsShowAgentSetting(false)
          }}
          onCancel={() => setIsShowAgentSetting(false)}
        />
      )}
    </>
  )
}
export default React.memo(AssistantTypePicker)
app/components/app/configuration/config/automatic/automatic-btn.tsx
New file
@@ -0,0 +1,25 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import {
  RiSparklingFill,
} from '@remixicon/react'
import Button from '@/app/components/base/button'
export type IAutomaticBtnProps = {
  onClick: () => void
}
const AutomaticBtn: FC<IAutomaticBtnProps> = ({
  onClick,
}) => {
  const { t } = useTranslation()
  return (
    <Button variant='secondary-accent' size='small' onClick={onClick}>
      <RiSparklingFill className='mr-1 h-3.5 w-3.5' />
      <span className=''>{t('appDebug.operation.automatic')}</span>
    </Button>
  )
}
export default React.memo(AutomaticBtn)
app/components/app/configuration/config/automatic/get-automatic-res.tsx
New file
@@ -0,0 +1,330 @@
'use client'
import type { FC } from 'react'
import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import {
  RiDatabase2Line,
  RiFileExcel2Line,
  RiGitCommitLine,
  RiNewspaperLine,
  RiPresentationLine,
  RiRoadMapLine,
  RiTerminalBoxLine,
  RiTranslate,
  RiUser2Line,
} from '@remixicon/react'
import cn from 'classnames'
import s from './style.module.css'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import Textarea from '@/app/components/base/textarea'
import Toast from '@/app/components/base/toast'
import { generateRule } from '@/service/debug'
import ConfigPrompt from '@/app/components/app/configuration/config-prompt'
import type { Model } from '@/types/app'
import { AppType } from '@/types/app'
import ConfigVar from '@/app/components/app/configuration/config-var'
import GroupName from '@/app/components/app/configuration/base/group-name'
import Loading from '@/app/components/base/loading'
import Confirm from '@/app/components/base/confirm'
import { LoveMessage } from '@/app/components/base/icons/src/vender/features'
// type
import type { AutomaticRes } from '@/service/debug'
import { Generator } from '@/app/components/base/icons/src/vender/other'
import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon'
import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
export type IGetAutomaticResProps = {
  mode: AppType
  model: Model
  isShow: boolean
  onClose: () => void
  onFinished: (res: AutomaticRes) => void
  isInLLMNode?: boolean
}
const TryLabel: FC<{
  Icon: any
  text: string
  onClick: () => void
}> = ({ Icon, text, onClick }) => {
  return (
    <div
      className='mr-1 mt-2 flex h-7 shrink-0 cursor-pointer items-center rounded-lg bg-components-button-secondary-bg px-2'
      onClick={onClick}
    >
      <Icon className='h-4 w-4 text-text-tertiary'></Icon>
      <div className='ml-1 text-xs font-medium text-text-secondary'>{text}</div>
    </div>
  )
}
const GetAutomaticRes: FC<IGetAutomaticResProps> = ({
  mode,
  model,
  isShow,
  onClose,
  isInLLMNode,
  onFinished,
}) => {
  const { t } = useTranslation()
  const {
    currentProvider,
    currentModel,
  } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.textGeneration)
  const tryList = [
    {
      icon: RiTerminalBoxLine,
      key: 'pythonDebugger',
    },
    {
      icon: RiTranslate,
      key: 'translation',
    },
    {
      icon: RiPresentationLine,
      key: 'meetingTakeaways',
    },
    {
      icon: RiNewspaperLine,
      key: 'writingsPolisher',
    },
    {
      icon: RiUser2Line,
      key: 'professionalAnalyst',
    },
    {
      icon: RiFileExcel2Line,
      key: 'excelFormulaExpert',
    },
    {
      icon: RiRoadMapLine,
      key: 'travelPlanning',
    },
    {
      icon: RiDatabase2Line,
      key: 'SQLSorcerer',
    },
    {
      icon: RiGitCommitLine,
      key: 'GitGud',
    },
  ]
  const [instruction, setInstruction] = React.useState<string>('')
  const handleChooseTemplate = useCallback((key: string) => {
    return () => {
      const template = t(`appDebug.generate.template.${key}.instruction`)
      setInstruction(template)
    }
  }, [t])
  const isValid = () => {
    if (instruction.trim() === '') {
      Toast.notify({
        type: 'error',
        message: t('common.errorMsg.fieldRequired', {
          field: t('appDebug.generate.instruction'),
        }),
      })
      return false
    }
    return true
  }
  const [isLoading, { setTrue: setLoadingTrue, setFalse: setLoadingFalse }] = useBoolean(false)
  const [res, setRes] = React.useState<AutomaticRes | null>(null)
  const renderLoading = (
    <div className='flex h-full w-0 grow flex-col items-center justify-center space-y-3'>
      <Loading />
      <div className='text-[13px] text-text-tertiary'>{t('appDebug.generate.loading')}</div>
    </div>
  )
  const renderNoData = (
    <div className='flex h-full w-0 grow flex-col items-center justify-center space-y-3 px-8'>
      <Generator className='h-14 w-14 text-text-tertiary' />
      <div className='text-center text-[13px] font-normal leading-5 text-text-tertiary'>
        <div>{t('appDebug.generate.noDataLine1')}</div>
        <div>{t('appDebug.generate.noDataLine2')}</div>
      </div>
    </div>
  )
  const onGenerate = async () => {
    if (!isValid())
      return
    if (isLoading)
      return
    setLoadingTrue()
    try {
      const { error, ...res } = await generateRule({
        instruction,
        model_config: model,
        no_variable: !!isInLLMNode,
      })
      setRes(res)
      if (error) {
        Toast.notify({
          type: 'error',
          message: error,
        })
      }
    }
    finally {
      setLoadingFalse()
    }
  }
  const [showConfirmOverwrite, setShowConfirmOverwrite] = React.useState(false)
  const isShowAutoPromptResPlaceholder = () => {
    return !isLoading && !res
  }
  return (
    <Modal
      isShow={isShow}
      onClose={onClose}
      className='min-w-[1140px] !p-0'
      closable
    >
      <div className='flex h-[680px] flex-wrap'>
        <div className='h-full w-[570px] shrink-0 overflow-y-auto border-r border-divider-regular p-6'>
          <div className='mb-8'>
            <div className={`text-lg font-bold leading-[28px] ${s.textGradient}`}>{t('appDebug.generate.title')}</div>
            <div className='mt-1 text-[13px] font-normal text-text-tertiary'>{t('appDebug.generate.description')}</div>
          </div>
          <div className='mb-8 flex items-center'>
            <ModelIcon
              className='mr-1.5 shrink-0 '
              provider={currentProvider}
              modelName={currentModel?.model}
            />
            <ModelName
              className='grow'
              modelItem={currentModel!}
              showMode
              showFeatures
            />
          </div>
          <div >
            <div className='flex items-center'>
              <div className='mr-3 shrink-0 text-xs font-semibold uppercase leading-[18px] text-text-tertiary'>{t('appDebug.generate.tryIt')}</div>
              <div className='h-px grow' style={{
                background: 'linear-gradient(to right, rgba(243, 244, 246, 1), rgba(243, 244, 246, 0))',
              }}></div>
            </div>
            <div className='flex flex-wrap'>
              {tryList.map(item => (
                <TryLabel
                  key={item.key}
                  Icon={item.icon}
                  text={t(`appDebug.generate.template.${item.key}.name`)}
                  onClick={handleChooseTemplate(item.key)}
                />
              ))}
            </div>
          </div>
          {/* inputs */}
          <div className='mt-6'>
            <div className='text-[0px]'>
              <div className='mb-2 text-sm font-medium leading-5 text-text-primary'>{t('appDebug.generate.instruction')}</div>
              <Textarea
                className="h-[200px] resize-none"
                placeholder={t('appDebug.generate.instructionPlaceHolder') as string}
                value={instruction}
                onChange={e => setInstruction(e.target.value)} />
            </div>
            <div className='mt-5 flex justify-end'>
              <Button
                className='flex space-x-1'
                variant='primary'
                onClick={onGenerate}
                disabled={isLoading}
              >
                <Generator className='h-4 w-4 text-white' />
                <span className='text-xs font-semibold text-white'>{t('appDebug.generate.generate')}</span>
              </Button>
            </div>
          </div>
        </div>
        {(!isLoading && res) && (
          <div className='h-full w-0 grow p-6 pb-0'>
            <div className='mb-3 shrink-0 text-base font-semibold leading-[160%] text-text-secondary'>{t('appDebug.generate.resTitle')}</div>
            <div className={cn('max-h-[555px] overflow-y-auto', !isInLLMNode && 'pb-2')}>
              <ConfigPrompt
                mode={mode}
                promptTemplate={res?.prompt || ''}
                promptVariables={[]}
                readonly
                noTitle={isInLLMNode}
                gradientBorder
                editorHeight={isInLLMNode ? 524 : 0}
                noResize={isInLLMNode}
              />
              {!isInLLMNode && (
                <>
                  {(res?.variables?.length && res?.variables?.length > 0)
                    ? (
                      <ConfigVar
                        promptVariables={res?.variables.map(key => ({ key, name: key, type: 'string', required: true })) || []}
                        readonly
                      />
                    )
                    : ''}
                  {(mode !== AppType.completion && res?.opening_statement) && (
                    <div className='mt-7'>
                      <GroupName name={t('appDebug.feature.groupChat.title')} />
                      <div
                        className='mb-1 rounded-xl border-l-[0.5px] border-t-[0.5px] border-effects-highlight bg-background-section-burn p-3'
                      >
                        <div className='mb-2 flex items-center gap-2'>
                          <div className='shrink-0 rounded-lg border-[0.5px] border-divider-subtle bg-util-colors-blue-light-blue-light-500 p-1 shadow-xs'>
                            <LoveMessage className='h-4 w-4 text-text-primary-on-surface' />
                          </div>
                          <div className='system-sm-semibold flex grow items-center text-text-secondary'>
                            {t('appDebug.feature.conversationOpener.title')}
                          </div>
                        </div>
                        <div className='system-xs-regular min-h-8 text-text-tertiary'>{res.opening_statement}</div>
                      </div>
                    </div>
                  )}
                </>
              )}
            </div>
            <div className='flex justify-end bg-background-default py-4'>
              <Button onClick={onClose}>{t('common.operation.cancel')}</Button>
              <Button variant='primary' className='ml-2' onClick={() => {
                setShowConfirmOverwrite(true)
              }}>{t('appDebug.generate.apply')}</Button>
            </div>
          </div>
        )}
        {isLoading && renderLoading}
        {isShowAutoPromptResPlaceholder() && renderNoData}
        {showConfirmOverwrite && (
          <Confirm
            title={t('appDebug.generate.overwriteTitle')}
            content={t('appDebug.generate.overwriteMessage')}
            isShow={showConfirmOverwrite}
            onConfirm={() => {
              setShowConfirmOverwrite(false)
              onFinished(res!)
            }}
            onCancel={() => setShowConfirmOverwrite(false)}
          />
        )}
      </div>
    </Modal>
  )
}
export default React.memo(GetAutomaticRes)
Diff truncated after the above file
app/components/app/configuration/config/automatic/style.module.css app/components/app/configuration/config/code-generator/get-code-generator-res.tsx app/components/app/configuration/config/config-document.tsx app/components/app/configuration/config/feature/use-feature.tsx app/components/app/configuration/config/index.tsx app/components/app/configuration/ctrl-btn-group/index.tsx app/components/app/configuration/ctrl-btn-group/style.module.css app/components/app/configuration/dataset-config/card-item/index.tsx app/components/app/configuration/dataset-config/card-item/item.tsx app/components/app/configuration/dataset-config/card-item/style.module.css app/components/app/configuration/dataset-config/context-var/index.tsx app/components/app/configuration/dataset-config/context-var/var-picker.tsx app/components/app/configuration/dataset-config/index.tsx app/components/app/configuration/dataset-config/params-config/config-content.tsx app/components/app/configuration/dataset-config/params-config/index.tsx app/components/app/configuration/dataset-config/params-config/weighted-score.css app/components/app/configuration/dataset-config/params-config/weighted-score.tsx app/components/app/configuration/dataset-config/select-dataset/index.tsx app/components/app/configuration/dataset-config/settings-modal/index.tsx app/components/app/configuration/dataset-config/type-icon/index.tsx app/components/app/configuration/debug/chat-user-input.tsx app/components/app/configuration/debug/debug-with-multiple-model/chat-item.tsx app/components/app/configuration/debug/debug-with-multiple-model/context.tsx app/components/app/configuration/debug/debug-with-multiple-model/debug-item.tsx app/components/app/configuration/debug/debug-with-multiple-model/index.tsx app/components/app/configuration/debug/debug-with-multiple-model/model-parameter-trigger.tsx app/components/app/configuration/debug/debug-with-multiple-model/text-generation-item.tsx app/components/app/configuration/debug/debug-with-single-model/index.tsx app/components/app/configuration/debug/hooks.tsx app/components/app/configuration/debug/index.tsx app/components/app/configuration/debug/types.ts app/components/app/configuration/features/experience-enhance-group/index.tsx app/components/app/configuration/features/experience-enhance-group/more-like-this/index.tsx app/components/app/configuration/hooks/use-advanced-prompt-config.ts app/components/app/configuration/images/prompt.svg app/components/app/configuration/index.tsx app/components/app/configuration/prompt-mode/advanced-mode-waring.tsx app/components/app/configuration/prompt-value-panel/index.tsx app/components/app/configuration/prompt-value-panel/utils.ts app/components/app/configuration/style.module.css app/components/app/configuration/tools/external-data-tool-modal.tsx app/components/app/configuration/tools/index.tsx app/components/app/create-app-dialog/app-card/index.tsx app/components/app/create-app-dialog/app-list/index.tsx app/components/app/create-app-dialog/app-list/sidebar.tsx app/components/app/create-app-dialog/index.tsx app/components/app/create-app-modal/index.tsx app/components/app/create-from-dsl-modal/dsl-confirm-modal.tsx app/components/app/create-from-dsl-modal/index.tsx app/components/app/create-from-dsl-modal/uploader.tsx app/components/app/duplicate-modal/index.tsx app/components/app/log-annotation/index.tsx app/components/app/log/filter.tsx app/components/app/log/index.tsx app/components/app/log/list.tsx app/components/app/log/model-info.tsx app/components/app/log/var-panel.tsx app/components/app/overview/apikey-info-panel/index.tsx app/components/app/overview/appCard.tsx app/components/app/overview/appChart.tsx app/components/app/overview/assets/chromeplugin-install.svg app/components/app/overview/assets/chromeplugin-option.svg app/components/app/overview/assets/code-browser.svg app/components/app/overview/assets/iframe-option.svg app/components/app/overview/assets/refresh-hover.svg app/components/app/overview/assets/refresh.svg app/components/app/overview/assets/scripts-option.svg app/components/app/overview/customize/index.tsx app/components/app/overview/embedded/index.tsx app/components/app/overview/embedded/style.module.css app/components/app/overview/settings/index.tsx app/components/app/overview/style.module.css app/components/app/store.ts app/components/app/switch-app-modal/index.tsx app/components/app/text-generate/item/index.tsx app/components/app/text-generate/item/result-tab.tsx app/components/app/text-generate/saved-items/index.tsx app/components/app/text-generate/saved-items/no-data/index.tsx app/components/app/type-selector/index.tsx app/components/app/workflow-log/detail.tsx app/components/app/workflow-log/filter.tsx app/components/app/workflow-log/index.tsx app/components/app/workflow-log/list.tsx app/components/base/action-button/index.css app/components/base/action-button/index.tsx app/components/base/agent-log-modal/detail.tsx app/components/base/agent-log-modal/index.tsx app/components/base/agent-log-modal/iteration.tsx app/components/base/agent-log-modal/result.tsx app/components/base/agent-log-modal/tool-call.tsx app/components/base/agent-log-modal/tracing.tsx app/components/base/answer-icon/index.tsx app/components/base/app-icon-picker/ImageInput.tsx app/components/base/app-icon-picker/hooks.tsx app/components/base/app-icon-picker/index.tsx app/components/base/app-icon-picker/style.module.css app/components/base/app-icon-picker/utils.ts app/components/base/app-icon/index.tsx app/components/base/app-icon/style.module.css app/components/base/app-unavailable.tsx app/components/base/audio-btn/audio.player.manager.ts app/components/base/audio-btn/audio.ts app/components/base/audio-btn/index.tsx app/components/base/audio-btn/style.module.css app/components/base/audio-gallery/AudioPlayer.tsx app/components/base/audio-gallery/index.tsx app/components/base/auto-height-textarea/common.tsx app/components/base/auto-height-textarea/index.tsx app/components/base/auto-height-textarea/style.module.scss app/components/base/avatar/index.tsx app/components/base/badge.tsx app/components/base/badge/index.css app/components/base/badge/index.tsx app/components/base/block-input/index.tsx app/components/base/button/add-button.tsx app/components/base/button/index.css app/components/base/button/index.spec.tsx app/components/base/button/index.stories.tsx app/components/base/button/index.tsx app/components/base/chat/__tests__/__snapshots__/utils.spec.ts.snap app/components/base/chat/__tests__/branchedTestMessages.json app/components/base/chat/__tests__/legacyTestMessages.json app/components/base/chat/__tests__/mixedTestMessages.json app/components/base/chat/__tests__/multiRootNodesMessages.json app/components/base/chat/__tests__/multiRootNodesWithLegacyTestMessages.json app/components/base/chat/__tests__/partialMessages.json app/components/base/chat/__tests__/realWorldMessages.json app/components/base/chat/__tests__/utils.spec.ts app/components/base/chat/chat-with-history/chat-wrapper.tsx app/components/base/chat/chat-with-history/context.tsx app/components/base/chat/chat-with-history/header-in-mobile.tsx app/components/base/chat/chat-with-history/header/index.tsx app/components/base/chat/chat-with-history/header/mobile-operation-dropdown.tsx app/components/base/chat/chat-with-history/header/operation.tsx app/components/base/chat/chat-with-history/hooks.tsx app/components/base/chat/chat-with-history/index.tsx app/components/base/chat/chat-with-history/inputs-form/content.tsx app/components/base/chat/chat-with-history/inputs-form/index.tsx app/components/base/chat/chat-with-history/inputs-form/view-form-dropdown.tsx app/components/base/chat/chat-with-history/sidebar/index.tsx app/components/base/chat/chat-with-history/sidebar/item.tsx app/components/base/chat/chat-with-history/sidebar/list.tsx app/components/base/chat/chat-with-history/sidebar/operation.tsx app/components/base/chat/chat-with-history/sidebar/rename-modal.tsx app/components/base/chat/chat/answer/__mocks__/markdownContent.ts app/components/base/chat/chat/answer/__mocks__/markdownContentSVG.ts app/components/base/chat/chat/answer/__mocks__/workflowProcess.ts app/components/base/chat/chat/answer/agent-content.tsx app/components/base/chat/chat/answer/basic-content.tsx app/components/base/chat/chat/answer/index.stories.tsx app/components/base/chat/chat/answer/index.tsx app/components/base/chat/chat/answer/more.tsx app/components/base/chat/chat/answer/operation.tsx app/components/base/chat/chat/answer/suggested-questions.tsx app/components/base/chat/chat/answer/tool-detail.tsx app/components/base/chat/chat/answer/workflow-process.tsx app/components/base/chat/chat/chat-input-area/hooks.ts app/components/base/chat/chat/chat-input-area/index.tsx app/components/base/chat/chat/chat-input-area/operation.tsx app/components/base/chat/chat/check-input-forms-hooks.ts app/components/base/chat/chat/citation/index.tsx app/components/base/chat/chat/citation/popup.tsx app/components/base/chat/chat/citation/progress-tooltip.tsx app/components/base/chat/chat/citation/tooltip.tsx app/components/base/chat/chat/content-switch.tsx app/components/base/chat/chat/context.tsx app/components/base/chat/chat/hooks.ts app/components/base/chat/chat/index.tsx app/components/base/chat/chat/loading-anim/index.tsx app/components/base/chat/chat/loading-anim/style.module.css app/components/base/chat/chat/log/index.tsx app/components/base/chat/chat/question.stories.tsx app/components/base/chat/chat/question.tsx app/components/base/chat/chat/thought/index.tsx app/components/base/chat/chat/thought/panel.tsx app/components/base/chat/chat/thought/tool.tsx app/components/base/chat/chat/try-to-ask.tsx app/components/base/chat/chat/type.ts app/components/base/chat/chat/utils.ts app/components/base/chat/constants.ts app/components/base/chat/embedded-chatbot/chat-wrapper.tsx app/components/base/chat/embedded-chatbot/context.tsx app/components/base/chat/embedded-chatbot/header/index.tsx app/components/base/chat/embedded-chatbot/hooks.tsx app/components/base/chat/embedded-chatbot/index.tsx app/components/base/chat/embedded-chatbot/inputs-form/content.tsx app/components/base/chat/embedded-chatbot/inputs-form/index.tsx app/components/base/chat/embedded-chatbot/inputs-form/view-form-dropdown.tsx app/components/base/chat/embedded-chatbot/theme/theme-context.ts app/components/base/chat/embedded-chatbot/theme/utils.ts app/components/base/chat/embedded-chatbot/utils.ts app/components/base/chat/types.ts app/components/base/chat/utils.ts app/components/base/checkbox/assets/indeterminate-icon.tsx app/components/base/checkbox/index.spec.tsx app/components/base/checkbox/index.tsx app/components/base/chip/index.tsx app/components/base/confirm/index.tsx app/components/base/content-dialog/index.tsx app/components/base/copy-btn/index.tsx app/components/base/copy-btn/style.module.css app/components/base/copy-feedback/index.tsx app/components/base/copy-feedback/style.module.css app/components/base/copy-icon/index.tsx app/components/base/corner-label/index.tsx app/components/base/custom-icon/index.tsx app/components/base/date-and-time-picker/calendar/days-of-week.tsx app/components/base/date-and-time-picker/calendar/index.tsx app/components/base/date-and-time-picker/calendar/item.tsx app/components/base/date-and-time-picker/common/option-list-item.tsx app/components/base/date-and-time-picker/date-picker/footer.tsx app/components/base/date-and-time-picker/date-picker/header.tsx app/components/base/date-and-time-picker/date-picker/index.tsx app/components/base/date-and-time-picker/hooks.ts app/components/base/date-and-time-picker/time-picker/footer.tsx app/components/base/date-and-time-picker/time-picker/header.tsx app/components/base/date-and-time-picker/time-picker/index.tsx app/components/base/date-and-time-picker/time-picker/options.tsx app/components/base/date-and-time-picker/types.ts app/components/base/date-and-time-picker/utils/dayjs.ts app/components/base/date-and-time-picker/year-and-month-picker/footer.tsx app/components/base/date-and-time-picker/year-and-month-picker/header.tsx app/components/base/date-and-time-picker/year-and-month-picker/options.tsx app/components/base/dialog/index.tsx app/components/base/divider/index.spec.tsx app/components/base/divider/index.tsx app/components/base/divider/with-label.tsx app/components/base/drawer-plus/index.tsx app/components/base/drawer/index.tsx app/components/base/dropdown/index.tsx app/components/base/emoji-picker/Inner.tsx app/components/base/emoji-picker/index.tsx app/components/base/features/context.tsx app/components/base/features/hooks.ts app/components/base/features/index.tsx app/components/base/features/new-feature-panel/annotation-reply/annotation-ctrl-button.tsx app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.tsx app/components/base/features/new-feature-panel/annotation-reply/config-param.tsx app/components/base/features/new-feature-panel/annotation-reply/index.tsx app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/index.tsx app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/style.module.css app/components/base/features/new-feature-panel/annotation-reply/score-slider/index.tsx app/components/base/features/new-feature-panel/annotation-reply/type.ts app/components/base/features/new-feature-panel/annotation-reply/use-annotation-config.ts app/components/base/features/new-feature-panel/citation.tsx app/components/base/features/new-feature-panel/conversation-opener/index.tsx app/components/base/features/new-feature-panel/conversation-opener/modal.tsx app/components/base/features/new-feature-panel/dialog-wrapper.tsx app/components/base/features/new-feature-panel/feature-bar.tsx app/components/base/features/new-feature-panel/feature-card.tsx app/components/base/features/new-feature-panel/file-upload/index.tsx app/components/base/features/new-feature-panel/file-upload/setting-content.tsx app/components/base/features/new-feature-panel/file-upload/setting-modal.tsx app/components/base/features/new-feature-panel/follow-up.tsx app/components/base/features/new-feature-panel/image-upload/index.tsx app/components/base/features/new-feature-panel/index.tsx app/components/base/features/new-feature-panel/moderation/form-generation.tsx app/components/base/features/new-feature-panel/moderation/index.tsx app/components/base/features/new-feature-panel/moderation/moderation-content.tsx app/components/base/features/new-feature-panel/moderation/moderation-setting-modal.tsx app/components/base/features/new-feature-panel/more-like-this.tsx app/components/base/features/new-feature-panel/speech-to-text.tsx app/components/base/features/new-feature-panel/text-to-speech/index.tsx app/components/base/features/new-feature-panel/text-to-speech/param-config-content.tsx app/components/base/features/new-feature-panel/text-to-speech/voice-settings.tsx app/components/base/features/store.ts app/components/base/features/types.ts app/components/base/file-icon/index.tsx app/components/base/file-uploader/audio-preview.tsx app/components/base/file-uploader/constants.ts app/components/base/file-uploader/dynamic-pdf-preview.tsx app/components/base/file-uploader/file-from-link-or-local/index.tsx app/components/base/file-uploader/file-image-render.tsx app/components/base/file-uploader/file-input.tsx app/components/base/file-uploader/file-list-in-log.tsx app/components/base/file-uploader/file-type-icon.tsx app/components/base/file-uploader/file-uploader-in-attachment/file-item.tsx app/components/base/file-uploader/file-uploader-in-attachment/index.tsx app/components/base/file-uploader/file-uploader-in-chat-input/file-image-item.tsx app/components/base/file-uploader/file-uploader-in-chat-input/file-item.tsx app/components/base/file-uploader/file-uploader-in-chat-input/file-list.tsx app/components/base/file-uploader/file-uploader-in-chat-input/index.tsx app/components/base/file-uploader/hooks.ts app/components/base/file-uploader/index.ts app/components/base/file-uploader/pdf-preview.tsx app/components/base/file-uploader/store.tsx app/components/base/file-uploader/types.ts app/components/base/file-uploader/utils.spec.ts app/components/base/file-uploader/utils.ts app/components/base/file-uploader/video-preview.tsx app/components/base/float-popover-container/index.tsx app/components/base/float-right-container/index.tsx app/components/base/form/components/field/checkbox.tsx app/components/base/form/components/field/number-input.tsx app/components/base/form/components/field/options.tsx app/components/base/form/components/field/select.tsx app/components/base/form/components/field/text.tsx app/components/base/form/components/form/submit-button.tsx app/components/base/form/components/label.spec.tsx app/components/base/form/components/label.tsx app/components/base/form/form-scenarios/demo/contact-fields.tsx app/components/base/form/form-scenarios/demo/index.tsx app/components/base/form/form-scenarios/demo/shared-options.tsx app/components/base/form/form-scenarios/demo/types.ts app/components/base/form/index.tsx app/components/base/fullscreen-modal/index.tsx app/components/base/ga/index.tsx app/components/base/grid-mask/Grid.svg app/components/base/grid-mask/index.tsx app/components/base/grid-mask/style.module.css app/components/base/icons/IconBase.spec.tsx app/components/base/icons/IconBase.tsx app/components/base/icons/assets/image/llm/baichuan-text-cn.png app/components/base/icons/assets/image/llm/minimax-text.png app/components/base/icons/assets/image/llm/minimax.png app/components/base/icons/assets/image/llm/tongyi-text-cn.png app/components/base/icons/assets/image/llm/tongyi-text.png app/components/base/icons/assets/image/llm/tongyi.png app/components/base/icons/assets/image/llm/wxyy-text-cn.png app/components/base/icons/assets/image/llm/wxyy-text.png app/components/base/icons/assets/image/llm/wxyy.png app/components/base/icons/assets/public/avatar/robot.svg app/components/base/icons/assets/public/avatar/user.svg app/components/base/icons/assets/public/billing/ar-cube-1.svg app/components/base/icons/assets/public/billing/asterisk.svg app/components/base/icons/assets/public/billing/aws-marketplace.svg app/components/base/icons/assets/public/billing/azure.svg app/components/base/icons/assets/public/billing/buildings.svg app/components/base/icons/assets/public/billing/diamond.svg app/components/base/icons/assets/public/billing/google-cloud.svg app/components/base/icons/assets/public/billing/group-2.svg app/components/base/icons/assets/public/billing/keyframe.svg app/components/base/icons/assets/public/billing/sparkles-soft.svg app/components/base/icons/assets/public/billing/sparkles.svg app/components/base/icons/assets/public/common/d.svg app/components/base/icons/assets/public/common/diagonal-dividing-line.svg app/components/base/icons/assets/public/common/dify.svg app/components/base/icons/assets/public/common/gdpr.svg app/components/base/icons/assets/public/common/github.svg app/components/base/icons/assets/public/common/highlight.svg app/components/base/icons/assets/public/common/iso.svg app/components/base/icons/assets/public/common/line-3.svg app/components/base/icons/assets/public/common/lock.svg app/components/base/icons/assets/public/common/message-chat-square.svg app/components/base/icons/assets/public/common/multi-path-retrieval.svg app/components/base/icons/assets/public/common/n-to-1-retrieval.svg app/components/base/icons/assets/public/common/notion.svg app/components/base/icons/assets/public/common/soc2.svg app/components/base/icons/assets/public/common/sparkles-soft.svg app/components/base/icons/assets/public/education/triangle.svg app/components/base/icons/assets/public/files/csv.svg app/components/base/icons/assets/public/files/doc.svg app/components/base/icons/assets/public/files/docx.svg app/components/base/icons/assets/public/files/html.svg app/components/base/icons/assets/public/files/json.svg app/components/base/icons/assets/public/files/md.svg app/components/base/icons/assets/public/files/pdf.svg app/components/base/icons/assets/public/files/txt.svg app/components/base/icons/assets/public/files/unknown.svg app/components/base/icons/assets/public/files/xlsx.svg app/components/base/icons/assets/public/files/yaml.svg app/components/base/icons/assets/public/knowledge/chunk.svg app/components/base/icons/assets/public/knowledge/collapse.svg app/components/base/icons/assets/public/knowledge/general-type.svg app/components/base/icons/assets/public/knowledge/layout-right-2-line-mod.svg app/components/base/icons/assets/public/knowledge/parent-child-type.svg app/components/base/icons/assets/public/knowledge/selection-mod.svg app/components/base/icons/assets/public/llm/Anthropic-dark.svg app/components/base/icons/assets/public/llm/Anthropic-light.svg app/components/base/icons/assets/public/llm/anthropic-text.svg app/components/base/icons/assets/public/llm/anthropic.svg app/components/base/icons/assets/public/llm/azure-openai-service-text.svg app/components/base/icons/assets/public/llm/azure-openai-service.svg app/components/base/icons/assets/public/llm/azureai-text.svg app/components/base/icons/assets/public/llm/azureai.svg app/components/base/icons/assets/public/llm/baichuan-text.svg app/components/base/icons/assets/public/llm/baichuan.svg app/components/base/icons/assets/public/llm/chatglm-text.svg app/components/base/icons/assets/public/llm/chatglm.svg app/components/base/icons/assets/public/llm/cohere-text.svg app/components/base/icons/assets/public/llm/cohere.svg app/components/base/icons/assets/public/llm/gpt-3.svg app/components/base/icons/assets/public/llm/gpt-4.svg app/components/base/icons/assets/public/llm/huggingface-text-hub.svg app/components/base/icons/assets/public/llm/huggingface-text.svg app/components/base/icons/assets/public/llm/huggingface.svg app/components/base/icons/assets/public/llm/iflytek-spark-text-cn.svg app/components/base/icons/assets/public/llm/iflytek-spark-text.svg app/components/base/icons/assets/public/llm/iflytek-spark.svg app/components/base/icons/assets/public/llm/jina-text.svg app/components/base/icons/assets/public/llm/jina.svg app/components/base/icons/assets/public/llm/localai-text.svg app/components/base/icons/assets/public/llm/localai.svg app/components/base/icons/assets/public/llm/microsoft.svg app/components/base/icons/assets/public/llm/openai-black.svg app/components/base/icons/assets/public/llm/openai-blue.svg app/components/base/icons/assets/public/llm/openai-green.svg app/components/base/icons/assets/public/llm/openai-text.svg app/components/base/icons/assets/public/llm/openai-transparent.svg app/components/base/icons/assets/public/llm/openai-violet.svg app/components/base/icons/assets/public/llm/openllm-text.svg app/components/base/icons/assets/public/llm/openllm.svg app/components/base/icons/assets/public/llm/replicate-text.svg app/components/base/icons/assets/public/llm/replicate.svg app/components/base/icons/assets/public/llm/xorbits-inference-text.svg app/components/base/icons/assets/public/llm/xorbits-inference.svg app/components/base/icons/assets/public/llm/zhipuai-text-cn.svg app/components/base/icons/assets/public/llm/zhipuai-text.svg app/components/base/icons/assets/public/llm/zhipuai.svg app/components/base/icons/assets/public/model/checked.svg app/components/base/icons/assets/public/other/Icon-3-dots.svg app/components/base/icons/assets/public/other/default-tool-icon.svg app/components/base/icons/assets/public/other/message-3-fill.svg app/components/base/icons/assets/public/other/row-struct.svg app/components/base/icons/assets/public/plugins/google.svg app/components/base/icons/assets/public/plugins/partner-dark.svg app/components/base/icons/assets/public/plugins/partner-light.svg app/components/base/icons/assets/public/plugins/verified-dark.svg app/components/base/icons/assets/public/plugins/verified-light.svg app/components/base/icons/assets/public/plugins/web-reader.svg app/components/base/icons/assets/public/plugins/wikipedia.svg app/components/base/icons/assets/public/thought/data-set.svg app/components/base/icons/assets/public/thought/loading.svg app/components/base/icons/assets/public/thought/search.svg app/components/base/icons/assets/public/thought/thought-list.svg app/components/base/icons/assets/public/thought/web-reader.svg app/components/base/icons/assets/public/tracing/langfuse-icon-big.svg app/components/base/icons/assets/public/tracing/langfuse-icon.svg app/components/base/icons/assets/public/tracing/langsmith-icon-big.svg app/components/base/icons/assets/public/tracing/langsmith-icon.svg app/components/base/icons/assets/public/tracing/opik-icon-big.svg app/components/base/icons/assets/public/tracing/opik-icon.svg app/components/base/icons/assets/public/tracing/tracing-icon.svg app/components/base/icons/assets/public/tracing/weave-icon-big.svg app/components/base/icons/assets/public/tracing/weave-icon.svg app/components/base/icons/assets/vender/features/citations.svg app/components/base/icons/assets/vender/features/content-moderation.svg app/components/base/icons/assets/vender/features/document.svg app/components/base/icons/assets/vender/features/folder-upload.svg app/components/base/icons/assets/vender/features/love-message.svg app/components/base/icons/assets/vender/features/message-fast.svg app/components/base/icons/assets/vender/features/microphone-01.svg app/components/base/icons/assets/vender/features/text-to-audio.svg app/components/base/icons/assets/vender/features/virtual-assistant.svg app/components/base/icons/assets/vender/features/vision.svg app/components/base/icons/assets/vender/line/alertsAndFeedback/alert-triangle.svg app/components/base/icons/assets/vender/line/alertsAndFeedback/thumbs-down.svg app/components/base/icons/assets/vender/line/alertsAndFeedback/thumbs-up.svg app/components/base/icons/assets/vender/line/arrows/arrow-narrow-left.svg app/components/base/icons/assets/vender/line/arrows/arrow-up-right.svg app/components/base/icons/assets/vender/line/arrows/chevron-down-double.svg app/components/base/icons/assets/vender/line/arrows/chevron-right.svg app/components/base/icons/assets/vender/line/arrows/chevron-selector-vertical.svg app/components/base/icons/assets/vender/line/arrows/refresh-ccw-01.svg app/components/base/icons/assets/vender/line/arrows/refresh-cw-05.svg app/components/base/icons/assets/vender/line/arrows/reverse-left.svg app/components/base/icons/assets/vender/line/communication/ai-text.svg app/components/base/icons/assets/vender/line/communication/chat-bot-slim.svg app/components/base/icons/assets/vender/line/communication/chat-bot.svg app/components/base/icons/assets/vender/line/communication/cute-robot.svg app/components/base/icons/assets/vender/line/communication/message-check-remove.svg app/components/base/icons/assets/vender/line/communication/message-fast-plus.svg app/components/base/icons/assets/vender/line/development/artificial-brain.svg app/components/base/icons/assets/vender/line/development/bar-chart-square-02.svg app/components/base/icons/assets/vender/line/development/brackets-x.svg app/components/base/icons/assets/vender/line/development/code-browser.svg app/components/base/icons/assets/vender/line/development/container.svg app/components/base/icons/assets/vender/line/development/database-01.svg app/components/base/icons/assets/vender/line/development/database-03.svg app/components/base/icons/assets/vender/line/development/file-heart-02.svg app/components/base/icons/assets/vender/line/development/git-branch-01.svg app/components/base/icons/assets/vender/line/development/prompt-engineering.svg app/components/base/icons/assets/vender/line/development/puzzle-piece-01.svg app/components/base/icons/assets/vender/line/development/terminal-square.svg app/components/base/icons/assets/vender/line/development/variable.svg app/components/base/icons/assets/vender/line/development/webhooks.svg app/components/base/icons/assets/vender/line/editor/align-left.svg app/components/base/icons/assets/vender/line/editor/bezier-curve-03.svg app/components/base/icons/assets/vender/line/editor/collapse.svg app/components/base/icons/assets/vender/line/editor/colors.svg app/components/base/icons/assets/vender/line/editor/image-indent-left.svg app/components/base/icons/assets/vender/line/editor/left-indent-02.svg app/components/base/icons/assets/vender/line/editor/letter-spacing-01.svg app/components/base/icons/assets/vender/line/editor/type-square.svg app/components/base/icons/assets/vender/line/education/book-open-01.svg app/components/base/icons/assets/vender/line/files/clipboard-check.svg app/components/base/icons/assets/vender/line/files/clipboard.svg app/components/base/icons/assets/vender/line/files/file-02.svg app/components/base/icons/assets/vender/line/files/file-arrow-01.svg app/components/base/icons/assets/vender/line/files/file-check-02.svg app/components/base/icons/assets/vender/line/files/file-download-02.svg app/components/base/icons/assets/vender/line/files/file-plus-01.svg app/components/base/icons/assets/vender/line/files/file-plus-02.svg app/components/base/icons/assets/vender/line/files/file-text.svg app/components/base/icons/assets/vender/line/files/file-upload.svg app/components/base/icons/assets/vender/line/files/folder.svg app/components/base/icons/assets/vender/line/financeAndECommerce/balance.svg app/components/base/icons/assets/vender/line/financeAndECommerce/coins-stacked-01.svg app/components/base/icons/assets/vender/line/financeAndECommerce/gold-coin.svg app/components/base/icons/assets/vender/line/financeAndECommerce/receipt-list.svg app/components/base/icons/assets/vender/line/financeAndECommerce/tag-01.svg app/components/base/icons/assets/vender/line/financeAndECommerce/tag-03.svg app/components/base/icons/assets/vender/line/general/at-sign.svg app/components/base/icons/assets/vender/line/general/bookmark.svg app/components/base/icons/assets/vender/line/general/check-done-01.svg app/components/base/icons/assets/vender/line/general/check.svg app/components/base/icons/assets/vender/line/general/checklist-square.svg app/components/base/icons/assets/vender/line/general/dots-grid.svg app/components/base/icons/assets/vender/line/general/edit-02.svg app/components/base/icons/assets/vender/line/general/edit-04.svg app/components/base/icons/assets/vender/line/general/edit-05.svg app/components/base/icons/assets/vender/line/general/hash-02.svg app/components/base/icons/assets/vender/line/general/info-circle.svg app/components/base/icons/assets/vender/line/general/link-03.svg app/components/base/icons/assets/vender/line/general/link-external-02.svg app/components/base/icons/assets/vender/line/general/log-in-04.svg app/components/base/icons/assets/vender/line/general/log-out-01.svg app/components/base/icons/assets/vender/line/general/log-out-04.svg app/components/base/icons/assets/vender/line/general/menu-01.svg app/components/base/icons/assets/vender/line/general/pin-01.svg app/components/base/icons/assets/vender/line/general/pin-02.svg app/components/base/icons/assets/vender/line/general/plus-02.svg app/components/base/icons/assets/vender/line/general/refresh.svg app/components/base/icons/assets/vender/line/general/settings-01.svg app/components/base/icons/assets/vender/line/general/settings-04.svg app/components/base/icons/assets/vender/line/general/target-04.svg app/components/base/icons/assets/vender/line/general/upload-03.svg app/components/base/icons/assets/vender/line/general/upload-cloud-01.svg app/components/base/icons/assets/vender/line/general/x.svg app/components/base/icons/assets/vender/line/images/image-plus.svg app/components/base/icons/assets/vender/line/layout/align-left-01.svg app/components/base/icons/assets/vender/line/layout/align-right-01.svg app/components/base/icons/assets/vender/line/layout/grid-01.svg app/components/base/icons/assets/vender/line/layout/layout-grid-02.svg app/components/base/icons/assets/vender/line/mapsAndTravel/globe-01.svg app/components/base/icons/assets/vender/line/mapsAndTravel/route.svg app/components/base/icons/assets/vender/line/mediaAndDevices/microphone-01.svg app/components/base/icons/assets/vender/line/mediaAndDevices/play-circle.svg app/components/base/icons/assets/vender/line/mediaAndDevices/sliders-h.svg app/components/base/icons/assets/vender/line/mediaAndDevices/speaker.svg app/components/base/icons/assets/vender/line/mediaAndDevices/stop-circle.svg app/components/base/icons/assets/vender/line/mediaAndDevices/stop.svg app/components/base/icons/assets/vender/line/others/apps-02.svg app/components/base/icons/assets/vender/line/others/bubble-x.svg app/components/base/icons/assets/vender/line/others/colors.svg app/components/base/icons/assets/vender/line/others/drag-handle.svg app/components/base/icons/assets/vender/line/others/env.svg app/components/base/icons/assets/vender/line/others/exchange-02.svg app/components/base/icons/assets/vender/line/others/file-code.svg app/components/base/icons/assets/vender/line/others/global-variable.svg app/components/base/icons/assets/vender/line/others/icon-3-dots.svg app/components/base/icons/assets/vender/line/others/long-arrow-left.svg app/components/base/icons/assets/vender/line/others/long-arrow-right.svg app/components/base/icons/assets/vender/line/others/tools.svg app/components/base/icons/assets/vender/line/shapes/cube-outline.svg app/components/base/icons/assets/vender/line/time/clock-fast-forward.svg app/components/base/icons/assets/vender/line/time/clock-play-slim.svg app/components/base/icons/assets/vender/line/time/clock-play.svg app/components/base/icons/assets/vender/line/time/clock-refresh.svg app/components/base/icons/assets/vender/line/users/user-01.svg app/components/base/icons/assets/vender/line/users/users-01.svg app/components/base/icons/assets/vender/line/weather/stars-02.svg app/components/base/icons/assets/vender/other/anthropic-text.svg app/components/base/icons/assets/vender/other/generator.svg app/components/base/icons/assets/vender/other/group.svg app/components/base/icons/assets/vender/other/openai.svg app/components/base/icons/assets/vender/other/replay-line.svg app/components/base/icons/assets/vender/plugin/box-sparkle-fill.svg app/components/base/icons/assets/vender/plugin/left-corner.svg app/components/base/icons/assets/vender/solid/FinanceAndECommerce/gold-coin.svg app/components/base/icons/assets/vender/solid/FinanceAndECommerce/scales-02.svg app/components/base/icons/assets/vender/solid/alertsAndFeedback/alert-triangle.svg app/components/base/icons/assets/vender/solid/arrows/chevron-down.svg app/components/base/icons/assets/vender/solid/arrows/high-priority.svg app/components/base/icons/assets/vender/solid/communication/ai-text.svg app/components/base/icons/assets/vender/solid/communication/bubble-text-mod.svg app/components/base/icons/assets/vender/solid/communication/chat-bot.svg app/components/base/icons/assets/vender/solid/communication/cute-robot.svg app/components/base/icons/assets/vender/solid/communication/edit-list.svg app/components/base/icons/assets/vender/solid/communication/list-sparkle.svg app/components/base/icons/assets/vender/solid/communication/logic.svg app/components/base/icons/assets/vender/solid/communication/message-dots-circle.svg app/components/base/icons/assets/vender/solid/communication/message-fast.svg app/components/base/icons/assets/vender/solid/communication/message-heart-circle.svg app/components/base/icons/assets/vender/solid/communication/message-smile-square.svg app/components/base/icons/assets/vender/solid/communication/send-03.svg app/components/base/icons/assets/vender/solid/development/api-connection-mod.svg app/components/base/icons/assets/vender/solid/development/api-connection.svg app/components/base/icons/assets/vender/solid/development/bar-chart-square-02.svg app/components/base/icons/assets/vender/solid/development/container.svg app/components/base/icons/assets/vender/solid/development/database-02.svg app/components/base/icons/assets/vender/solid/development/database-03.svg app/components/base/icons/assets/vender/solid/development/file-heart-02.svg app/components/base/icons/assets/vender/solid/development/pattern-recognition.svg app/components/base/icons/assets/vender/solid/development/prompt-engineering.svg app/components/base/icons/assets/vender/solid/development/puzzle-piece-01.svg app/components/base/icons/assets/vender/solid/development/semantic.svg app/components/base/icons/assets/vender/solid/development/terminal-square.svg app/components/base/icons/assets/vender/solid/development/variable-02.svg app/components/base/icons/assets/vender/solid/editor/brush-01.svg app/components/base/icons/assets/vender/solid/editor/citations.svg app/components/base/icons/assets/vender/solid/editor/colors.svg app/components/base/icons/assets/vender/solid/editor/paragraph.svg app/components/base/icons/assets/vender/solid/editor/type-square.svg app/components/base/icons/assets/vender/solid/education/beaker-02.svg app/components/base/icons/assets/vender/solid/education/bubble-text.svg app/components/base/icons/assets/vender/solid/education/heart-02.svg app/components/base/icons/assets/vender/solid/education/unblur.svg app/components/base/icons/assets/vender/solid/files/file-05.svg app/components/base/icons/assets/vender/solid/files/file-search-02.svg app/components/base/icons/assets/vender/solid/files/file-zip.svg app/components/base/icons/assets/vender/solid/files/folder.svg app/components/base/icons/assets/vender/solid/general/answer-triangle.svg app/components/base/icons/assets/vender/solid/general/arrow-down-round-fill.svg app/components/base/icons/assets/vender/solid/general/check-circle.svg app/components/base/icons/assets/vender/solid/general/check-done-01.svg app/components/base/icons/assets/vender/solid/general/download-02.svg app/components/base/icons/assets/vender/solid/general/edit-03.svg app/components/base/icons/assets/vender/solid/general/edit-04.svg app/components/base/icons/assets/vender/solid/general/eye.svg app/components/base/icons/assets/vender/solid/general/github.svg app/components/base/icons/assets/vender/solid/general/message-clock-circle.svg app/components/base/icons/assets/vender/solid/general/plus-circle.svg app/components/base/icons/assets/vender/solid/general/question-triangle.svg app/components/base/icons/assets/vender/solid/general/search-md.svg app/components/base/icons/assets/vender/solid/general/target-04.svg app/components/base/icons/assets/vender/solid/general/tool-03.svg app/components/base/icons/assets/vender/solid/general/x-circle.svg app/components/base/icons/assets/vender/solid/general/zap-fast.svg app/components/base/icons/assets/vender/solid/general/zap-narrow.svg app/components/base/icons/assets/vender/solid/layout/grid-01.svg app/components/base/icons/assets/vender/solid/mapsAndTravel/globe-06.svg app/components/base/icons/assets/vender/solid/mapsAndTravel/route.svg app/components/base/icons/assets/vender/solid/mediaAndDevices/audio-support-icon.svg app/components/base/icons/assets/vender/solid/mediaAndDevices/document-support-icon.svg app/components/base/icons/assets/vender/solid/mediaAndDevices/magic-box.svg app/components/base/icons/assets/vender/solid/mediaAndDevices/magic-eyes.svg app/components/base/icons/assets/vender/solid/mediaAndDevices/magic-wand.svg app/components/base/icons/assets/vender/solid/mediaAndDevices/microphone-01.svg app/components/base/icons/assets/vender/solid/mediaAndDevices/play.svg app/components/base/icons/assets/vender/solid/mediaAndDevices/robot.svg app/components/base/icons/assets/vender/solid/mediaAndDevices/sliders-02.svg app/components/base/icons/assets/vender/solid/mediaAndDevices/speaker.svg app/components/base/icons/assets/vender/solid/mediaAndDevices/stop-circle.svg app/components/base/icons/assets/vender/solid/mediaAndDevices/video-support-icon.svg app/components/base/icons/assets/vender/solid/security/lock-01.svg app/components/base/icons/assets/vender/solid/shapes/corner.svg app/components/base/icons/assets/vender/solid/shapes/star-04.svg app/components/base/icons/assets/vender/solid/shapes/star-06.svg app/components/base/icons/assets/vender/solid/users/user-01.svg app/components/base/icons/assets/vender/solid/users/user-edit-02.svg app/components/base/icons/assets/vender/solid/users/users-01.svg app/components/base/icons/assets/vender/solid/users/users-plus.svg app/components/base/icons/assets/vender/workflow/agent.svg app/components/base/icons/assets/vender/workflow/answer.svg app/components/base/icons/assets/vender/workflow/assigner.svg app/components/base/icons/assets/vender/workflow/code.svg app/components/base/icons/assets/vender/workflow/docs-extractor.svg app/components/base/icons/assets/vender/workflow/end.svg app/components/base/icons/assets/vender/workflow/home.svg app/components/base/icons/assets/vender/workflow/http.svg app/components/base/icons/assets/vender/workflow/if-else.svg app/components/base/icons/assets/vender/workflow/iteration-start.svg app/components/base/icons/assets/vender/workflow/iteration.svg app/components/base/icons/assets/vender/workflow/jinja.svg app/components/base/icons/assets/vender/workflow/knowledge-retrieval.svg app/components/base/icons/assets/vender/workflow/list-filter.svg app/components/base/icons/assets/vender/workflow/llm.svg app/components/base/icons/assets/vender/workflow/loop-end.svg app/components/base/icons/assets/vender/workflow/loop.svg app/components/base/icons/assets/vender/workflow/parameter-extractor.svg app/components/base/icons/assets/vender/workflow/question-classifier.svg app/components/base/icons/assets/vender/workflow/templating-transform.svg app/components/base/icons/assets/vender/workflow/variable-x.svg app/components/base/icons/script.mjs app/components/base/icons/src/image/llm/BaichuanTextCn.module.css app/components/base/icons/src/image/llm/BaichuanTextCn.tsx app/components/base/icons/src/image/llm/Minimax.module.css app/components/base/icons/src/image/llm/Minimax.tsx app/components/base/icons/src/image/llm/MinimaxText.module.css app/components/base/icons/src/image/llm/MinimaxText.tsx app/components/base/icons/src/image/llm/Tongyi.module.css app/components/base/icons/src/image/llm/Tongyi.tsx app/components/base/icons/src/image/llm/TongyiText.module.css app/components/base/icons/src/image/llm/TongyiText.tsx app/components/base/icons/src/image/llm/TongyiTextCn.module.css app/components/base/icons/src/image/llm/TongyiTextCn.tsx app/components/base/icons/src/image/llm/Wxyy.module.css app/components/base/icons/src/image/llm/Wxyy.tsx app/components/base/icons/src/image/llm/WxyyText.module.css app/components/base/icons/src/image/llm/WxyyText.tsx app/components/base/icons/src/image/llm/WxyyTextCn.module.css app/components/base/icons/src/image/llm/WxyyTextCn.tsx app/components/base/icons/src/image/llm/index.ts app/components/base/icons/src/public/avatar/Robot.json app/components/base/icons/src/public/avatar/Robot.tsx app/components/base/icons/src/public/avatar/User.json app/components/base/icons/src/public/avatar/User.tsx app/components/base/icons/src/public/avatar/index.ts app/components/base/icons/src/public/billing/ArCube1.json app/components/base/icons/src/public/billing/ArCube1.tsx app/components/base/icons/src/public/billing/Asterisk.json app/components/base/icons/src/public/billing/Asterisk.tsx app/components/base/icons/src/public/billing/AwsMarketplace.json app/components/base/icons/src/public/billing/AwsMarketplace.tsx app/components/base/icons/src/public/billing/Azure.json app/components/base/icons/src/public/billing/Azure.tsx app/components/base/icons/src/public/billing/Buildings.json app/components/base/icons/src/public/billing/Buildings.tsx app/components/base/icons/src/public/billing/Diamond.json app/components/base/icons/src/public/billing/Diamond.tsx app/components/base/icons/src/public/billing/GoogleCloud.json app/components/base/icons/src/public/billing/GoogleCloud.tsx app/components/base/icons/src/public/billing/Group2.json app/components/base/icons/src/public/billing/Group2.tsx app/components/base/icons/src/public/billing/Keyframe.json app/components/base/icons/src/public/billing/Keyframe.tsx app/components/base/icons/src/public/billing/Sparkles.json app/components/base/icons/src/public/billing/Sparkles.tsx app/components/base/icons/src/public/billing/SparklesSoft.json app/components/base/icons/src/public/billing/SparklesSoft.tsx app/components/base/icons/src/public/billing/index.ts app/components/base/icons/src/public/common/D.json app/components/base/icons/src/public/common/D.tsx app/components/base/icons/src/public/common/DiagonalDividingLine.json app/components/base/icons/src/public/common/DiagonalDividingLine.tsx app/components/base/icons/src/public/common/Dify.json app/components/base/icons/src/public/common/Dify.tsx app/components/base/icons/src/public/common/Gdpr.json app/components/base/icons/src/public/common/Gdpr.tsx app/components/base/icons/src/public/common/Github.json app/components/base/icons/src/public/common/Github.tsx app/components/base/icons/src/public/common/Highlight.json app/components/base/icons/src/public/common/Highlight.tsx app/components/base/icons/src/public/common/Iso.json app/components/base/icons/src/public/common/Iso.tsx app/components/base/icons/src/public/common/Line3.json app/components/base/icons/src/public/common/Line3.tsx app/components/base/icons/src/public/common/Lock.json app/components/base/icons/src/public/common/Lock.tsx app/components/base/icons/src/public/common/MessageChatSquare.json app/components/base/icons/src/public/common/MessageChatSquare.tsx app/components/base/icons/src/public/common/MultiPathRetrieval.json app/components/base/icons/src/public/common/MultiPathRetrieval.tsx app/components/base/icons/src/public/common/NTo1Retrieval.json app/components/base/icons/src/public/common/NTo1Retrieval.tsx app/components/base/icons/src/public/common/Notion.json app/components/base/icons/src/public/common/Notion.tsx app/components/base/icons/src/public/common/Soc2.json app/components/base/icons/src/public/common/Soc2.tsx app/components/base/icons/src/public/common/SparklesSoft.json app/components/base/icons/src/public/common/SparklesSoft.tsx app/components/base/icons/src/public/common/index.ts app/components/base/icons/src/public/education/Triangle.json app/components/base/icons/src/public/education/Triangle.tsx app/components/base/icons/src/public/education/index.ts app/components/base/icons/src/public/files/Csv.json app/components/base/icons/src/public/files/Csv.tsx app/components/base/icons/src/public/files/Doc.json app/components/base/icons/src/public/files/Doc.tsx app/components/base/icons/src/public/files/Docx.json app/components/base/icons/src/public/files/Docx.tsx app/components/base/icons/src/public/files/Html.json app/components/base/icons/src/public/files/Html.tsx app/components/base/icons/src/public/files/Json.json app/components/base/icons/src/public/files/Json.tsx app/components/base/icons/src/public/files/Md.json app/components/base/icons/src/public/files/Md.tsx app/components/base/icons/src/public/files/Pdf.json app/components/base/icons/src/public/files/Pdf.tsx app/components/base/icons/src/public/files/Txt.json app/components/base/icons/src/public/files/Txt.tsx app/components/base/icons/src/public/files/Unknown.json app/components/base/icons/src/public/files/Unknown.tsx app/components/base/icons/src/public/files/Xlsx.json app/components/base/icons/src/public/files/Xlsx.tsx app/components/base/icons/src/public/files/Yaml.json app/components/base/icons/src/public/files/Yaml.tsx app/components/base/icons/src/public/files/index.ts app/components/base/icons/src/public/knowledge/Chunk.json app/components/base/icons/src/public/knowledge/Chunk.tsx app/components/base/icons/src/public/knowledge/Collapse.json app/components/base/icons/src/public/knowledge/Collapse.tsx app/components/base/icons/src/public/knowledge/GeneralType.json app/components/base/icons/src/public/knowledge/GeneralType.tsx app/components/base/icons/src/public/knowledge/LayoutRight2LineMod.json app/components/base/icons/src/public/knowledge/LayoutRight2LineMod.tsx app/components/base/icons/src/public/knowledge/ParentChildType.json app/components/base/icons/src/public/knowledge/ParentChildType.tsx app/components/base/icons/src/public/knowledge/SelectionMod.json app/components/base/icons/src/public/knowledge/SelectionMod.tsx app/components/base/icons/src/public/knowledge/index.ts app/components/base/icons/src/public/llm/Anthropic.json app/components/base/icons/src/public/llm/Anthropic.tsx app/components/base/icons/src/public/llm/AnthropicDark.json app/components/base/icons/src/public/llm/AnthropicDark.tsx app/components/base/icons/src/public/llm/AnthropicLight.json app/components/base/icons/src/public/llm/AnthropicLight.tsx app/components/base/icons/src/public/llm/AnthropicText.json app/components/base/icons/src/public/llm/AnthropicText.tsx app/components/base/icons/src/public/llm/AzureOpenaiService.json app/components/base/icons/src/public/llm/AzureOpenaiService.tsx app/components/base/icons/src/public/llm/AzureOpenaiServiceText.json app/components/base/icons/src/public/llm/AzureOpenaiServiceText.tsx app/components/base/icons/src/public/llm/Azureai.json app/components/base/icons/src/public/llm/Azureai.tsx app/components/base/icons/src/public/llm/AzureaiText.json app/components/base/icons/src/public/llm/AzureaiText.tsx app/components/base/icons/src/public/llm/Baichuan.json app/components/base/icons/src/public/llm/Baichuan.tsx app/components/base/icons/src/public/llm/BaichuanText.json app/components/base/icons/src/public/llm/BaichuanText.tsx app/components/base/icons/src/public/llm/Chatglm.json app/components/base/icons/src/public/llm/Chatglm.tsx app/components/base/icons/src/public/llm/ChatglmText.json app/components/base/icons/src/public/llm/ChatglmText.tsx app/components/base/icons/src/public/llm/Cohere.json app/components/base/icons/src/public/llm/Cohere.tsx app/components/base/icons/src/public/llm/CohereText.json app/components/base/icons/src/public/llm/CohereText.tsx app/components/base/icons/src/public/llm/Gpt3.json app/components/base/icons/src/public/llm/Gpt3.tsx app/components/base/icons/src/public/llm/Gpt4.json app/components/base/icons/src/public/llm/Gpt4.tsx app/components/base/icons/src/public/llm/Huggingface.json app/components/base/icons/src/public/llm/Huggingface.tsx app/components/base/icons/src/public/llm/HuggingfaceText.json app/components/base/icons/src/public/llm/HuggingfaceText.tsx app/components/base/icons/src/public/llm/HuggingfaceTextHub.json app/components/base/icons/src/public/llm/HuggingfaceTextHub.tsx app/components/base/icons/src/public/llm/IflytekSpark.json app/components/base/icons/src/public/llm/IflytekSpark.tsx app/components/base/icons/src/public/llm/IflytekSparkText.json app/components/base/icons/src/public/llm/IflytekSparkText.tsx app/components/base/icons/src/public/llm/IflytekSparkTextCn.json app/components/base/icons/src/public/llm/IflytekSparkTextCn.tsx app/components/base/icons/src/public/llm/Jina.json app/components/base/icons/src/public/llm/Jina.tsx app/components/base/icons/src/public/llm/JinaText.json app/components/base/icons/src/public/llm/JinaText.tsx app/components/base/icons/src/public/llm/Localai.json app/components/base/icons/src/public/llm/Localai.tsx app/components/base/icons/src/public/llm/LocalaiText.json app/components/base/icons/src/public/llm/LocalaiText.tsx app/components/base/icons/src/public/llm/Microsoft.json app/components/base/icons/src/public/llm/Microsoft.tsx app/components/base/icons/src/public/llm/OpenaiBlack.json app/components/base/icons/src/public/llm/OpenaiBlack.tsx app/components/base/icons/src/public/llm/OpenaiBlue.json app/components/base/icons/src/public/llm/OpenaiBlue.tsx app/components/base/icons/src/public/llm/OpenaiGreen.json app/components/base/icons/src/public/llm/OpenaiGreen.tsx app/components/base/icons/src/public/llm/OpenaiText.json app/components/base/icons/src/public/llm/OpenaiText.tsx app/components/base/icons/src/public/llm/OpenaiTransparent.json app/components/base/icons/src/public/llm/OpenaiTransparent.tsx app/components/base/icons/src/public/llm/OpenaiViolet.json app/components/base/icons/src/public/llm/OpenaiViolet.tsx app/components/base/icons/src/public/llm/Openllm.json app/components/base/icons/src/public/llm/Openllm.tsx app/components/base/icons/src/public/llm/OpenllmText.json app/components/base/icons/src/public/llm/OpenllmText.tsx app/components/base/icons/src/public/llm/Replicate.json app/components/base/icons/src/public/llm/Replicate.tsx app/components/base/icons/src/public/llm/ReplicateText.json app/components/base/icons/src/public/llm/ReplicateText.tsx app/components/base/icons/src/public/llm/XorbitsInference.json app/components/base/icons/src/public/llm/XorbitsInference.tsx app/components/base/icons/src/public/llm/XorbitsInferenceText.json app/components/base/icons/src/public/llm/XorbitsInferenceText.tsx app/components/base/icons/src/public/llm/Zhipuai.json app/components/base/icons/src/public/llm/Zhipuai.tsx app/components/base/icons/src/public/llm/ZhipuaiText.json app/components/base/icons/src/public/llm/ZhipuaiText.tsx app/components/base/icons/src/public/llm/ZhipuaiTextCn.json app/components/base/icons/src/public/llm/ZhipuaiTextCn.tsx app/components/base/icons/src/public/llm/index.ts app/components/base/icons/src/public/model/Checked.json app/components/base/icons/src/public/model/Checked.tsx app/components/base/icons/src/public/model/index.ts app/components/base/icons/src/public/other/DefaultToolIcon.json app/components/base/icons/src/public/other/DefaultToolIcon.tsx app/components/base/icons/src/public/other/Icon3Dots.json app/components/base/icons/src/public/other/Icon3Dots.tsx app/components/base/icons/src/public/other/Message3Fill.json app/components/base/icons/src/public/other/Message3Fill.tsx app/components/base/icons/src/public/other/RowStruct.json app/components/base/icons/src/public/other/RowStruct.tsx app/components/base/icons/src/public/other/index.ts app/components/base/icons/src/public/plugins/Google.json app/components/base/icons/src/public/plugins/Google.tsx app/components/base/icons/src/public/plugins/PartnerDark.json app/components/base/icons/src/public/plugins/PartnerDark.tsx app/components/base/icons/src/public/plugins/PartnerLight.json app/components/base/icons/src/public/plugins/PartnerLight.tsx app/components/base/icons/src/public/plugins/VerifiedDark.json app/components/base/icons/src/public/plugins/VerifiedDark.tsx app/components/base/icons/src/public/plugins/VerifiedLight.json app/components/base/icons/src/public/plugins/VerifiedLight.tsx app/components/base/icons/src/public/plugins/WebReader.json app/components/base/icons/src/public/plugins/WebReader.tsx app/components/base/icons/src/public/plugins/Wikipedia.json app/components/base/icons/src/public/plugins/Wikipedia.tsx app/components/base/icons/src/public/plugins/index.ts app/components/base/icons/src/public/thought/DataSet.json app/components/base/icons/src/public/thought/DataSet.tsx app/components/base/icons/src/public/thought/Loading.json app/components/base/icons/src/public/thought/Loading.tsx app/components/base/icons/src/public/thought/Search.json app/components/base/icons/src/public/thought/Search.tsx app/components/base/icons/src/public/thought/ThoughtList.json app/components/base/icons/src/public/thought/ThoughtList.tsx app/components/base/icons/src/public/thought/WebReader.json app/components/base/icons/src/public/thought/WebReader.tsx app/components/base/icons/src/public/thought/index.ts app/components/base/icons/src/public/tracing/LangfuseIcon.json app/components/base/icons/src/public/tracing/LangfuseIcon.tsx app/components/base/icons/src/public/tracing/LangfuseIconBig.json app/components/base/icons/src/public/tracing/LangfuseIconBig.tsx app/components/base/icons/src/public/tracing/LangsmithIcon.json app/components/base/icons/src/public/tracing/LangsmithIcon.tsx app/components/base/icons/src/public/tracing/LangsmithIconBig.json app/components/base/icons/src/public/tracing/LangsmithIconBig.tsx app/components/base/icons/src/public/tracing/OpikIcon.json app/components/base/icons/src/public/tracing/OpikIcon.tsx app/components/base/icons/src/public/tracing/OpikIconBig.json app/components/base/icons/src/public/tracing/OpikIconBig.tsx app/components/base/icons/src/public/tracing/TracingIcon.json app/components/base/icons/src/public/tracing/TracingIcon.tsx app/components/base/icons/src/public/tracing/WeaveIcon.json app/components/base/icons/src/public/tracing/WeaveIcon.tsx app/components/base/icons/src/public/tracing/WeaveIconBig.json app/components/base/icons/src/public/tracing/WeaveIconBig.tsx app/components/base/icons/src/public/tracing/index.ts app/components/base/icons/src/vender/features/Citations.json app/components/base/icons/src/vender/features/Citations.tsx app/components/base/icons/src/vender/features/ContentModeration.json app/components/base/icons/src/vender/features/ContentModeration.tsx app/components/base/icons/src/vender/features/Document.json app/components/base/icons/src/vender/features/Document.tsx app/components/base/icons/src/vender/features/FolderUpload.json app/components/base/icons/src/vender/features/FolderUpload.tsx app/components/base/icons/src/vender/features/LoveMessage.json app/components/base/icons/src/vender/features/LoveMessage.tsx app/components/base/icons/src/vender/features/MessageFast.json app/components/base/icons/src/vender/features/MessageFast.tsx app/components/base/icons/src/vender/features/Microphone01.json app/components/base/icons/src/vender/features/Microphone01.tsx app/components/base/icons/src/vender/features/TextToAudio.json app/components/base/icons/src/vender/features/TextToAudio.tsx app/components/base/icons/src/vender/features/VirtualAssistant.json app/components/base/icons/src/vender/features/VirtualAssistant.tsx app/components/base/icons/src/vender/features/Vision.json app/components/base/icons/src/vender/features/Vision.tsx app/components/base/icons/src/vender/features/index.ts app/components/base/icons/src/vender/line/alertsAndFeedback/AlertTriangle.json app/components/base/icons/src/vender/line/alertsAndFeedback/AlertTriangle.tsx app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsDown.json app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsDown.tsx app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsUp.json app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsUp.tsx app/components/base/icons/src/vender/line/alertsAndFeedback/index.ts app/components/base/icons/src/vender/line/arrows/ArrowNarrowLeft.json app/components/base/icons/src/vender/line/arrows/ArrowNarrowLeft.tsx app/components/base/icons/src/vender/line/arrows/ArrowUpRight.json app/components/base/icons/src/vender/line/arrows/ArrowUpRight.tsx app/components/base/icons/src/vender/line/arrows/ChevronDownDouble.json app/components/base/icons/src/vender/line/arrows/ChevronDownDouble.tsx app/components/base/icons/src/vender/line/arrows/ChevronRight.json app/components/base/icons/src/vender/line/arrows/ChevronRight.tsx app/components/base/icons/src/vender/line/arrows/ChevronSelectorVertical.json app/components/base/icons/src/vender/line/arrows/ChevronSelectorVertical.tsx app/components/base/icons/src/vender/line/arrows/RefreshCcw01.json app/components/base/icons/src/vender/line/arrows/RefreshCcw01.tsx app/components/base/icons/src/vender/line/arrows/RefreshCw05.json app/components/base/icons/src/vender/line/arrows/RefreshCw05.tsx app/components/base/icons/src/vender/line/arrows/ReverseLeft.json app/components/base/icons/src/vender/line/arrows/ReverseLeft.tsx app/components/base/icons/src/vender/line/arrows/index.ts app/components/base/icons/src/vender/line/communication/AiText.json app/components/base/icons/src/vender/line/communication/AiText.tsx app/components/base/icons/src/vender/line/communication/ChatBot.json app/components/base/icons/src/vender/line/communication/ChatBot.tsx app/components/base/icons/src/vender/line/communication/ChatBotSlim.json app/components/base/icons/src/vender/line/communication/ChatBotSlim.tsx app/components/base/icons/src/vender/line/communication/CuteRobot.json app/components/base/icons/src/vender/line/communication/CuteRobot.tsx app/components/base/icons/src/vender/line/communication/MessageCheckRemove.json app/components/base/icons/src/vender/line/communication/MessageCheckRemove.tsx app/components/base/icons/src/vender/line/communication/MessageFastPlus.json app/components/base/icons/src/vender/line/communication/MessageFastPlus.tsx app/components/base/icons/src/vender/line/communication/index.ts app/components/base/icons/src/vender/line/development/ArtificialBrain.json app/components/base/icons/src/vender/line/development/ArtificialBrain.tsx app/components/base/icons/src/vender/line/development/BarChartSquare02.json app/components/base/icons/src/vender/line/development/BarChartSquare02.tsx app/components/base/icons/src/vender/line/development/BracketsX.json app/components/base/icons/src/vender/line/development/BracketsX.tsx app/components/base/icons/src/vender/line/development/CodeBrowser.json app/components/base/icons/src/vender/line/development/CodeBrowser.tsx app/components/base/icons/src/vender/line/development/Container.json app/components/base/icons/src/vender/line/development/Container.tsx app/components/base/icons/src/vender/line/development/Database01.json app/components/base/icons/src/vender/line/development/Database01.tsx app/components/base/icons/src/vender/line/development/Database03.json app/components/base/icons/src/vender/line/development/Database03.tsx app/components/base/icons/src/vender/line/development/FileHeart02.json app/components/base/icons/src/vender/line/development/FileHeart02.tsx app/components/base/icons/src/vender/line/development/GitBranch01.json app/components/base/icons/src/vender/line/development/GitBranch01.tsx app/components/base/icons/src/vender/line/development/PromptEngineering.json app/components/base/icons/src/vender/line/development/PromptEngineering.tsx app/components/base/icons/src/vender/line/development/PuzzlePiece01.json app/components/base/icons/src/vender/line/development/PuzzlePiece01.tsx app/components/base/icons/src/vender/line/development/TerminalSquare.json app/components/base/icons/src/vender/line/development/TerminalSquare.tsx app/components/base/icons/src/vender/line/development/Variable.json app/components/base/icons/src/vender/line/development/Variable.tsx app/components/base/icons/src/vender/line/development/Webhooks.json app/components/base/icons/src/vender/line/development/Webhooks.tsx app/components/base/icons/src/vender/line/development/index.ts app/components/base/icons/src/vender/line/editor/AlignLeft.json app/components/base/icons/src/vender/line/editor/AlignLeft.tsx app/components/base/icons/src/vender/line/editor/BezierCurve03.json app/components/base/icons/src/vender/line/editor/BezierCurve03.tsx app/components/base/icons/src/vender/line/editor/Collapse.json app/components/base/icons/src/vender/line/editor/Collapse.tsx app/components/base/icons/src/vender/line/editor/Colors.json app/components/base/icons/src/vender/line/editor/Colors.tsx app/components/base/icons/src/vender/line/editor/ImageIndentLeft.json app/components/base/icons/src/vender/line/editor/ImageIndentLeft.tsx app/components/base/icons/src/vender/line/editor/LeftIndent02.json app/components/base/icons/src/vender/line/editor/LeftIndent02.tsx app/components/base/icons/src/vender/line/editor/LetterSpacing01.json app/components/base/icons/src/vender/line/editor/LetterSpacing01.tsx app/components/base/icons/src/vender/line/editor/TypeSquare.json app/components/base/icons/src/vender/line/editor/TypeSquare.tsx app/components/base/icons/src/vender/line/editor/index.ts app/components/base/icons/src/vender/line/education/BookOpen01.json app/components/base/icons/src/vender/line/education/BookOpen01.tsx app/components/base/icons/src/vender/line/education/index.ts app/components/base/icons/src/vender/line/files/Clipboard.json app/components/base/icons/src/vender/line/files/Clipboard.tsx app/components/base/icons/src/vender/line/files/ClipboardCheck.json app/components/base/icons/src/vender/line/files/ClipboardCheck.tsx app/components/base/icons/src/vender/line/files/File02.json app/components/base/icons/src/vender/line/files/File02.tsx app/components/base/icons/src/vender/line/files/FileArrow01.json app/components/base/icons/src/vender/line/files/FileArrow01.tsx app/components/base/icons/src/vender/line/files/FileCheck02.json app/components/base/icons/src/vender/line/files/FileCheck02.tsx app/components/base/icons/src/vender/line/files/FileDownload02.json app/components/base/icons/src/vender/line/files/FileDownload02.tsx app/components/base/icons/src/vender/line/files/FilePlus01.json app/components/base/icons/src/vender/line/files/FilePlus01.tsx app/components/base/icons/src/vender/line/files/FilePlus02.json app/components/base/icons/src/vender/line/files/FilePlus02.tsx app/components/base/icons/src/vender/line/files/FileText.json app/components/base/icons/src/vender/line/files/FileText.tsx app/components/base/icons/src/vender/line/files/FileUpload.json app/components/base/icons/src/vender/line/files/FileUpload.tsx app/components/base/icons/src/vender/line/files/Folder.json app/components/base/icons/src/vender/line/files/Folder.tsx app/components/base/icons/src/vender/line/files/index.ts app/components/base/icons/src/vender/line/financeAndECommerce/Balance.json app/components/base/icons/src/vender/line/financeAndECommerce/Balance.tsx app/components/base/icons/src/vender/line/financeAndECommerce/CoinsStacked01.json app/components/base/icons/src/vender/line/financeAndECommerce/CoinsStacked01.tsx app/components/base/icons/src/vender/line/financeAndECommerce/GoldCoin.json app/components/base/icons/src/vender/line/financeAndECommerce/GoldCoin.tsx app/components/base/icons/src/vender/line/financeAndECommerce/ReceiptList.json app/components/base/icons/src/vender/line/financeAndECommerce/ReceiptList.tsx app/components/base/icons/src/vender/line/financeAndECommerce/Tag01.json app/components/base/icons/src/vender/line/financeAndECommerce/Tag01.tsx app/components/base/icons/src/vender/line/financeAndECommerce/Tag03.json app/components/base/icons/src/vender/line/financeAndECommerce/Tag03.tsx app/components/base/icons/src/vender/line/financeAndECommerce/index.ts app/components/base/icons/src/vender/line/general/AtSign.json app/components/base/icons/src/vender/line/general/AtSign.tsx app/components/base/icons/src/vender/line/general/Bookmark.json app/components/base/icons/src/vender/line/general/Bookmark.tsx app/components/base/icons/src/vender/line/general/Check.json app/components/base/icons/src/vender/line/general/Check.tsx app/components/base/icons/src/vender/line/general/CheckDone01.json app/components/base/icons/src/vender/line/general/CheckDone01.tsx app/components/base/icons/src/vender/line/general/ChecklistSquare.json app/components/base/icons/src/vender/line/general/ChecklistSquare.tsx app/components/base/icons/src/vender/line/general/DotsGrid.json app/components/base/icons/src/vender/line/general/DotsGrid.tsx app/components/base/icons/src/vender/line/general/Edit02.json app/components/base/icons/src/vender/line/general/Edit02.tsx app/components/base/icons/src/vender/line/general/Edit04.json app/components/base/icons/src/vender/line/general/Edit04.tsx app/components/base/icons/src/vender/line/general/Edit05.json app/components/base/icons/src/vender/line/general/Edit05.tsx app/components/base/icons/src/vender/line/general/Hash02.json app/components/base/icons/src/vender/line/general/Hash02.tsx app/components/base/icons/src/vender/line/general/InfoCircle.json app/components/base/icons/src/vender/line/general/InfoCircle.tsx app/components/base/icons/src/vender/line/general/Link03.json app/components/base/icons/src/vender/line/general/Link03.tsx app/components/base/icons/src/vender/line/general/LinkExternal02.json app/components/base/icons/src/vender/line/general/LinkExternal02.tsx app/components/base/icons/src/vender/line/general/LogIn04.json app/components/base/icons/src/vender/line/general/LogIn04.tsx app/components/base/icons/src/vender/line/general/LogOut01.json app/components/base/icons/src/vender/line/general/LogOut01.tsx app/components/base/icons/src/vender/line/general/LogOut04.json app/components/base/icons/src/vender/line/general/LogOut04.tsx app/components/base/icons/src/vender/line/general/Menu01.json app/components/base/icons/src/vender/line/general/Menu01.tsx app/components/base/icons/src/vender/line/general/Pin01.json app/components/base/icons/src/vender/line/general/Pin01.tsx app/components/base/icons/src/vender/line/general/Pin02.json app/components/base/icons/src/vender/line/general/Pin02.tsx app/components/base/icons/src/vender/line/general/Plus02.json app/components/base/icons/src/vender/line/general/Plus02.tsx app/components/base/icons/src/vender/line/general/Refresh.json app/components/base/icons/src/vender/line/general/Refresh.tsx app/components/base/icons/src/vender/line/general/Settings01.json app/components/base/icons/src/vender/line/general/Settings01.tsx app/components/base/icons/src/vender/line/general/Settings04.json app/components/base/icons/src/vender/line/general/Settings04.tsx app/components/base/icons/src/vender/line/general/Target04.json app/components/base/icons/src/vender/line/general/Target04.tsx app/components/base/icons/src/vender/line/general/Upload03.json app/components/base/icons/src/vender/line/general/Upload03.tsx app/components/base/icons/src/vender/line/general/UploadCloud01.json app/components/base/icons/src/vender/line/general/UploadCloud01.tsx app/components/base/icons/src/vender/line/general/X.json app/components/base/icons/src/vender/line/general/X.tsx app/components/base/icons/src/vender/line/general/index.ts app/components/base/icons/src/vender/line/images/ImagePlus.json app/components/base/icons/src/vender/line/images/ImagePlus.tsx app/components/base/icons/src/vender/line/images/index.ts app/components/base/icons/src/vender/line/layout/AlignLeft01.json app/components/base/icons/src/vender/line/layout/AlignLeft01.tsx app/components/base/icons/src/vender/line/layout/AlignRight01.json app/components/base/icons/src/vender/line/layout/AlignRight01.tsx app/components/base/icons/src/vender/line/layout/Grid01.json app/components/base/icons/src/vender/line/layout/Grid01.tsx app/components/base/icons/src/vender/line/layout/LayoutGrid02.json app/components/base/icons/src/vender/line/layout/LayoutGrid02.tsx app/components/base/icons/src/vender/line/layout/index.ts app/components/base/icons/src/vender/line/mapsAndTravel/Globe01.json app/components/base/icons/src/vender/line/mapsAndTravel/Globe01.tsx app/components/base/icons/src/vender/line/mapsAndTravel/Route.json app/components/base/icons/src/vender/line/mapsAndTravel/Route.tsx app/components/base/icons/src/vender/line/mapsAndTravel/index.ts app/components/base/icons/src/vender/line/mediaAndDevices/Microphone01.json app/components/base/icons/src/vender/line/mediaAndDevices/Microphone01.tsx app/components/base/icons/src/vender/line/mediaAndDevices/PlayCircle.json app/components/base/icons/src/vender/line/mediaAndDevices/PlayCircle.tsx app/components/base/icons/src/vender/line/mediaAndDevices/SlidersH.json app/components/base/icons/src/vender/line/mediaAndDevices/SlidersH.tsx app/components/base/icons/src/vender/line/mediaAndDevices/Speaker.json app/components/base/icons/src/vender/line/mediaAndDevices/Speaker.tsx app/components/base/icons/src/vender/line/mediaAndDevices/Stop.json app/components/base/icons/src/vender/line/mediaAndDevices/Stop.tsx app/components/base/icons/src/vender/line/mediaAndDevices/StopCircle.json app/components/base/icons/src/vender/line/mediaAndDevices/StopCircle.tsx app/components/base/icons/src/vender/line/mediaAndDevices/index.ts app/components/base/icons/src/vender/line/others/Apps02.json app/components/base/icons/src/vender/line/others/Apps02.tsx app/components/base/icons/src/vender/line/others/BubbleX.json app/components/base/icons/src/vender/line/others/BubbleX.tsx app/components/base/icons/src/vender/line/others/Colors.json app/components/base/icons/src/vender/line/others/Colors.tsx app/components/base/icons/src/vender/line/others/DragHandle.json app/components/base/icons/src/vender/line/others/DragHandle.tsx app/components/base/icons/src/vender/line/others/Env.json app/components/base/icons/src/vender/line/others/Env.tsx app/components/base/icons/src/vender/line/others/Exchange02.json app/components/base/icons/src/vender/line/others/Exchange02.tsx app/components/base/icons/src/vender/line/others/FileCode.json app/components/base/icons/src/vender/line/others/FileCode.tsx app/components/base/icons/src/vender/line/others/GlobalVariable.json app/components/base/icons/src/vender/line/others/GlobalVariable.tsx app/components/base/icons/src/vender/line/others/Icon3Dots.json app/components/base/icons/src/vender/line/others/Icon3Dots.tsx app/components/base/icons/src/vender/line/others/LongArrowLeft.json app/components/base/icons/src/vender/line/others/LongArrowLeft.tsx app/components/base/icons/src/vender/line/others/LongArrowRight.json app/components/base/icons/src/vender/line/others/LongArrowRight.tsx app/components/base/icons/src/vender/line/others/Tools.json app/components/base/icons/src/vender/line/others/Tools.tsx app/components/base/icons/src/vender/line/others/index.ts app/components/base/icons/src/vender/line/shapes/CubeOutline.json app/components/base/icons/src/vender/line/shapes/CubeOutline.tsx app/components/base/icons/src/vender/line/shapes/index.ts app/components/base/icons/src/vender/line/time/ClockFastForward.json app/components/base/icons/src/vender/line/time/ClockFastForward.tsx app/components/base/icons/src/vender/line/time/ClockPlay.json app/components/base/icons/src/vender/line/time/ClockPlay.tsx app/components/base/icons/src/vender/line/time/ClockPlaySlim.json app/components/base/icons/src/vender/line/time/ClockPlaySlim.tsx app/components/base/icons/src/vender/line/time/ClockRefresh.json app/components/base/icons/src/vender/line/time/ClockRefresh.tsx app/components/base/icons/src/vender/line/time/index.ts app/components/base/icons/src/vender/line/users/User01.json app/components/base/icons/src/vender/line/users/User01.tsx app/components/base/icons/src/vender/line/users/Users01.json app/components/base/icons/src/vender/line/users/Users01.tsx app/components/base/icons/src/vender/line/users/index.ts app/components/base/icons/src/vender/line/weather/Stars02.json app/components/base/icons/src/vender/line/weather/Stars02.tsx app/components/base/icons/src/vender/line/weather/index.ts app/components/base/icons/src/vender/other/AnthropicText.json app/components/base/icons/src/vender/other/AnthropicText.tsx app/components/base/icons/src/vender/other/Generator.json app/components/base/icons/src/vender/other/Generator.tsx app/components/base/icons/src/vender/other/Group.json app/components/base/icons/src/vender/other/Group.tsx app/components/base/icons/src/vender/other/Openai.json app/components/base/icons/src/vender/other/Openai.tsx app/components/base/icons/src/vender/other/ReplayLine.json app/components/base/icons/src/vender/other/ReplayLine.tsx app/components/base/icons/src/vender/other/index.ts app/components/base/icons/src/vender/plugin/BoxSparkleFill.json app/components/base/icons/src/vender/plugin/BoxSparkleFill.tsx app/components/base/icons/src/vender/plugin/LeftCorner.json app/components/base/icons/src/vender/plugin/LeftCorner.tsx app/components/base/icons/src/vender/plugin/index.ts app/components/base/icons/src/vender/solid/FinanceAndECommerce/GoldCoin.json app/components/base/icons/src/vender/solid/FinanceAndECommerce/GoldCoin.tsx app/components/base/icons/src/vender/solid/FinanceAndECommerce/Scales02.json app/components/base/icons/src/vender/solid/FinanceAndECommerce/Scales02.tsx app/components/base/icons/src/vender/solid/FinanceAndECommerce/index.ts app/components/base/icons/src/vender/solid/alertsAndFeedback/AlertTriangle.json app/components/base/icons/src/vender/solid/alertsAndFeedback/AlertTriangle.tsx app/components/base/icons/src/vender/solid/alertsAndFeedback/index.ts app/components/base/icons/src/vender/solid/arrows/ChevronDown.json app/components/base/icons/src/vender/solid/arrows/ChevronDown.tsx app/components/base/icons/src/vender/solid/arrows/HighPriority.json app/components/base/icons/src/vender/solid/arrows/HighPriority.tsx app/components/base/icons/src/vender/solid/arrows/index.ts app/components/base/icons/src/vender/solid/communication/AiText.json app/components/base/icons/src/vender/solid/communication/AiText.tsx app/components/base/icons/src/vender/solid/communication/BubbleTextMod.json app/components/base/icons/src/vender/solid/communication/BubbleTextMod.tsx app/components/base/icons/src/vender/solid/communication/ChatBot.json app/components/base/icons/src/vender/solid/communication/ChatBot.tsx app/components/base/icons/src/vender/solid/communication/CuteRobot.json app/components/base/icons/src/vender/solid/communication/CuteRobot.tsx app/components/base/icons/src/vender/solid/communication/EditList.json app/components/base/icons/src/vender/solid/communication/EditList.tsx app/components/base/icons/src/vender/solid/communication/ListSparkle.json app/components/base/icons/src/vender/solid/communication/ListSparkle.tsx app/components/base/icons/src/vender/solid/communication/Logic.json app/components/base/icons/src/vender/solid/communication/Logic.tsx app/components/base/icons/src/vender/solid/communication/MessageDotsCircle.json app/components/base/icons/src/vender/solid/communication/MessageDotsCircle.tsx app/components/base/icons/src/vender/solid/communication/MessageFast.json app/components/base/icons/src/vender/solid/communication/MessageFast.tsx app/components/base/icons/src/vender/solid/communication/MessageHeartCircle.json app/components/base/icons/src/vender/solid/communication/MessageHeartCircle.tsx app/components/base/icons/src/vender/solid/communication/MessageSmileSquare.json app/components/base/icons/src/vender/solid/communication/MessageSmileSquare.tsx app/components/base/icons/src/vender/solid/communication/Send03.json app/components/base/icons/src/vender/solid/communication/Send03.tsx app/components/base/icons/src/vender/solid/communication/index.ts app/components/base/icons/src/vender/solid/development/ApiConnection.json app/components/base/icons/src/vender/solid/development/ApiConnection.tsx app/components/base/icons/src/vender/solid/development/ApiConnectionMod.json app/components/base/icons/src/vender/solid/development/ApiConnectionMod.tsx app/components/base/icons/src/vender/solid/development/BarChartSquare02.json app/components/base/icons/src/vender/solid/development/BarChartSquare02.tsx app/components/base/icons/src/vender/solid/development/Container.json app/components/base/icons/src/vender/solid/development/Container.tsx app/components/base/icons/src/vender/solid/development/Database02.json app/components/base/icons/src/vender/solid/development/Database02.tsx app/components/base/icons/src/vender/solid/development/Database03.json app/components/base/icons/src/vender/solid/development/Database03.tsx app/components/base/icons/src/vender/solid/development/FileHeart02.json app/components/base/icons/src/vender/solid/development/FileHeart02.tsx app/components/base/icons/src/vender/solid/development/PatternRecognition.json app/components/base/icons/src/vender/solid/development/PatternRecognition.tsx app/components/base/icons/src/vender/solid/development/PromptEngineering.json app/components/base/icons/src/vender/solid/development/PromptEngineering.tsx app/components/base/icons/src/vender/solid/development/PuzzlePiece01.json app/components/base/icons/src/vender/solid/development/PuzzlePiece01.tsx app/components/base/icons/src/vender/solid/development/Semantic.json app/components/base/icons/src/vender/solid/development/Semantic.tsx app/components/base/icons/src/vender/solid/development/TerminalSquare.json app/components/base/icons/src/vender/solid/development/TerminalSquare.tsx app/components/base/icons/src/vender/solid/development/Variable02.json app/components/base/icons/src/vender/solid/development/Variable02.tsx app/components/base/icons/src/vender/solid/development/index.ts app/components/base/icons/src/vender/solid/editor/Brush01.json app/components/base/icons/src/vender/solid/editor/Brush01.tsx app/components/base/icons/src/vender/solid/editor/Citations.json app/components/base/icons/src/vender/solid/editor/Citations.tsx app/components/base/icons/src/vender/solid/editor/Colors.json app/components/base/icons/src/vender/solid/editor/Colors.tsx app/components/base/icons/src/vender/solid/editor/Paragraph.json app/components/base/icons/src/vender/solid/editor/Paragraph.tsx app/components/base/icons/src/vender/solid/editor/TypeSquare.json app/components/base/icons/src/vender/solid/editor/TypeSquare.tsx app/components/base/icons/src/vender/solid/editor/index.ts app/components/base/icons/src/vender/solid/education/Beaker02.json app/components/base/icons/src/vender/solid/education/Beaker02.tsx app/components/base/icons/src/vender/solid/education/BubbleText.json app/components/base/icons/src/vender/solid/education/BubbleText.tsx app/components/base/icons/src/vender/solid/education/Heart02.json app/components/base/icons/src/vender/solid/education/Heart02.tsx app/components/base/icons/src/vender/solid/education/Unblur.json app/components/base/icons/src/vender/solid/education/Unblur.tsx app/components/base/icons/src/vender/solid/education/index.ts app/components/base/icons/src/vender/solid/files/File05.json app/components/base/icons/src/vender/solid/files/File05.tsx app/components/base/icons/src/vender/solid/files/FileSearch02.json app/components/base/icons/src/vender/solid/files/FileSearch02.tsx app/components/base/icons/src/vender/solid/files/FileZip.json app/components/base/icons/src/vender/solid/files/FileZip.tsx app/components/base/icons/src/vender/solid/files/Folder.json app/components/base/icons/src/vender/solid/files/Folder.tsx app/components/base/icons/src/vender/solid/files/index.ts app/components/base/icons/src/vender/solid/general/AnswerTriangle.json app/components/base/icons/src/vender/solid/general/AnswerTriangle.tsx app/components/base/icons/src/vender/solid/general/ArrowDownRoundFill.json app/components/base/icons/src/vender/solid/general/ArrowDownRoundFill.tsx app/components/base/icons/src/vender/solid/general/CheckCircle.json app/components/base/icons/src/vender/solid/general/CheckCircle.tsx app/components/base/icons/src/vender/solid/general/CheckDone01.json app/components/base/icons/src/vender/solid/general/CheckDone01.tsx app/components/base/icons/src/vender/solid/general/Download02.json app/components/base/icons/src/vender/solid/general/Download02.tsx app/components/base/icons/src/vender/solid/general/Edit03.json app/components/base/icons/src/vender/solid/general/Edit03.tsx app/components/base/icons/src/vender/solid/general/Edit04.json app/components/base/icons/src/vender/solid/general/Edit04.tsx app/components/base/icons/src/vender/solid/general/Eye.json app/components/base/icons/src/vender/solid/general/Eye.tsx app/components/base/icons/src/vender/solid/general/Github.json app/components/base/icons/src/vender/solid/general/Github.tsx app/components/base/icons/src/vender/solid/general/MessageClockCircle.json app/components/base/icons/src/vender/solid/general/MessageClockCircle.tsx app/components/base/icons/src/vender/solid/general/PlusCircle.json app/components/base/icons/src/vender/solid/general/PlusCircle.tsx app/components/base/icons/src/vender/solid/general/QuestionTriangle.json app/components/base/icons/src/vender/solid/general/QuestionTriangle.tsx app/components/base/icons/src/vender/solid/general/SearchMd.json app/components/base/icons/src/vender/solid/general/SearchMd.tsx app/components/base/icons/src/vender/solid/general/Target04.json app/components/base/icons/src/vender/solid/general/Target04.tsx app/components/base/icons/src/vender/solid/general/Tool03.json app/components/base/icons/src/vender/solid/general/Tool03.tsx app/components/base/icons/src/vender/solid/general/XCircle.json app/components/base/icons/src/vender/solid/general/XCircle.tsx app/components/base/icons/src/vender/solid/general/ZapFast.json app/components/base/icons/src/vender/solid/general/ZapFast.tsx app/components/base/icons/src/vender/solid/general/ZapNarrow.json app/components/base/icons/src/vender/solid/general/ZapNarrow.tsx app/components/base/icons/src/vender/solid/general/index.ts app/components/base/icons/src/vender/solid/layout/Grid01.json app/components/base/icons/src/vender/solid/layout/Grid01.tsx app/components/base/icons/src/vender/solid/layout/index.ts app/components/base/icons/src/vender/solid/mapsAndTravel/Globe06.json app/components/base/icons/src/vender/solid/mapsAndTravel/Globe06.tsx app/components/base/icons/src/vender/solid/mapsAndTravel/Route.json app/components/base/icons/src/vender/solid/mapsAndTravel/Route.tsx app/components/base/icons/src/vender/solid/mapsAndTravel/index.ts app/components/base/icons/src/vender/solid/mediaAndDevices/AudioSupportIcon.json app/components/base/icons/src/vender/solid/mediaAndDevices/AudioSupportIcon.tsx app/components/base/icons/src/vender/solid/mediaAndDevices/DocumentSupportIcon.json app/components/base/icons/src/vender/solid/mediaAndDevices/DocumentSupportIcon.tsx app/components/base/icons/src/vender/solid/mediaAndDevices/MagicBox.json app/components/base/icons/src/vender/solid/mediaAndDevices/MagicBox.tsx app/components/base/icons/src/vender/solid/mediaAndDevices/MagicEyes.json app/components/base/icons/src/vender/solid/mediaAndDevices/MagicEyes.tsx app/components/base/icons/src/vender/solid/mediaAndDevices/MagicWand.json app/components/base/icons/src/vender/solid/mediaAndDevices/MagicWand.tsx app/components/base/icons/src/vender/solid/mediaAndDevices/Microphone01.json app/components/base/icons/src/vender/solid/mediaAndDevices/Microphone01.tsx app/components/base/icons/src/vender/solid/mediaAndDevices/Play.json app/components/base/icons/src/vender/solid/mediaAndDevices/Play.tsx app/components/base/icons/src/vender/solid/mediaAndDevices/Robot.json app/components/base/icons/src/vender/solid/mediaAndDevices/Robot.tsx app/components/base/icons/src/vender/solid/mediaAndDevices/Sliders02.json app/components/base/icons/src/vender/solid/mediaAndDevices/Sliders02.tsx app/components/base/icons/src/vender/solid/mediaAndDevices/Speaker.json app/components/base/icons/src/vender/solid/mediaAndDevices/Speaker.tsx app/components/base/icons/src/vender/solid/mediaAndDevices/StopCircle.json app/components/base/icons/src/vender/solid/mediaAndDevices/StopCircle.tsx app/components/base/icons/src/vender/solid/mediaAndDevices/VideoSupportIcon.json app/components/base/icons/src/vender/solid/mediaAndDevices/VideoSupportIcon.tsx app/components/base/icons/src/vender/solid/mediaAndDevices/index.ts app/components/base/icons/src/vender/solid/security/Lock01.json app/components/base/icons/src/vender/solid/security/Lock01.tsx app/components/base/icons/src/vender/solid/security/index.ts app/components/base/icons/src/vender/solid/shapes/Corner.json app/components/base/icons/src/vender/solid/shapes/Corner.tsx app/components/base/icons/src/vender/solid/shapes/Star04.json app/components/base/icons/src/vender/solid/shapes/Star04.tsx app/components/base/icons/src/vender/solid/shapes/Star06.json app/components/base/icons/src/vender/solid/shapes/Star06.tsx app/components/base/icons/src/vender/solid/shapes/index.ts app/components/base/icons/src/vender/solid/users/User01.json app/components/base/icons/src/vender/solid/users/User01.tsx app/components/base/icons/src/vender/solid/users/UserEdit02.json app/components/base/icons/src/vender/solid/users/UserEdit02.tsx app/components/base/icons/src/vender/solid/users/Users01.json app/components/base/icons/src/vender/solid/users/Users01.tsx app/components/base/icons/src/vender/solid/users/UsersPlus.json app/components/base/icons/src/vender/solid/users/UsersPlus.tsx app/components/base/icons/src/vender/solid/users/index.ts app/components/base/icons/src/vender/workflow/Agent.json app/components/base/icons/src/vender/workflow/Agent.tsx app/components/base/icons/src/vender/workflow/Answer.json app/components/base/icons/src/vender/workflow/Answer.tsx app/components/base/icons/src/vender/workflow/Assigner.json app/components/base/icons/src/vender/workflow/Assigner.tsx app/components/base/icons/src/vender/workflow/Code.json app/components/base/icons/src/vender/workflow/Code.tsx app/components/base/icons/src/vender/workflow/DocsExtractor.json app/components/base/icons/src/vender/workflow/DocsExtractor.tsx app/components/base/icons/src/vender/workflow/End.json app/components/base/icons/src/vender/workflow/End.tsx app/components/base/icons/src/vender/workflow/Home.json app/components/base/icons/src/vender/workflow/Home.tsx app/components/base/icons/src/vender/workflow/Http.json app/components/base/icons/src/vender/workflow/Http.tsx app/components/base/icons/src/vender/workflow/IfElse.json app/components/base/icons/src/vender/workflow/IfElse.tsx app/components/base/icons/src/vender/workflow/Iteration.json app/components/base/icons/src/vender/workflow/Iteration.tsx app/components/base/icons/src/vender/workflow/IterationStart.json app/components/base/icons/src/vender/workflow/IterationStart.tsx app/components/base/icons/src/vender/workflow/Jinja.json app/components/base/icons/src/vender/workflow/Jinja.tsx app/components/base/icons/src/vender/workflow/KnowledgeRetrieval.json app/components/base/icons/src/vender/workflow/KnowledgeRetrieval.tsx app/components/base/icons/src/vender/workflow/ListFilter.json app/components/base/icons/src/vender/workflow/ListFilter.tsx app/components/base/icons/src/vender/workflow/Llm.json app/components/base/icons/src/vender/workflow/Llm.tsx app/components/base/icons/src/vender/workflow/Loop.json app/components/base/icons/src/vender/workflow/Loop.tsx app/components/base/icons/src/vender/workflow/LoopEnd.json app/components/base/icons/src/vender/workflow/LoopEnd.tsx app/components/base/icons/src/vender/workflow/ParameterExtractor.json app/components/base/icons/src/vender/workflow/ParameterExtractor.tsx app/components/base/icons/src/vender/workflow/QuestionClassifier.json app/components/base/icons/src/vender/workflow/QuestionClassifier.tsx app/components/base/icons/src/vender/workflow/TemplatingTransform.json app/components/base/icons/src/vender/workflow/TemplatingTransform.tsx app/components/base/icons/src/vender/workflow/VariableX.json app/components/base/icons/src/vender/workflow/VariableX.tsx app/components/base/icons/src/vender/workflow/index.ts app/components/base/icons/utils.spec.ts app/components/base/icons/utils.ts app/components/base/image-gallery/index.tsx app/components/base/image-gallery/style.module.css app/components/base/image-uploader/audio-preview.tsx app/components/base/image-uploader/chat-image-uploader.tsx app/components/base/image-uploader/hooks.ts app/components/base/image-uploader/image-link-input.tsx app/components/base/image-uploader/image-list.tsx app/components/base/image-uploader/image-preview.tsx app/components/base/image-uploader/text-generation-image-uploader.tsx app/components/base/image-uploader/uploader.tsx app/components/base/image-uploader/utils.ts app/components/base/image-uploader/video-preview.tsx app/components/base/input-number/index.spec.tsx app/components/base/input-number/index.tsx app/components/base/input/index.spec.tsx app/components/base/input/index.tsx app/components/base/install-button/index.tsx app/components/base/linked-apps-panel/index.tsx app/components/base/list-empty/horizontal-line.tsx app/components/base/list-empty/index.tsx app/components/base/list-empty/vertical-line.tsx app/components/base/loading/index.spec.tsx app/components/base/loading/index.tsx app/components/base/loading/style.css app/components/base/logo/dify-logo.tsx app/components/base/logo/logo-embedded-chat-avatar.tsx app/components/base/logo/logo-embedded-chat-header.tsx app/components/base/markdown-blocks/button.tsx app/components/base/markdown-blocks/form.tsx app/components/base/markdown-blocks/music.tsx app/components/base/markdown-blocks/think-block.tsx app/components/base/markdown.tsx app/components/base/mermaid/index.tsx app/components/base/mermaid/utils.spec.ts app/components/base/mermaid/utils.ts app/components/base/message-log-modal/index.tsx app/components/base/modal-like-wrap/index.tsx app/components/base/modal/index.css app/components/base/modal/index.tsx app/components/base/new-audio-button/index.tsx app/components/base/notion-icon/index.tsx app/components/base/notion-page-selector/assets/clear.svg app/components/base/notion-page-selector/assets/down-arrow.svg app/components/base/notion-page-selector/assets/notion-empty-page.svg app/components/base/notion-page-selector/assets/notion-page.svg app/components/base/notion-page-selector/assets/search.svg app/components/base/notion-page-selector/assets/setting.svg app/components/base/notion-page-selector/base.tsx app/components/base/notion-page-selector/index.tsx app/components/base/notion-page-selector/notion-page-selector-modal/index.module.css app/components/base/notion-page-selector/notion-page-selector-modal/index.tsx app/components/base/notion-page-selector/page-selector/index.tsx app/components/base/notion-page-selector/search-input/index.tsx app/components/base/notion-page-selector/workspace-selector/index.tsx app/components/base/pagination/hook.ts app/components/base/pagination/index.tsx app/components/base/pagination/pagination.tsx app/components/base/pagination/type.ts app/components/base/param-item/index.tsx app/components/base/param-item/score-threshold-item.tsx app/components/base/param-item/top-k-item.tsx app/components/base/popover/index.tsx app/components/base/portal-to-follow-elem/index.spec.tsx app/components/base/portal-to-follow-elem/index.tsx app/components/base/premium-badge/index.css app/components/base/premium-badge/index.tsx app/components/base/progress-bar/index.tsx app/components/base/progress-bar/progress-circle.tsx app/components/base/prompt-editor/constants.tsx app/components/base/prompt-editor/hooks.ts app/components/base/prompt-editor/index.tsx app/components/base/prompt-editor/plugins/component-picker-block/hooks.tsx app/components/base/prompt-editor/plugins/component-picker-block/index.tsx app/components/base/prompt-editor/plugins/component-picker-block/menu.tsx app/components/base/prompt-editor/plugins/component-picker-block/prompt-option.tsx app/components/base/prompt-editor/plugins/component-picker-block/variable-option.tsx app/components/base/prompt-editor/plugins/context-block/component.tsx app/components/base/prompt-editor/plugins/context-block/context-block-replacement-block.tsx app/components/base/prompt-editor/plugins/context-block/index.tsx app/components/base/prompt-editor/plugins/context-block/node.tsx app/components/base/prompt-editor/plugins/custom-text/node.tsx app/components/base/prompt-editor/plugins/history-block/component.tsx app/components/base/prompt-editor/plugins/history-block/history-block-replacement-block.tsx app/components/base/prompt-editor/plugins/history-block/index.tsx app/components/base/prompt-editor/plugins/history-block/node.tsx app/components/base/prompt-editor/plugins/on-blur-or-focus-block.tsx app/components/base/prompt-editor/plugins/placeholder.tsx app/components/base/prompt-editor/plugins/query-block/component.tsx app/components/base/prompt-editor/plugins/query-block/index.tsx app/components/base/prompt-editor/plugins/query-block/node.tsx app/components/base/prompt-editor/plugins/query-block/query-block-replacement-block.tsx app/components/base/prompt-editor/plugins/tree-view.tsx app/components/base/prompt-editor/plugins/update-block.tsx app/components/base/prompt-editor/plugins/variable-block/index.tsx app/components/base/prompt-editor/plugins/variable-value-block/index.tsx app/components/base/prompt-editor/plugins/variable-value-block/node.tsx app/components/base/prompt-editor/plugins/variable-value-block/utils.ts app/components/base/prompt-editor/plugins/workflow-variable-block/component.tsx app/components/base/prompt-editor/plugins/workflow-variable-block/index.tsx app/components/base/prompt-editor/plugins/workflow-variable-block/node.tsx app/components/base/prompt-editor/plugins/workflow-variable-block/workflow-variable-block-replacement-block.tsx app/components/base/prompt-editor/types.ts app/components/base/prompt-editor/utils.ts app/components/base/prompt-log-modal/card.tsx app/components/base/prompt-log-modal/index.tsx app/components/base/qrcode/index.tsx app/components/base/radio-card/index.tsx app/components/base/radio-card/simple/index.tsx app/components/base/radio-card/simple/style.module.css app/components/base/radio/component/group/index.tsx app/components/base/radio/component/radio/index.tsx app/components/base/radio/context/index.tsx app/components/base/radio/index.tsx app/components/base/radio/style.module.css app/components/base/radio/ui.tsx app/components/base/search-input/index.tsx app/components/base/segmented-control/index.tsx app/components/base/select/index.tsx app/components/base/select/locale.tsx app/components/base/select/pure.tsx app/components/base/simple-pie-chart/index.module.css app/components/base/simple-pie-chart/index.tsx app/components/base/skeleton/index.tsx app/components/base/slider/index.tsx app/components/base/slider/style.css app/components/base/sort/index.tsx app/components/base/spinner/index.spec.tsx app/components/base/spinner/index.tsx app/components/base/svg-gallery/index.tsx app/components/base/svg/index.tsx app/components/base/svg/style.module.css app/components/base/switch/index.tsx app/components/base/tab-header/index.tsx app/components/base/tab-slider-new/index.tsx app/components/base/tab-slider-plain/index.tsx app/components/base/tab-slider/index.tsx app/components/base/tag-input/index.tsx app/components/base/tag-management/constant.ts app/components/base/tag-management/filter.tsx app/components/base/tag-management/index.tsx app/components/base/tag-management/selector.tsx app/components/base/tag-management/store.ts app/components/base/tag-management/tag-item-editor.tsx app/components/base/tag-management/tag-remove-modal.tsx app/components/base/tag/index.tsx app/components/base/text-generation/hooks.ts app/components/base/text-generation/types.ts app/components/base/textarea/index.tsx app/components/base/theme-selector.tsx app/components/base/theme-switcher.tsx app/components/base/toast/index.spec.tsx app/components/base/toast/index.tsx app/components/base/toast/style.module.css app/components/base/tooltip/content.tsx app/components/base/tooltip/index.spec.tsx app/components/base/tooltip/index.tsx app/components/base/video-gallery/VideoPlayer.module.css app/components/base/video-gallery/VideoPlayer.tsx app/components/base/video-gallery/index.tsx app/components/base/voice-input/index.module.css app/components/base/voice-input/index.tsx app/components/base/voice-input/utils.ts app/components/base/with-input-validation/index.spec.tsx app/components/base/with-input-validation/index.tsx app/components/billing/annotation-full/index.tsx app/components/billing/annotation-full/modal.tsx app/components/billing/annotation-full/style.module.css app/components/billing/annotation-full/usage.tsx app/components/billing/apps-full-in-dialog/index.tsx app/components/billing/apps-full-in-dialog/style.module.css app/components/billing/billing-page/index.tsx app/components/billing/config.ts app/components/billing/header-billing-btn/index.tsx app/components/billing/plan/index.tsx app/components/billing/pricing/index.tsx app/components/billing/pricing/plan-item.tsx app/components/billing/pricing/select-plan-range.tsx app/components/billing/pricing/self-hosted-plan-item.tsx app/components/billing/priority-label/index.tsx app/components/billing/progress-bar/index.tsx app/components/billing/type.ts app/components/billing/upgrade-btn/index.tsx app/components/billing/upgrade-btn/style.module.css app/components/billing/usage-info/apps-info.tsx app/components/billing/usage-info/index.tsx app/components/billing/usage-info/vector-space-info.tsx app/components/billing/utils/index.ts app/components/billing/vector-space-full/index.tsx app/components/billing/vector-space-full/style.module.css app/components/browser-initor.tsx app/components/custom/custom-page/index.tsx app/components/custom/custom-web-app-brand/index.tsx app/components/custom/custom-web-app-brand/style.module.css app/components/custom/style.module.css app/components/datasets/api/index.tsx app/components/datasets/chunk.tsx app/components/datasets/common/check-rerank-model.ts app/components/datasets/common/chunking-mode-label.tsx app/components/datasets/common/document-file-icon.tsx app/components/datasets/common/document-picker/document-list.tsx app/components/datasets/common/document-picker/index.tsx app/components/datasets/common/document-picker/preview-document-picker.tsx app/components/datasets/common/document-status-with-action/auto-disabled-document.tsx app/components/datasets/common/document-status-with-action/index-failed.tsx app/components/datasets/common/document-status-with-action/status-with-action.tsx app/components/datasets/common/economical-retrieval-method-config/index.tsx app/components/datasets/common/retrieval-method-config/index.tsx app/components/datasets/common/retrieval-method-info/index.tsx app/components/datasets/common/retrieval-param-config/index.tsx app/components/datasets/create/assets/Icon-3-dots.svg app/components/datasets/create/assets/Loading.svg app/components/datasets/create/assets/alert-triangle.svg app/components/datasets/create/assets/annotation-info.svg app/components/datasets/create/assets/arrow-narrow-left.svg app/components/datasets/create/assets/book-open-01.svg app/components/datasets/create/assets/check.svg app/components/datasets/create/assets/close.svg app/components/datasets/create/assets/csv.svg app/components/datasets/create/assets/doc.svg app/components/datasets/create/assets/docx.svg app/components/datasets/create/assets/family-mod.svg app/components/datasets/create/assets/file-list-3-fill.svg app/components/datasets/create/assets/file.svg app/components/datasets/create/assets/folder-plus.svg app/components/datasets/create/assets/gold.svg app/components/datasets/create/assets/html.svg app/components/datasets/create/assets/jina.png app/components/datasets/create/assets/json.svg app/components/datasets/create/assets/md.svg app/components/datasets/create/assets/normal.svg app/components/datasets/create/assets/note-mod.svg app/components/datasets/create/assets/notion.svg app/components/datasets/create/assets/option-card-effect-blue.svg app/components/datasets/create/assets/option-card-effect-orange.svg app/components/datasets/create/assets/option-card-effect-purple.svg app/components/datasets/create/assets/pattern-recognition-mod.svg app/components/datasets/create/assets/pdf.svg app/components/datasets/create/assets/piggy-bank-01.svg app/components/datasets/create/assets/piggy-bank-mod.svg app/components/datasets/create/assets/progress-indicator.svg app/components/datasets/create/assets/rerank.svg app/components/datasets/create/assets/research-mod.svg app/components/datasets/create/assets/selection-mod.svg app/components/datasets/create/assets/setting-gear-mod.svg app/components/datasets/create/assets/sliders-02.svg app/components/datasets/create/assets/star-07.svg app/components/datasets/create/assets/star.svg app/components/datasets/create/assets/trash.svg app/components/datasets/create/assets/txt.svg app/components/datasets/create/assets/unknown.svg app/components/datasets/create/assets/upload-cloud-01.svg app/components/datasets/create/assets/watercrawl.svg app/components/datasets/create/assets/web.svg app/components/datasets/create/assets/xlsx.svg app/components/datasets/create/assets/zap-fast.svg app/components/datasets/create/embedding-process/index.module.css app/components/datasets/create/embedding-process/index.tsx app/components/datasets/create/empty-dataset-creation-modal/index.module.css app/components/datasets/create/empty-dataset-creation-modal/index.tsx app/components/datasets/create/file-preview/index.module.css app/components/datasets/create/file-preview/index.tsx app/components/datasets/create/file-uploader/index.module.css app/components/datasets/create/file-uploader/index.tsx app/components/datasets/create/icons.ts app/components/datasets/create/index.module.css app/components/datasets/create/index.tsx app/components/datasets/create/notion-page-preview/index.module.css app/components/datasets/create/notion-page-preview/index.tsx app/components/datasets/create/step-one/index.module.css app/components/datasets/create/step-one/index.tsx app/components/datasets/create/step-three/index.module.css app/components/datasets/create/step-three/index.tsx app/components/datasets/create/step-two/escape.ts app/components/datasets/create/step-two/index.module.css app/components/datasets/create/step-two/index.tsx app/components/datasets/create/step-two/inputs.tsx app/components/datasets/create/step-two/language-select/index.tsx app/components/datasets/create/step-two/option-card.tsx app/components/datasets/create/step-two/preview-item/index.tsx app/components/datasets/create/step-two/unescape.ts app/components/datasets/create/stepper/index.tsx app/components/datasets/create/stepper/step.tsx app/components/datasets/create/stop-embedding-modal/index.module.css app/components/datasets/create/stop-embedding-modal/index.tsx app/components/datasets/create/top-bar/index.tsx app/components/datasets/create/website/base/checkbox-with-label.tsx app/components/datasets/create/website/base/crawled-result-item.tsx app/components/datasets/create/website/base/crawled-result.tsx app/components/datasets/create/website/base/crawling.tsx app/components/datasets/create/website/base/error-message.tsx app/components/datasets/create/website/base/field.tsx app/components/datasets/create/website/base/input.tsx app/components/datasets/create/website/base/mock-crawl-result.ts app/components/datasets/create/website/base/options-wrap.tsx app/components/datasets/create/website/base/url-input.tsx app/components/datasets/create/website/firecrawl/header.tsx app/components/datasets/create/website/firecrawl/index.tsx app/components/datasets/create/website/firecrawl/options.tsx app/components/datasets/create/website/index.module.css app/components/datasets/create/website/index.tsx app/components/datasets/create/website/jina-reader/base/checkbox-with-label.tsx app/components/datasets/create/website/jina-reader/base/error-message.tsx app/components/datasets/create/website/jina-reader/base/field.tsx app/components/datasets/create/website/jina-reader/base/input.tsx app/components/datasets/create/website/jina-reader/base/options-wrap.tsx app/components/datasets/create/website/jina-reader/base/url-input.tsx app/components/datasets/create/website/jina-reader/header.tsx app/components/datasets/create/website/jina-reader/index.tsx app/components/datasets/create/website/jina-reader/options.tsx app/components/datasets/create/website/no-data.tsx app/components/datasets/create/website/preview.tsx app/components/datasets/create/website/watercrawl/header.tsx app/components/datasets/create/website/watercrawl/index.tsx app/components/datasets/create/website/watercrawl/options.tsx app/components/datasets/documents/assets/atSign.svg app/components/datasets/documents/assets/bezierCurve.svg app/components/datasets/documents/assets/bookOpen.svg app/components/datasets/documents/assets/briefcase.svg app/components/datasets/documents/assets/cardLoading.svg app/components/datasets/documents/assets/file.svg app/components/datasets/documents/assets/globe.svg app/components/datasets/documents/assets/graduationHat.svg app/components/datasets/documents/assets/hitLoading.svg app/components/datasets/documents/assets/layoutRightClose.svg app/components/datasets/documents/assets/layoutRightShow.svg app/components/datasets/documents/assets/messageTextCircle.svg app/components/datasets/documents/assets/normal.svg app/components/datasets/documents/assets/star.svg app/components/datasets/documents/assets/target.svg app/components/datasets/documents/assets/typeSquare.svg app/components/datasets/documents/detail/batch-modal/csv-downloader.tsx app/components/datasets/documents/detail/batch-modal/csv-uploader.tsx app/components/datasets/documents/detail/batch-modal/index.tsx app/components/datasets/documents/detail/completed/child-segment-detail.tsx app/components/datasets/documents/detail/completed/child-segment-list.tsx app/components/datasets/documents/detail/completed/common/action-buttons.tsx app/components/datasets/documents/detail/completed/common/add-another.tsx app/components/datasets/documents/detail/completed/common/batch-action.tsx app/components/datasets/documents/detail/completed/common/chunk-content.tsx app/components/datasets/documents/detail/completed/common/dot.tsx app/components/datasets/documents/detail/completed/common/empty.tsx app/components/datasets/documents/detail/completed/common/full-screen-drawer.tsx app/components/datasets/documents/detail/completed/common/keywords.tsx app/components/datasets/documents/detail/completed/common/regeneration-modal.tsx app/components/datasets/documents/detail/completed/common/segment-index-tag.tsx app/components/datasets/documents/detail/completed/common/tag.tsx app/components/datasets/documents/detail/completed/display-toggle.tsx app/components/datasets/documents/detail/completed/index.tsx app/components/datasets/documents/detail/completed/new-child-segment.tsx app/components/datasets/documents/detail/completed/segment-card/chunk-content.tsx app/components/datasets/documents/detail/completed/segment-card/index.tsx app/components/datasets/documents/detail/completed/segment-detail.tsx app/components/datasets/documents/detail/completed/segment-list.tsx app/components/datasets/documents/detail/completed/skeleton/full-doc-list-skeleton.tsx app/components/datasets/documents/detail/completed/skeleton/general-list-skeleton.tsx app/components/datasets/documents/detail/completed/skeleton/paragraph-list-skeleton.tsx app/components/datasets/documents/detail/completed/skeleton/parent-chunk-card-skeleton.tsx app/components/datasets/documents/detail/completed/status-item.tsx app/components/datasets/documents/detail/completed/style.module.css app/components/datasets/documents/detail/embedding/index.tsx app/components/datasets/documents/detail/embedding/skeleton/index.tsx app/components/datasets/documents/detail/embedding/style.module.css app/components/datasets/documents/detail/index.tsx app/components/datasets/documents/detail/metadata/index.tsx app/components/datasets/documents/detail/metadata/style.module.css app/components/datasets/documents/detail/new-segment.tsx app/components/datasets/documents/detail/segment-add/index.tsx app/components/datasets/documents/detail/settings/index.tsx app/components/datasets/documents/detail/style.module.css app/components/datasets/documents/index.tsx app/components/datasets/documents/list.tsx app/components/datasets/documents/rename-modal.tsx app/components/datasets/documents/style.module.css app/components/datasets/external-api/declarations.ts app/components/datasets/external-api/external-api-modal/Form.tsx app/components/datasets/external-api/external-api-modal/index.tsx app/components/datasets/external-api/external-api-panel/index.tsx app/components/datasets/external-api/external-knowledge-api-card/index.tsx app/components/datasets/external-knowledge-base/connector/index.tsx app/components/datasets/external-knowledge-base/create/ExternalApiSelect.tsx app/components/datasets/external-knowledge-base/create/ExternalApiSelection.tsx app/components/datasets/external-knowledge-base/create/InfoPanel.tsx app/components/datasets/external-knowledge-base/create/KnowledgeBaseInfo.tsx app/components/datasets/external-knowledge-base/create/RetrievalSettings.tsx app/components/datasets/external-knowledge-base/create/declarations.ts app/components/datasets/external-knowledge-base/create/index.tsx app/components/datasets/formatted-text/flavours/edit-slice.tsx app/components/datasets/formatted-text/flavours/preview-slice.tsx app/components/datasets/formatted-text/flavours/shared.tsx app/components/datasets/formatted-text/flavours/type.ts app/components/datasets/formatted-text/formatted.tsx app/components/datasets/hit-testing/assets/clock.svg app/components/datasets/hit-testing/assets/grid.svg app/components/datasets/hit-testing/assets/plugin.svg app/components/datasets/hit-testing/components/child-chunks-item.tsx app/components/datasets/hit-testing/components/chunk-detail-modal.tsx app/components/datasets/hit-testing/components/result-item-external.tsx app/components/datasets/hit-testing/components/result-item-footer.tsx app/components/datasets/hit-testing/components/result-item-meta.tsx app/components/datasets/hit-testing/components/result-item.tsx app/components/datasets/hit-testing/components/score.tsx app/components/datasets/hit-testing/index.tsx app/components/datasets/hit-testing/modify-external-retrieval-modal.tsx app/components/datasets/hit-testing/modify-retrieval-modal.tsx app/components/datasets/hit-testing/style.module.css app/components/datasets/hit-testing/textarea.tsx app/components/datasets/hit-testing/utils/extension-to-file-type.ts app/components/datasets/loading.tsx app/components/datasets/metadata/add-metadata-button.tsx app/components/datasets/metadata/base/date-picker.tsx app/components/datasets/metadata/edit-metadata-batch/add-row.tsx app/components/datasets/metadata/edit-metadata-batch/edit-row.tsx app/components/datasets/metadata/edit-metadata-batch/edited-beacon.tsx app/components/datasets/metadata/edit-metadata-batch/input-combined.tsx app/components/datasets/metadata/edit-metadata-batch/input-has-set-multiple-value.tsx app/components/datasets/metadata/edit-metadata-batch/label.tsx app/components/datasets/metadata/edit-metadata-batch/modal.tsx app/components/datasets/metadata/hooks/use-batch-edit-document-metadata.ts app/components/datasets/metadata/hooks/use-check-metadata-name.ts app/components/datasets/metadata/hooks/use-edit-dataset-metadata.ts app/components/datasets/metadata/hooks/use-metadata-document.ts app/components/datasets/metadata/metadata-dataset/create-content.tsx app/components/datasets/metadata/metadata-dataset/create-metadata-modal.tsx app/components/datasets/metadata/metadata-dataset/dataset-metadata-drawer.tsx app/components/datasets/metadata/metadata-dataset/field.tsx app/components/datasets/metadata/metadata-dataset/select-metadata-modal.tsx app/components/datasets/metadata/metadata-dataset/select-metadata.tsx app/components/datasets/metadata/metadata-document/field.tsx app/components/datasets/metadata/metadata-document/index.tsx app/components/datasets/metadata/metadata-document/info-group.tsx app/components/datasets/metadata/metadata-document/no-data.tsx app/components/datasets/metadata/types.ts app/components/datasets/metadata/utils/get-icon.ts app/components/datasets/preview/container.tsx app/components/datasets/preview/header.tsx app/components/datasets/preview/index.tsx app/components/datasets/rename-modal/index.tsx app/components/datasets/settings/form/index.tsx app/components/datasets/settings/index-method-radio/assets/economy.svg app/components/datasets/settings/index-method-radio/assets/high-quality.svg app/components/datasets/settings/index-method-radio/index.tsx app/components/datasets/settings/permission-selector/index.tsx app/components/develop/ApiServer.tsx app/components/develop/code.tsx app/components/develop/doc.tsx app/components/develop/index.tsx app/components/develop/md.tsx app/components/develop/secret-key/assets/copied.svg app/components/develop/secret-key/assets/copy-hover.svg app/components/develop/secret-key/assets/copy.svg app/components/develop/secret-key/assets/pause.svg app/components/develop/secret-key/assets/play.svg app/components/develop/secret-key/assets/qrcode-hover.svg app/components/develop/secret-key/assets/qrcode.svg app/components/develop/secret-key/assets/svg.svg app/components/develop/secret-key/assets/svged.svg app/components/develop/secret-key/assets/trash-gray.svg app/components/develop/secret-key/assets/trash-red.svg app/components/develop/secret-key/input-copy.tsx app/components/develop/secret-key/secret-key-button.tsx app/components/develop/secret-key/secret-key-generate.tsx app/components/develop/secret-key/secret-key-modal.tsx app/components/develop/secret-key/style.module.css app/components/develop/tag.tsx app/components/develop/template/template.en.mdx app/components/develop/template/template.ja.mdx app/components/develop/template/template.zh.mdx app/components/develop/template/template_advanced_chat.en.mdx app/components/develop/template/template_advanced_chat.ja.mdx app/components/develop/template/template_advanced_chat.zh.mdx app/components/develop/template/template_chat.en.mdx app/components/develop/template/template_chat.ja.mdx app/components/develop/template/template_chat.zh.mdx app/components/develop/template/template_workflow.en.mdx app/components/develop/template/template_workflow.ja.mdx app/components/develop/template/template_workflow.zh.mdx app/components/explore/app-card/index.tsx app/components/explore/app-list/index.tsx app/components/explore/app-list/style.module.css app/components/explore/category.tsx app/components/explore/create-app-modal/index.tsx app/components/explore/index.tsx app/components/explore/installed-app/index.tsx app/components/explore/item-operation/index.tsx app/components/explore/item-operation/style.module.css app/components/explore/sidebar/app-nav-item/index.tsx app/components/explore/sidebar/index.tsx app/components/header/account-about/index.tsx app/components/header/account-dropdown/compliance.tsx app/components/header/account-dropdown/index.tsx app/components/header/account-dropdown/support.tsx app/components/header/account-dropdown/workplace-selector/index.module.css app/components/header/account-dropdown/workplace-selector/index.tsx app/components/header/account-setting/Integrations-page/index.module.css app/components/header/account-setting/Integrations-page/index.tsx app/components/header/account-setting/api-based-extension-page/empty.tsx app/components/header/account-setting/api-based-extension-page/index.tsx app/components/header/account-setting/api-based-extension-page/item.tsx app/components/header/account-setting/api-based-extension-page/modal.tsx app/components/header/account-setting/api-based-extension-page/selector.tsx app/components/header/account-setting/collapse/index.tsx app/components/header/account-setting/data-source-page/data-source-notion/index.tsx app/components/header/account-setting/data-source-page/data-source-notion/operate/index.tsx app/components/header/account-setting/data-source-page/data-source-website/config-firecrawl-modal.tsx app/components/header/account-setting/data-source-page/data-source-website/config-jina-reader-modal.tsx app/components/header/account-setting/data-source-page/data-source-website/config-watercrawl-modal.tsx app/components/header/account-setting/data-source-page/data-source-website/index.tsx app/components/header/account-setting/data-source-page/index.module.css app/components/header/account-setting/data-source-page/index.tsx app/components/header/account-setting/data-source-page/panel/config-item.tsx app/components/header/account-setting/data-source-page/panel/index.tsx app/components/header/account-setting/data-source-page/panel/style.module.css app/components/header/account-setting/data-source-page/panel/types.ts app/components/header/account-setting/index.tsx app/components/header/account-setting/key-validator/KeyInput.tsx app/components/header/account-setting/key-validator/Operate.tsx app/components/header/account-setting/key-validator/ValidateStatus.tsx app/components/header/account-setting/key-validator/declarations.ts app/components/header/account-setting/key-validator/hooks.ts app/components/header/account-setting/key-validator/index.tsx app/components/header/account-setting/language-page/index.module.css app/components/header/account-setting/language-page/index.tsx app/components/header/account-setting/members-page/edit-workspace-modal/index.module.css app/components/header/account-setting/members-page/edit-workspace-modal/index.tsx app/components/header/account-setting/members-page/index.tsx app/components/header/account-setting/members-page/invite-modal/index.module.css app/components/header/account-setting/members-page/invite-modal/index.tsx app/components/header/account-setting/members-page/invite-modal/role-selector.tsx app/components/header/account-setting/members-page/invited-modal/assets/copied.svg app/components/header/account-setting/members-page/invited-modal/assets/copy-hover.svg app/components/header/account-setting/members-page/invited-modal/assets/copy.svg app/components/header/account-setting/members-page/invited-modal/index.module.css app/components/header/account-setting/members-page/invited-modal/index.tsx app/components/header/account-setting/members-page/invited-modal/invitation-link.tsx app/components/header/account-setting/members-page/operation/index.tsx app/components/header/account-setting/menu-dialog.tsx app/components/header/account-setting/model-provider-page/declarations.ts app/components/header/account-setting/model-provider-page/hooks.spec.ts app/components/header/account-setting/model-provider-page/hooks.ts app/components/header/account-setting/model-provider-page/index.tsx app/components/header/account-setting/model-provider-page/install-from-marketplace.tsx app/components/header/account-setting/model-provider-page/model-badge/index.tsx app/components/header/account-setting/model-provider-page/model-icon/index.tsx app/components/header/account-setting/model-provider-page/model-modal/Form.tsx app/components/header/account-setting/model-provider-page/model-modal/Input.tsx app/components/header/account-setting/model-provider-page/model-modal/index.tsx app/components/header/account-setting/model-provider-page/model-modal/model-load-balancing-entry-modal.tsx app/components/header/account-setting/model-provider-page/model-name/index.tsx app/components/header/account-setting/model-provider-page/model-parameter-modal/agent-model-trigger.tsx app/components/header/account-setting/model-provider-page/model-parameter-modal/configuration-button.tsx app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx app/components/header/account-setting/model-provider-page/model-parameter-modal/model-display.tsx app/components/header/account-setting/model-provider-page/model-parameter-modal/parameter-item.tsx app/components/header/account-setting/model-provider-page/model-parameter-modal/presets-parameter.tsx app/components/header/account-setting/model-provider-page/model-parameter-modal/status-indicators.tsx app/components/header/account-setting/model-provider-page/model-parameter-modal/trigger.tsx app/components/header/account-setting/model-provider-page/model-selector/deprecated-model-trigger.tsx app/components/header/account-setting/model-provider-page/model-selector/empty-trigger.tsx app/components/header/account-setting/model-provider-page/model-selector/feature-icon.tsx app/components/header/account-setting/model-provider-page/model-selector/index.tsx app/components/header/account-setting/model-provider-page/model-selector/model-trigger.tsx app/components/header/account-setting/model-provider-page/model-selector/popup-item.tsx app/components/header/account-setting/model-provider-page/model-selector/popup.tsx app/components/header/account-setting/model-provider-page/provider-added-card/add-model-button.tsx app/components/header/account-setting/model-provider-page/provider-added-card/cooldown-timer.tsx app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx app/components/header/account-setting/model-provider-page/provider-added-card/model-list-item.tsx app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-configs.tsx app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx app/components/header/account-setting/model-provider-page/provider-added-card/priority-selector.tsx app/components/header/account-setting/model-provider-page/provider-added-card/priority-use-tip.tsx app/components/header/account-setting/model-provider-page/provider-added-card/quota-panel.tsx app/components/header/account-setting/model-provider-page/provider-icon/index.tsx app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx app/components/header/account-setting/model-provider-page/utils.ts app/components/header/account-setting/plugin-page/SerpapiPlugin.tsx app/components/header/account-setting/plugin-page/index.tsx app/components/header/account-setting/plugin-page/utils.ts app/components/header/app-back/index.tsx app/components/header/app-nav/index.tsx app/components/header/app-selector/index.tsx app/components/header/assets/alpha.svg app/components/header/assets/anthropic.svg app/components/header/assets/azure.svg app/components/header/assets/bitbucket.svg app/components/header/assets/file.svg app/components/header/assets/github.svg app/components/header/assets/google.svg app/components/header/assets/gpt.svg app/components/header/assets/hugging-face.svg app/components/header/assets/notion.svg app/components/header/assets/salesforce.svg app/components/header/assets/serpapi.png app/components/header/assets/sync.svg app/components/header/assets/trash.svg app/components/header/assets/twitter.svg app/components/header/dataset-nav/index.tsx app/components/header/env-nav/index.tsx app/components/header/explore-nav/index.tsx app/components/header/github-star/index.tsx app/components/header/header-wrapper.tsx app/components/header/index.module.css app/components/header/index.tsx app/components/header/indicator/index.tsx app/components/header/license-env/index.tsx app/components/header/maintenance-notice.tsx app/components/header/nav/index.module.css app/components/header/nav/index.tsx app/components/header/nav/nav-selector/index.tsx app/components/header/plan-badge/index.tsx app/components/header/plugins-nav/downloading-icon.module.css app/components/header/plugins-nav/downloading-icon.tsx app/components/header/plugins-nav/index.tsx app/components/header/tools-nav/index.tsx app/components/header/utils/util.ts app/components/i18n-server.tsx app/components/i18n.tsx app/components/plugins/base/badges/icon-with-tooltip.tsx app/components/plugins/base/badges/partner.tsx app/components/plugins/base/badges/verified.tsx app/components/plugins/base/key-value-item.tsx app/components/plugins/card/base/card-icon.tsx app/components/plugins/card/base/corner-mark.tsx app/components/plugins/card/base/description.tsx app/components/plugins/card/base/download-count.tsx app/components/plugins/card/base/org-info.tsx app/components/plugins/card/base/placeholder.tsx app/components/plugins/card/base/title.tsx app/components/plugins/card/card-more-info.tsx app/components/plugins/card/index.tsx app/components/plugins/constants.ts app/components/plugins/hooks.ts app/components/plugins/install-plugin/base/check-task-status.ts app/components/plugins/install-plugin/base/installed.tsx app/components/plugins/install-plugin/base/loading-error.tsx app/components/plugins/install-plugin/base/loading.tsx app/components/plugins/install-plugin/base/use-get-icon.ts app/components/plugins/install-plugin/base/version.tsx app/components/plugins/install-plugin/hooks.ts app/components/plugins/install-plugin/hooks/use-check-installed.tsx app/components/plugins/install-plugin/hooks/use-fold-anim-into.ts app/components/plugins/install-plugin/hooks/use-hide-logic.ts app/components/plugins/install-plugin/hooks/use-refresh-plugin-list.tsx app/components/plugins/install-plugin/install-bundle/index.tsx app/components/plugins/install-plugin/install-bundle/item/github-item.tsx app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx app/components/plugins/install-plugin/install-bundle/item/marketplace-item.tsx app/components/plugins/install-plugin/install-bundle/item/package-item.tsx app/components/plugins/install-plugin/install-bundle/ready-to-install.tsx app/components/plugins/install-plugin/install-bundle/steps/install-multi.tsx app/components/plugins/install-plugin/install-bundle/steps/install.tsx app/components/plugins/install-plugin/install-bundle/steps/installed.tsx app/components/plugins/install-plugin/install-from-github/index.tsx app/components/plugins/install-plugin/install-from-github/steps/loaded.tsx app/components/plugins/install-plugin/install-from-github/steps/selectPackage.tsx app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx app/components/plugins/install-plugin/install-from-local-package/index.tsx app/components/plugins/install-plugin/install-from-local-package/ready-to-install.tsx app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx app/components/plugins/install-plugin/install-from-marketplace/index.tsx app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx app/components/plugins/install-plugin/utils.ts app/components/plugins/marketplace/constants.ts app/components/plugins/marketplace/context.tsx app/components/plugins/marketplace/description/index.tsx app/components/plugins/marketplace/empty/index.tsx app/components/plugins/marketplace/empty/line.tsx app/components/plugins/marketplace/hooks.ts app/components/plugins/marketplace/index.tsx app/components/plugins/marketplace/intersection-line/hooks.ts app/components/plugins/marketplace/intersection-line/index.tsx app/components/plugins/marketplace/list/card-wrapper.tsx app/components/plugins/marketplace/list/index.tsx app/components/plugins/marketplace/list/list-with-collection.tsx app/components/plugins/marketplace/list/list-wrapper.tsx app/components/plugins/marketplace/plugin-type-switch.tsx app/components/plugins/marketplace/search-box/index.tsx app/components/plugins/marketplace/search-box/search-box-wrapper.tsx app/components/plugins/marketplace/search-box/tags-filter.tsx app/components/plugins/marketplace/sort-dropdown/index.tsx app/components/plugins/marketplace/types.ts app/components/plugins/marketplace/utils.ts app/components/plugins/permission-setting-modal/modal.tsx app/components/plugins/permission-setting-modal/style.module.css app/components/plugins/plugin-detail-panel/action-list.tsx app/components/plugins/plugin-detail-panel/agent-strategy-list.tsx app/components/plugins/plugin-detail-panel/app-selector/app-inputs-form.tsx app/components/plugins/plugin-detail-panel/app-selector/app-inputs-panel.tsx app/components/plugins/plugin-detail-panel/app-selector/app-picker.tsx app/components/plugins/plugin-detail-panel/app-selector/app-trigger.tsx app/components/plugins/plugin-detail-panel/app-selector/index.tsx app/components/plugins/plugin-detail-panel/detail-header.tsx app/components/plugins/plugin-detail-panel/endpoint-card.tsx app/components/plugins/plugin-detail-panel/endpoint-list.tsx app/components/plugins/plugin-detail-panel/endpoint-modal.tsx app/components/plugins/plugin-detail-panel/index.tsx app/components/plugins/plugin-detail-panel/model-list.tsx app/components/plugins/plugin-detail-panel/model-selector/index.tsx app/components/plugins/plugin-detail-panel/model-selector/llm-params-panel.tsx app/components/plugins/plugin-detail-panel/model-selector/tts-params-panel.tsx app/components/plugins/plugin-detail-panel/multiple-tool-selector/index.tsx app/components/plugins/plugin-detail-panel/operation-dropdown.tsx app/components/plugins/plugin-detail-panel/strategy-detail.tsx app/components/plugins/plugin-detail-panel/strategy-item.tsx app/components/plugins/plugin-detail-panel/tool-selector/hooks.ts app/components/plugins/plugin-detail-panel/tool-selector/index.tsx app/components/plugins/plugin-detail-panel/tool-selector/reasoning-config-form.tsx app/components/plugins/plugin-detail-panel/tool-selector/tool-credentials-form.tsx app/components/plugins/plugin-detail-panel/tool-selector/tool-item.tsx app/components/plugins/plugin-detail-panel/tool-selector/tool-trigger.tsx app/components/plugins/plugin-detail-panel/utils.ts app/components/plugins/plugin-item/action.tsx app/components/plugins/plugin-item/index.tsx app/components/plugins/plugin-mutation-model/index.tsx app/components/plugins/plugin-page/context.tsx app/components/plugins/plugin-page/debug-info.tsx app/components/plugins/plugin-page/empty/index.tsx app/components/plugins/plugin-page/filter-management/category-filter.tsx app/components/plugins/plugin-page/filter-management/constant.ts app/components/plugins/plugin-page/filter-management/index.tsx app/components/plugins/plugin-page/filter-management/search-box.tsx app/components/plugins/plugin-page/filter-management/store.ts app/components/plugins/plugin-page/filter-management/tag-filter.tsx app/components/plugins/plugin-page/index.tsx app/components/plugins/plugin-page/install-plugin-dropdown.tsx app/components/plugins/plugin-page/list/index.tsx app/components/plugins/plugin-page/plugin-info.tsx app/components/plugins/plugin-page/plugin-tasks/hooks.ts app/components/plugins/plugin-page/plugin-tasks/index.tsx app/components/plugins/plugin-page/plugins-panel.tsx app/components/plugins/plugin-page/use-permission.ts app/components/plugins/plugin-page/use-uploader.ts app/components/plugins/provider-card.tsx app/components/plugins/types.ts app/components/plugins/update-plugin/from-github.tsx app/components/plugins/update-plugin/from-market-place.tsx app/components/plugins/update-plugin/index.tsx app/components/plugins/update-plugin/plugin-version-picker.tsx app/components/plugins/utils.ts app/components/sentry-initor.tsx app/components/share/text-generation/icons/star.svg app/components/share/text-generation/index.tsx app/components/share/text-generation/info-modal.tsx app/components/share/text-generation/menu-dropdown.tsx app/components/share/text-generation/no-data/index.tsx app/components/share/text-generation/result/content.tsx app/components/share/text-generation/result/header.tsx app/components/share/text-generation/result/index.tsx app/components/share/text-generation/run-batch/csv-download/index.tsx app/components/share/text-generation/run-batch/csv-reader/index.tsx app/components/share/text-generation/run-batch/index.tsx app/components/share/text-generation/run-batch/res-download/index.tsx app/components/share/text-generation/run-once/index.tsx app/components/share/utils.ts app/components/signin/countdown.tsx app/components/swr-initor.tsx app/components/tools/add-tool-modal/D.png app/components/tools/add-tool-modal/category.tsx app/components/tools/add-tool-modal/empty.png app/components/tools/add-tool-modal/empty.tsx app/components/tools/add-tool-modal/index.tsx app/components/tools/add-tool-modal/tools.tsx app/components/tools/add-tool-modal/type.tsx app/components/tools/edit-custom-collection-modal/config-credentials.tsx app/components/tools/edit-custom-collection-modal/examples.ts app/components/tools/edit-custom-collection-modal/get-schema.tsx app/components/tools/edit-custom-collection-modal/index.tsx app/components/tools/edit-custom-collection-modal/modal.tsx app/components/tools/edit-custom-collection-modal/test-api.tsx app/components/tools/labels/constant.ts app/components/tools/labels/filter.tsx app/components/tools/labels/selector.tsx app/components/tools/marketplace/hooks.ts app/components/tools/marketplace/index.tsx app/components/tools/provider-list.tsx app/components/tools/provider/custom-create-card.tsx app/components/tools/provider/detail.tsx app/components/tools/provider/tool-item.tsx app/components/tools/setting/build-in/config-credentials.tsx app/components/tools/types.ts app/components/tools/utils/index.ts app/components/tools/utils/to-form-schema.ts app/components/tools/workflow-tool/configure-button.tsx app/components/tools/workflow-tool/confirm-modal/index.tsx app/components/tools/workflow-tool/index.tsx app/components/tools/workflow-tool/method-selector.tsx app/components/with-i18n.tsx app/components/workflow-app/components/workflow-children.tsx app/components/workflow-app/components/workflow-header/chat-variable-trigger.tsx app/components/workflow-app/components/workflow-header/features-trigger.tsx app/components/workflow-app/components/workflow-header/index.tsx app/components/workflow-app/components/workflow-main.tsx app/components/workflow-app/components/workflow-panel.tsx app/components/workflow-app/hooks/index.ts app/components/workflow-app/hooks/use-is-chat-mode.ts app/components/workflow-app/hooks/use-nodes-sync-draft.ts app/components/workflow-app/hooks/use-workflow-init.ts app/components/workflow-app/hooks/use-workflow-refresh-draft.ts app/components/workflow-app/hooks/use-workflow-run.ts app/components/workflow-app/hooks/use-workflow-start-run.tsx app/components/workflow-app/hooks/use-workflow-template.ts app/components/workflow-app/index.tsx app/components/workflow-app/store/workflow/workflow-slice.ts app/components/workflow/block-icon.tsx app/components/workflow/block-selector/all-tools.tsx app/components/workflow/block-selector/blocks.tsx app/components/workflow/block-selector/constants.tsx app/components/workflow/block-selector/hooks.ts app/components/workflow/block-selector/index-bar.tsx app/components/workflow/block-selector/index.tsx app/components/workflow/block-selector/market-place-plugin/action.tsx app/components/workflow/block-selector/market-place-plugin/item.tsx app/components/workflow/block-selector/market-place-plugin/list.tsx app/components/workflow/block-selector/tabs.tsx app/components/workflow/block-selector/tool-picker.tsx app/components/workflow/block-selector/tool/action-item.tsx app/components/workflow/block-selector/tool/tool-list-flat-view/list.tsx app/components/workflow/block-selector/tool/tool-list-tree-view/item.tsx app/components/workflow/block-selector/tool/tool-list-tree-view/list.tsx app/components/workflow/block-selector/tool/tool.tsx app/components/workflow/block-selector/tools.tsx app/components/workflow/block-selector/types.ts app/components/workflow/block-selector/use-sticky-scroll.ts app/components/workflow/block-selector/view-type-select.tsx app/components/workflow/blocks.tsx app/components/workflow/candidate-node.tsx app/components/workflow/constants.ts app/components/workflow/context.tsx app/components/workflow/custom-connection-line.tsx app/components/workflow/custom-edge-linear-gradient-render.tsx app/components/workflow/custom-edge.tsx app/components/workflow/datasets-detail-store/provider.tsx app/components/workflow/datasets-detail-store/store.ts app/components/workflow/dsl-export-confirm-modal.tsx app/components/workflow/features.tsx app/components/workflow/header/chat-variable-button.tsx app/components/workflow/header/checklist.tsx app/components/workflow/header/editing-title.tsx app/components/workflow/header/env-button.tsx app/components/workflow/header/global-variable-button.tsx app/components/workflow/header/header-in-normal.tsx app/components/workflow/header/header-in-restoring.tsx app/components/workflow/header/header-in-view-history.tsx app/components/workflow/header/index.tsx app/components/workflow/header/restoring-title.tsx app/components/workflow/header/run-and-history.tsx app/components/workflow/header/running-title.tsx app/components/workflow/header/undo-redo.tsx app/components/workflow/header/version-history-button.tsx app/components/workflow/header/view-history.tsx app/components/workflow/header/view-workflow-history.tsx app/components/workflow/help-line/index.tsx app/components/workflow/help-line/types.ts app/components/workflow/hooks-store/index.ts app/components/workflow/hooks-store/provider.tsx app/components/workflow/hooks-store/store.ts app/components/workflow/hooks/index.ts app/components/workflow/hooks/use-checklist.ts app/components/workflow/hooks/use-config-vision.ts app/components/workflow/hooks/use-edges-interactions-without-sync.ts app/components/workflow/hooks/use-edges-interactions.ts app/components/workflow/hooks/use-format-time-from-now.ts app/components/workflow/hooks/use-helpline.ts app/components/workflow/hooks/use-node-data-update.ts app/components/workflow/hooks/use-nodes-data.ts app/components/workflow/hooks/use-nodes-interactions-without-sync.ts app/components/workflow/hooks/use-nodes-interactions.ts app/components/workflow/hooks/use-nodes-layout.ts app/components/workflow/hooks/use-nodes-sync-draft.ts app/components/workflow/hooks/use-panel-interactions.ts app/components/workflow/hooks/use-selection-interactions.ts app/components/workflow/hooks/use-shortcuts.ts app/components/workflow/hooks/use-workflow-history.ts app/components/workflow/hooks/use-workflow-interactions.ts app/components/workflow/hooks/use-workflow-mode.ts app/components/workflow/hooks/use-workflow-refresh-draft.ts app/components/workflow/hooks/use-workflow-run-event/index.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-agent-log.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-failed.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-finished.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-finished.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-iteration-finished.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-iteration-next.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-iteration-started.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-loop-finished.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-loop-next.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-loop-started.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-retry.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-node-started.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-run-event.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-started.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-text-chunk.ts app/components/workflow/hooks/use-workflow-run-event/use-workflow-text-replace.ts app/components/workflow/hooks/use-workflow-run.ts app/components/workflow/hooks/use-workflow-start-run.tsx app/components/workflow/hooks/use-workflow-variables.ts app/components/workflow/hooks/use-workflow.ts app/components/workflow/index.tsx app/components/workflow/limit-tips.tsx app/components/workflow/node-contextmenu.tsx app/components/workflow/nodes/_base/components/add-button.tsx app/components/workflow/nodes/_base/components/add-variable-popup-with-position.tsx app/components/workflow/nodes/_base/components/add-variable-popup.tsx app/components/workflow/nodes/_base/components/agent-strategy-selector.tsx app/components/workflow/nodes/_base/components/agent-strategy.tsx app/components/workflow/nodes/_base/components/before-run-form/form-item.tsx app/components/workflow/nodes/_base/components/before-run-form/form.tsx app/components/workflow/nodes/_base/components/before-run-form/index.tsx app/components/workflow/nodes/_base/components/code-generator-button.tsx app/components/workflow/nodes/_base/components/collapse/field-collapse.tsx app/components/workflow/nodes/_base/components/collapse/index.tsx app/components/workflow/nodes/_base/components/config-vision.tsx app/components/workflow/nodes/_base/components/editor/base.tsx app/components/workflow/nodes/_base/components/editor/code-editor/editor-support-vars.tsx app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx app/components/workflow/nodes/_base/components/editor/code-editor/style.css app/components/workflow/nodes/_base/components/editor/text-editor.tsx app/components/workflow/nodes/_base/components/editor/wrap.tsx app/components/workflow/nodes/_base/components/error-handle/default-value.tsx app/components/workflow/nodes/_base/components/error-handle/error-handle-on-node.tsx app/components/workflow/nodes/_base/components/error-handle/error-handle-on-panel.tsx app/components/workflow/nodes/_base/components/error-handle/error-handle-tip.tsx app/components/workflow/nodes/_base/components/error-handle/error-handle-type-selector.tsx app/components/workflow/nodes/_base/components/error-handle/fail-branch-card.tsx app/components/workflow/nodes/_base/components/error-handle/hooks.ts app/components/workflow/nodes/_base/components/error-handle/types.ts app/components/workflow/nodes/_base/components/error-handle/utils.ts app/components/workflow/nodes/_base/components/field.tsx app/components/workflow/nodes/_base/components/file-type-item.tsx app/components/workflow/nodes/_base/components/file-upload-setting.tsx app/components/workflow/nodes/_base/components/group.tsx app/components/workflow/nodes/_base/components/help-link.tsx app/components/workflow/nodes/_base/components/info-panel.tsx app/components/workflow/nodes/_base/components/input-number-with-slider.tsx app/components/workflow/nodes/_base/components/input-support-select-var.tsx app/components/workflow/nodes/_base/components/input-var-type-icon.tsx app/components/workflow/nodes/_base/components/install-plugin-button.tsx app/components/workflow/nodes/_base/components/list-no-data-placeholder.tsx app/components/workflow/nodes/_base/components/memory-config.tsx app/components/workflow/nodes/_base/components/next-step/add.tsx app/components/workflow/nodes/_base/components/next-step/container.tsx app/components/workflow/nodes/_base/components/next-step/index.tsx app/components/workflow/nodes/_base/components/next-step/item.tsx app/components/workflow/nodes/_base/components/next-step/line.tsx app/components/workflow/nodes/_base/components/next-step/operator.tsx app/components/workflow/nodes/_base/components/node-control.tsx app/components/workflow/nodes/_base/components/node-handle.tsx app/components/workflow/nodes/_base/components/node-resizer.tsx app/components/workflow/nodes/_base/components/node-status-icon.tsx app/components/workflow/nodes/_base/components/option-card.tsx app/components/workflow/nodes/_base/components/output-vars.tsx app/components/workflow/nodes/_base/components/panel-operator/change-block.tsx app/components/workflow/nodes/_base/components/panel-operator/index.tsx app/components/workflow/nodes/_base/components/panel-operator/panel-operator-popup.tsx app/components/workflow/nodes/_base/components/prompt/editor.tsx app/components/workflow/nodes/_base/components/readonly-input-with-select-var.tsx app/components/workflow/nodes/_base/components/remove-button.tsx app/components/workflow/nodes/_base/components/remove-effect-var-confirm.tsx app/components/workflow/nodes/_base/components/retry/hooks.ts app/components/workflow/nodes/_base/components/retry/retry-on-node.tsx app/components/workflow/nodes/_base/components/retry/retry-on-panel.tsx app/components/workflow/nodes/_base/components/retry/style.module.css app/components/workflow/nodes/_base/components/retry/types.ts app/components/workflow/nodes/_base/components/retry/utils.ts app/components/workflow/nodes/_base/components/selector.tsx app/components/workflow/nodes/_base/components/setting-item.tsx app/components/workflow/nodes/_base/components/split.tsx app/components/workflow/nodes/_base/components/support-var-input/index.tsx app/components/workflow/nodes/_base/components/switch-plugin-version.tsx app/components/workflow/nodes/_base/components/title-description-input.tsx app/components/workflow/nodes/_base/components/toggle-expand-btn.tsx app/components/workflow/nodes/_base/components/variable-tag.tsx app/components/workflow/nodes/_base/components/variable/assigned-var-reference-popup.tsx app/components/workflow/nodes/_base/components/variable/constant-field.tsx app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/picker/field.tsx app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/picker/index.tsx app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/show/field.tsx app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/show/index.tsx app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/tree-indent-line.tsx app/components/workflow/nodes/_base/components/variable/output-var-list.tsx app/components/workflow/nodes/_base/components/variable/utils.ts app/components/workflow/nodes/_base/components/variable/var-full-path-panel.tsx app/components/workflow/nodes/_base/components/variable/var-list.tsx app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx app/components/workflow/nodes/_base/components/variable/var-reference-popup.tsx app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx app/components/workflow/nodes/_base/components/variable/var-type-picker.tsx app/components/workflow/nodes/_base/hooks/use-available-var-list.ts app/components/workflow/nodes/_base/hooks/use-node-crud.ts app/components/workflow/nodes/_base/hooks/use-node-help-link.ts app/components/workflow/nodes/_base/hooks/use-node-info.ts app/components/workflow/nodes/_base/hooks/use-one-step-run.ts app/components/workflow/nodes/_base/hooks/use-output-var-list.ts app/components/workflow/nodes/_base/hooks/use-resize-panel.ts app/components/workflow/nodes/_base/hooks/use-toggle-expend.ts app/components/workflow/nodes/_base/hooks/use-var-list.ts app/components/workflow/nodes/_base/node.tsx app/components/workflow/nodes/_base/panel.tsx app/components/workflow/nodes/agent/components/model-bar.tsx app/components/workflow/nodes/agent/components/tool-icon.tsx app/components/workflow/nodes/agent/default.ts app/components/workflow/nodes/agent/node.tsx app/components/workflow/nodes/agent/panel.tsx app/components/workflow/nodes/agent/types.ts app/components/workflow/nodes/agent/use-config.ts app/components/workflow/nodes/answer/default.ts app/components/workflow/nodes/answer/node.tsx app/components/workflow/nodes/answer/panel.tsx app/components/workflow/nodes/answer/types.ts app/components/workflow/nodes/answer/use-config.ts app/components/workflow/nodes/answer/utils.ts app/components/workflow/nodes/assigner/components/operation-selector.tsx app/components/workflow/nodes/assigner/components/var-list/index.tsx app/components/workflow/nodes/assigner/components/var-list/use-var-list.ts app/components/workflow/nodes/assigner/default.ts app/components/workflow/nodes/assigner/hooks.ts app/components/workflow/nodes/assigner/node.tsx app/components/workflow/nodes/assigner/panel.tsx app/components/workflow/nodes/assigner/types.ts app/components/workflow/nodes/assigner/use-config.ts app/components/workflow/nodes/assigner/utils.ts app/components/workflow/nodes/code/code-parser.spec.ts app/components/workflow/nodes/code/code-parser.ts app/components/workflow/nodes/code/default.ts app/components/workflow/nodes/code/dependency-picker.tsx app/components/workflow/nodes/code/node.tsx app/components/workflow/nodes/code/panel.tsx app/components/workflow/nodes/code/types.ts app/components/workflow/nodes/code/use-config.ts app/components/workflow/nodes/code/utils.ts app/components/workflow/nodes/constants.ts app/components/workflow/nodes/document-extractor/default.ts app/components/workflow/nodes/document-extractor/node.tsx app/components/workflow/nodes/document-extractor/panel.tsx app/components/workflow/nodes/document-extractor/types.ts app/components/workflow/nodes/document-extractor/use-config.ts app/components/workflow/nodes/end/default.ts app/components/workflow/nodes/end/node.tsx app/components/workflow/nodes/end/panel.tsx app/components/workflow/nodes/end/types.ts app/components/workflow/nodes/end/use-config.ts app/components/workflow/nodes/end/utils.ts app/components/workflow/nodes/http/components/api-input.tsx app/components/workflow/nodes/http/components/authorization/index.tsx app/components/workflow/nodes/http/components/authorization/radio-group.tsx app/components/workflow/nodes/http/components/curl-panel.tsx app/components/workflow/nodes/http/components/edit-body/index.tsx app/components/workflow/nodes/http/components/key-value/bulk-edit/index.tsx app/components/workflow/nodes/http/components/key-value/index.tsx app/components/workflow/nodes/http/components/key-value/key-value-edit/index.tsx app/components/workflow/nodes/http/components/key-value/key-value-edit/input-item.tsx app/components/workflow/nodes/http/components/key-value/key-value-edit/item.tsx app/components/workflow/nodes/http/components/timeout/index.tsx app/components/workflow/nodes/http/default.ts app/components/workflow/nodes/http/hooks/use-key-value-list.ts app/components/workflow/nodes/http/node.tsx app/components/workflow/nodes/http/panel.tsx app/components/workflow/nodes/http/types.ts app/components/workflow/nodes/http/use-config.ts app/components/workflow/nodes/http/utils.ts app/components/workflow/nodes/if-else/components/condition-add.tsx app/components/workflow/nodes/if-else/components/condition-files-list-value.tsx app/components/workflow/nodes/if-else/components/condition-list/condition-input.tsx app/components/workflow/nodes/if-else/components/condition-list/condition-item.tsx app/components/workflow/nodes/if-else/components/condition-list/condition-operator.tsx app/components/workflow/nodes/if-else/components/condition-list/condition-var-selector.tsx app/components/workflow/nodes/if-else/components/condition-list/index.tsx app/components/workflow/nodes/if-else/components/condition-number-input.tsx app/components/workflow/nodes/if-else/components/condition-value.tsx app/components/workflow/nodes/if-else/components/condition-wrap.tsx app/components/workflow/nodes/if-else/default.ts app/components/workflow/nodes/if-else/node.tsx app/components/workflow/nodes/if-else/panel.tsx app/components/workflow/nodes/if-else/types.ts app/components/workflow/nodes/if-else/use-config.ts app/components/workflow/nodes/if-else/use-is-var-file-attribute.ts app/components/workflow/nodes/if-else/utils.ts app/components/workflow/nodes/index.tsx app/components/workflow/nodes/iteration-start/constants.ts app/components/workflow/nodes/iteration-start/default.ts app/components/workflow/nodes/iteration-start/index.tsx app/components/workflow/nodes/iteration-start/types.ts app/components/workflow/nodes/iteration/add-block.tsx app/components/workflow/nodes/iteration/default.ts app/components/workflow/nodes/iteration/node.tsx app/components/workflow/nodes/iteration/panel.tsx app/components/workflow/nodes/iteration/types.ts app/components/workflow/nodes/iteration/use-config.ts app/components/workflow/nodes/iteration/use-interactions.ts app/components/workflow/nodes/knowledge-retrieval/components/add-dataset.tsx app/components/workflow/nodes/knowledge-retrieval/components/dataset-item.tsx app/components/workflow/nodes/knowledge-retrieval/components/dataset-list.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/add-condition.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-common-variable-selector.tsx.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-date.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-item.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-number.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-operator.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-string.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-value-method.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/condition-variable-selector.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/index.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/condition-list/utils.ts app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-filter/index.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-filter/metadata-filter-selector.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-icon.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-panel.tsx app/components/workflow/nodes/knowledge-retrieval/components/metadata/metadata-trigger.tsx app/components/workflow/nodes/knowledge-retrieval/components/retrieval-config.tsx app/components/workflow/nodes/knowledge-retrieval/default.ts app/components/workflow/nodes/knowledge-retrieval/hooks.ts app/components/workflow/nodes/knowledge-retrieval/node.tsx app/components/workflow/nodes/knowledge-retrieval/panel.tsx app/components/workflow/nodes/knowledge-retrieval/types.ts app/components/workflow/nodes/knowledge-retrieval/use-config.ts app/components/workflow/nodes/knowledge-retrieval/utils.ts app/components/workflow/nodes/list-operator/components/extract-input.tsx app/components/workflow/nodes/list-operator/components/filter-condition.tsx app/components/workflow/nodes/list-operator/components/limit-config.tsx app/components/workflow/nodes/list-operator/components/sub-variable-picker.tsx app/components/workflow/nodes/list-operator/default.ts app/components/workflow/nodes/list-operator/node.tsx app/components/workflow/nodes/list-operator/panel.tsx app/components/workflow/nodes/list-operator/types.ts app/components/workflow/nodes/list-operator/use-config.ts app/components/workflow/nodes/llm/components/config-prompt-item.tsx app/components/workflow/nodes/llm/components/config-prompt.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/code-editor.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/error-message.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/index.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/json-importer.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-config.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/assets/index.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/assets/schema-generator-dark.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/assets/schema-generator-light.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/generated-result.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/index.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/json-schema-generator/prompt-editor.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/schema-editor.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/add-field.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/card.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/context.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/actions.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/advanced-actions.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/advanced-options.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/auto-width-input.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/index.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/required-switch.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/edit-card/type-selector.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/hooks.ts app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/index.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/schema-node.tsx app/components/workflow/nodes/llm/components/json-schema-config-modal/visual-editor/store.ts app/components/workflow/nodes/llm/components/prompt-generator-btn.tsx app/components/workflow/nodes/llm/components/resolution-picker.tsx app/components/workflow/nodes/llm/components/structure-output.tsx app/components/workflow/nodes/llm/default.ts app/components/workflow/nodes/llm/node.tsx app/components/workflow/nodes/llm/panel.tsx app/components/workflow/nodes/llm/types.ts app/components/workflow/nodes/llm/use-config.ts app/components/workflow/nodes/llm/utils.ts app/components/workflow/nodes/loop-end/default.ts app/components/workflow/nodes/loop-start/constants.ts app/components/workflow/nodes/loop-start/default.ts app/components/workflow/nodes/loop-start/index.tsx app/components/workflow/nodes/loop-start/types.ts app/components/workflow/nodes/loop/add-block.tsx app/components/workflow/nodes/loop/components/condition-add.tsx app/components/workflow/nodes/loop/components/condition-files-list-value.tsx app/components/workflow/nodes/loop/components/condition-list/condition-input.tsx app/components/workflow/nodes/loop/components/condition-list/condition-item.tsx app/components/workflow/nodes/loop/components/condition-list/condition-operator.tsx app/components/workflow/nodes/loop/components/condition-list/condition-var-selector.tsx app/components/workflow/nodes/loop/components/condition-list/index.tsx app/components/workflow/nodes/loop/components/condition-number-input.tsx app/components/workflow/nodes/loop/components/condition-value.tsx app/components/workflow/nodes/loop/components/condition-wrap.tsx app/components/workflow/nodes/loop/components/loop-variables/empty.tsx app/components/workflow/nodes/loop/components/loop-variables/form-item.tsx app/components/workflow/nodes/loop/components/loop-variables/index.tsx app/components/workflow/nodes/loop/components/loop-variables/input-mode-selec.tsx app/components/workflow/nodes/loop/components/loop-variables/item.tsx app/components/workflow/nodes/loop/components/loop-variables/variable-type-select.tsx app/components/workflow/nodes/loop/default.ts app/components/workflow/nodes/loop/insert-block.tsx app/components/workflow/nodes/loop/node.tsx app/components/workflow/nodes/loop/panel.tsx app/components/workflow/nodes/loop/types.ts app/components/workflow/nodes/loop/use-config.ts app/components/workflow/nodes/loop/use-interactions.ts app/components/workflow/nodes/loop/use-is-var-file-attribute.ts app/components/workflow/nodes/loop/utils.ts app/components/workflow/nodes/parameter-extractor/components/extract-parameter/import-from-tool.tsx app/components/workflow/nodes/parameter-extractor/components/extract-parameter/item.tsx app/components/workflow/nodes/parameter-extractor/components/extract-parameter/list.tsx app/components/workflow/nodes/parameter-extractor/components/extract-parameter/update.tsx app/components/workflow/nodes/parameter-extractor/components/reasoning-mode-picker.tsx app/components/workflow/nodes/parameter-extractor/default.ts app/components/workflow/nodes/parameter-extractor/node.tsx app/components/workflow/nodes/parameter-extractor/panel.tsx app/components/workflow/nodes/parameter-extractor/types.ts app/components/workflow/nodes/parameter-extractor/use-config.ts app/components/workflow/nodes/question-classifier/components/advanced-setting.tsx app/components/workflow/nodes/question-classifier/components/class-item.tsx app/components/workflow/nodes/question-classifier/components/class-list.tsx app/components/workflow/nodes/question-classifier/default.ts app/components/workflow/nodes/question-classifier/node.tsx app/components/workflow/nodes/question-classifier/panel.tsx app/components/workflow/nodes/question-classifier/types.ts app/components/workflow/nodes/question-classifier/use-config.ts app/components/workflow/nodes/question-classifier/utils.ts app/components/workflow/nodes/start/components/var-item.tsx app/components/workflow/nodes/start/components/var-list.tsx app/components/workflow/nodes/start/default.ts app/components/workflow/nodes/start/node.tsx app/components/workflow/nodes/start/panel.tsx app/components/workflow/nodes/start/types.ts app/components/workflow/nodes/start/use-config.ts app/components/workflow/nodes/start/utils.ts app/components/workflow/nodes/template-transform/default.ts app/components/workflow/nodes/template-transform/node.tsx app/components/workflow/nodes/template-transform/panel.tsx app/components/workflow/nodes/template-transform/types.ts app/components/workflow/nodes/template-transform/use-config.ts app/components/workflow/nodes/template-transform/utils.ts app/components/workflow/nodes/tool/components/input-var-list.tsx app/components/workflow/nodes/tool/default.ts app/components/workflow/nodes/tool/node.tsx app/components/workflow/nodes/tool/panel.tsx app/components/workflow/nodes/tool/types.ts app/components/workflow/nodes/tool/use-config.ts app/components/workflow/nodes/tool/utils.ts app/components/workflow/nodes/utils.ts app/components/workflow/nodes/variable-assigner/components/add-variable/index.tsx app/components/workflow/nodes/variable-assigner/components/node-group-item.tsx app/components/workflow/nodes/variable-assigner/components/node-variable-item.tsx app/components/workflow/nodes/variable-assigner/components/var-group-item.tsx app/components/workflow/nodes/variable-assigner/components/var-list/index.tsx app/components/workflow/nodes/variable-assigner/components/var-list/use-var-list.ts app/components/workflow/nodes/variable-assigner/default.ts app/components/workflow/nodes/variable-assigner/hooks.ts app/components/workflow/nodes/variable-assigner/node.tsx app/components/workflow/nodes/variable-assigner/panel.tsx app/components/workflow/nodes/variable-assigner/types.ts app/components/workflow/nodes/variable-assigner/use-config.ts app/components/workflow/nodes/variable-assigner/utils.ts app/components/workflow/note-node/constants.ts app/components/workflow/note-node/hooks.ts app/components/workflow/note-node/index.tsx app/components/workflow/note-node/note-editor/context.tsx app/components/workflow/note-node/note-editor/editor.tsx app/components/workflow/note-node/note-editor/index.tsx app/components/workflow/note-node/note-editor/plugins/format-detector-plugin/hooks.ts app/components/workflow/note-node/note-editor/plugins/format-detector-plugin/index.tsx app/components/workflow/note-node/note-editor/plugins/link-editor-plugin/component.tsx app/components/workflow/note-node/note-editor/plugins/link-editor-plugin/hooks.ts app/components/workflow/note-node/note-editor/plugins/link-editor-plugin/index.tsx app/components/workflow/note-node/note-editor/store.ts app/components/workflow/note-node/note-editor/theme/index.ts app/components/workflow/note-node/note-editor/theme/theme.css app/components/workflow/note-node/note-editor/toolbar/color-picker.tsx app/components/workflow/note-node/note-editor/toolbar/command.tsx app/components/workflow/note-node/note-editor/toolbar/divider.tsx app/components/workflow/note-node/note-editor/toolbar/font-size-selector.tsx app/components/workflow/note-node/note-editor/toolbar/hooks.ts app/components/workflow/note-node/note-editor/toolbar/index.tsx app/components/workflow/note-node/note-editor/toolbar/operator.tsx app/components/workflow/note-node/note-editor/utils.ts app/components/workflow/note-node/types.ts app/components/workflow/operator/add-block.tsx app/components/workflow/operator/control.tsx app/components/workflow/operator/export-image.tsx app/components/workflow/operator/hooks.ts app/components/workflow/operator/index.tsx app/components/workflow/operator/tip-popup.tsx app/components/workflow/operator/zoom-in-out.tsx app/components/workflow/panel-contextmenu.tsx app/components/workflow/panel/chat-record/index.tsx app/components/workflow/panel/chat-record/user-input.tsx app/components/workflow/panel/chat-variable-panel/components/array-value-list.tsx app/components/workflow/panel/chat-variable-panel/components/object-value-item.tsx app/components/workflow/panel/chat-variable-panel/components/object-value-list.tsx app/components/workflow/panel/chat-variable-panel/components/variable-item.tsx app/components/workflow/panel/chat-variable-panel/components/variable-modal-trigger.tsx app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx app/components/workflow/panel/chat-variable-panel/components/variable-type-select.tsx app/components/workflow/panel/chat-variable-panel/index.tsx app/components/workflow/panel/chat-variable-panel/type.ts app/components/workflow/panel/debug-and-preview/chat-wrapper.tsx app/components/workflow/panel/debug-and-preview/conversation-variable-modal.tsx app/components/workflow/panel/debug-and-preview/empty.tsx app/components/workflow/panel/debug-and-preview/hooks.ts app/components/workflow/panel/debug-and-preview/index.tsx app/components/workflow/panel/debug-and-preview/user-input.tsx app/components/workflow/panel/env-panel/env-item.tsx app/components/workflow/panel/env-panel/index.tsx app/components/workflow/panel/env-panel/variable-modal.tsx app/components/workflow/panel/env-panel/variable-trigger.tsx app/components/workflow/panel/global-variable-panel/index.tsx app/components/workflow/panel/global-variable-panel/item.tsx app/components/workflow/panel/index.tsx app/components/workflow/panel/inputs-panel.tsx app/components/workflow/panel/record.tsx app/components/workflow/panel/version-history-panel/context-menu/index.tsx app/components/workflow/panel/version-history-panel/context-menu/menu-item.tsx app/components/workflow/panel/version-history-panel/context-menu/use-context-menu.ts app/components/workflow/panel/version-history-panel/delete-confirm-modal.tsx app/components/workflow/panel/version-history-panel/empty.tsx app/components/workflow/panel/version-history-panel/filter/filter-item.tsx app/components/workflow/panel/version-history-panel/filter/filter-switch.tsx app/components/workflow/panel/version-history-panel/filter/index.tsx app/components/workflow/panel/version-history-panel/filter/use-filter.ts app/components/workflow/panel/version-history-panel/index.tsx app/components/workflow/panel/version-history-panel/loading/index.tsx app/components/workflow/panel/version-history-panel/loading/item.tsx app/components/workflow/panel/version-history-panel/restore-confirm-modal.tsx app/components/workflow/panel/version-history-panel/version-history-item.tsx app/components/workflow/panel/workflow-preview.tsx app/components/workflow/plugin-dependency/hooks.ts app/components/workflow/plugin-dependency/index.tsx app/components/workflow/plugin-dependency/store.ts app/components/workflow/run/agent-log/agent-log-item.tsx app/components/workflow/run/agent-log/agent-log-nav-more.tsx app/components/workflow/run/agent-log/agent-log-nav.tsx app/components/workflow/run/agent-log/agent-log-trigger.tsx app/components/workflow/run/agent-log/agent-result-panel.tsx app/components/workflow/run/agent-log/index.tsx app/components/workflow/run/assets/bg-line-error.svg app/components/workflow/run/assets/bg-line-running.svg app/components/workflow/run/assets/bg-line-success.svg app/components/workflow/run/assets/bg-line-warning.svg app/components/workflow/run/assets/highlight-dark.svg app/components/workflow/run/assets/highlight.svg app/components/workflow/run/hooks.ts app/components/workflow/run/index.tsx app/components/workflow/run/iteration-log/index.tsx app/components/workflow/run/iteration-log/iteration-log-trigger.tsx app/components/workflow/run/iteration-log/iteration-result-panel.tsx app/components/workflow/run/loop-log/index.tsx app/components/workflow/run/loop-log/loop-log-trigger.tsx app/components/workflow/run/loop-log/loop-result-panel.tsx app/components/workflow/run/loop-result-panel.tsx app/components/workflow/run/meta.tsx app/components/workflow/run/node.tsx app/components/workflow/run/output-panel.tsx app/components/workflow/run/result-panel.tsx app/components/workflow/run/result-text.tsx app/components/workflow/run/retry-log/index.tsx app/components/workflow/run/retry-log/retry-log-trigger.tsx app/components/workflow/run/retry-log/retry-result-panel.tsx app/components/workflow/run/special-result-panel.tsx app/components/workflow/run/status-container.tsx app/components/workflow/run/status.tsx app/components/workflow/run/tracing-panel.tsx app/components/workflow/run/utils/format-log/agent/data.ts app/components/workflow/run/utils/format-log/agent/index.spec.ts app/components/workflow/run/utils/format-log/agent/index.ts app/components/workflow/run/utils/format-log/graph-to-log-struct.spec.ts app/components/workflow/run/utils/format-log/graph-to-log-struct.ts app/components/workflow/run/utils/format-log/index.ts app/components/workflow/run/utils/format-log/iteration/index.spec.ts app/components/workflow/run/utils/format-log/iteration/index.ts app/components/workflow/run/utils/format-log/loop/index.spec.ts app/components/workflow/run/utils/format-log/loop/index.ts app/components/workflow/run/utils/format-log/parallel/index.ts app/components/workflow/run/utils/format-log/retry/index.spec.ts app/components/workflow/run/utils/format-log/retry/index.ts app/components/workflow/shortcuts-name.tsx app/components/workflow/simple-node/constants.ts app/components/workflow/simple-node/index.tsx app/components/workflow/simple-node/types.ts app/components/workflow/store/index.ts app/components/workflow/store/workflow/chat-variable-slice.ts app/components/workflow/store/workflow/env-variable-slice.ts app/components/workflow/store/workflow/form-slice.ts app/components/workflow/store/workflow/help-line-slice.ts app/components/workflow/store/workflow/history-slice.ts app/components/workflow/store/workflow/index.ts app/components/workflow/store/workflow/node-slice.ts app/components/workflow/store/workflow/panel-slice.ts app/components/workflow/store/workflow/tool-slice.ts app/components/workflow/store/workflow/version-slice.ts app/components/workflow/store/workflow/workflow-draft-slice.ts app/components/workflow/store/workflow/workflow-slice.ts app/components/workflow/style.css app/components/workflow/syncing-data-modal.tsx app/components/workflow/types.ts app/components/workflow/update-dsl-modal.tsx app/components/workflow/utils/common.ts app/components/workflow/utils/edge.ts app/components/workflow/utils/index.ts app/components/workflow/utils/layout.ts app/components/workflow/utils/node.ts app/components/workflow/utils/tool.ts app/components/workflow/utils/variable.ts app/components/workflow/utils/workflow-init.spec.ts app/components/workflow/utils/workflow-init.ts app/components/workflow/utils/workflow.ts app/components/workflow/workflow-history-store.tsx app/dev-only/i18n-checker/page.tsx app/dev-only/layout.tsx app/dev-preview/page.tsx app/education-apply/constants.ts app/education-apply/education-apply-page.tsx app/education-apply/hooks.ts app/education-apply/role-selector.tsx app/education-apply/search-input.tsx app/education-apply/types.ts app/education-apply/user-info.tsx app/education-apply/verify-state-modal.tsx app/forgot-password/ChangePasswordForm.tsx app/forgot-password/ForgotPasswordForm.tsx app/forgot-password/page.tsx app/init/InitPasswordPopup.tsx app/init/page.tsx app/install/installForm.tsx app/install/page.tsx app/layout.tsx app/page.module.css app/page.tsx app/repos/[owner]/[repo]/releases/route.ts app/reset-password/check-code/page.tsx app/reset-password/layout.tsx app/reset-password/page.tsx app/reset-password/set-password/page.tsx app/routePrefixHandle.tsx app/signin/_header.tsx app/signin/assets/github.svg app/signin/assets/google.svg app/signin/check-code/page.tsx app/signin/components/mail-and-code-auth.tsx app/signin/components/mail-and-password-auth.tsx app/signin/components/social-auth.tsx app/signin/components/sso-auth.tsx app/signin/invite-settings/page.tsx app/signin/layout.tsx app/signin/normalForm.tsx app/signin/oneMoreStep.tsx app/signin/page.module.css app/signin/page.tsx app/styles/globals.css app/styles/markdown.scss app/styles/preflight.css assets/action.svg assets/csv.svg assets/delete.svg assets/doc.svg assets/docx.svg assets/html.svg assets/json.svg assets/md.svg assets/pdf.svg assets/txt.svg assets/xlsx.svg bin/uglify-embed.js config/index.ts context/app-context.tsx context/dataset-detail.ts context/datasets-context.tsx context/debug-configuration.ts context/event-emitter.tsx context/explore-context.ts context/external-api-panel-context.tsx context/external-knowledge-api-context.tsx context/i18n.ts context/modal-context.tsx context/provider-context.tsx context/query-client.tsx context/workspace-context.tsx docker/entrypoint.sh docker/pm2.json eslint.config.mjs global.d.ts hooks/use-app-favicon.ts hooks/use-breakpoints.spec.ts hooks/use-breakpoints.ts hooks/use-i18n.ts hooks/use-import-dsl.ts hooks/use-knowledge.ts hooks/use-metadata.ts hooks/use-mitt.ts hooks/use-moderate.ts hooks/use-pay.tsx hooks/use-tab-searchparams.ts hooks/use-theme.ts hooks/use-timestamp.spec.ts hooks/use-timestamp.ts i18n/DEV.md i18n/README.md i18n/auto-gen-i18n.js i18n/check-i18n.js i18n/de-DE/app-annotation.ts i18n/de-DE/app-api.ts i18n/de-DE/app-debug.ts i18n/de-DE/app-log.ts i18n/de-DE/app-overview.ts i18n/de-DE/app.ts i18n/de-DE/billing.ts i18n/de-DE/common.ts i18n/de-DE/custom.ts i18n/de-DE/dataset-creation.ts i18n/de-DE/dataset-documents.ts i18n/de-DE/dataset-hit-testing.ts i18n/de-DE/dataset-settings.ts i18n/de-DE/dataset.ts i18n/de-DE/education.ts i18n/de-DE/explore.ts i18n/de-DE/layout.ts i18n/de-DE/login.ts i18n/de-DE/plugin-tags.ts i18n/de-DE/plugin.ts i18n/de-DE/register.ts i18n/de-DE/run-log.ts i18n/de-DE/share-app.ts i18n/de-DE/time.ts i18n/de-DE/tools.ts i18n/de-DE/workflow.ts i18n/en-US/app-annotation.ts i18n/en-US/app-api.ts i18n/en-US/app-debug.ts i18n/en-US/app-log.ts i18n/en-US/app-overview.ts i18n/en-US/app.ts i18n/en-US/billing.ts i18n/en-US/common.ts i18n/en-US/custom.ts i18n/en-US/dataset-creation.ts i18n/en-US/dataset-documents.ts i18n/en-US/dataset-hit-testing.ts i18n/en-US/dataset-settings.ts i18n/en-US/dataset.ts i18n/en-US/education.ts i18n/en-US/explore.ts i18n/en-US/layout.ts i18n/en-US/login.ts i18n/en-US/plugin-tags.ts i18n/en-US/plugin.ts i18n/en-US/register.ts i18n/en-US/run-log.ts i18n/en-US/share-app.ts i18n/en-US/time.ts i18n/en-US/tools.ts i18n/en-US/workflow.ts i18n/es-ES/app-annotation.ts i18n/es-ES/app-api.ts i18n/es-ES/app-debug.ts i18n/es-ES/app-log.ts i18n/es-ES/app-overview.ts i18n/es-ES/app.ts i18n/es-ES/billing.ts i18n/es-ES/common.ts i18n/es-ES/custom.ts i18n/es-ES/dataset-creation.ts i18n/es-ES/dataset-documents.ts i18n/es-ES/dataset-hit-testing.ts i18n/es-ES/dataset-settings.ts i18n/es-ES/dataset.ts i18n/es-ES/education.ts i18n/es-ES/explore.ts i18n/es-ES/layout.ts i18n/es-ES/login.ts i18n/es-ES/plugin-tags.ts i18n/es-ES/plugin.ts i18n/es-ES/register.ts i18n/es-ES/run-log.ts i18n/es-ES/share-app.ts i18n/es-ES/time.ts i18n/es-ES/tools.ts i18n/es-ES/workflow.ts i18n/fa-IR/app-annotation.ts i18n/fa-IR/app-api.ts i18n/fa-IR/app-debug.ts i18n/fa-IR/app-log.ts i18n/fa-IR/app-overview.ts i18n/fa-IR/app.ts i18n/fa-IR/billing.ts i18n/fa-IR/common.ts i18n/fa-IR/custom.ts i18n/fa-IR/dataset-creation.ts i18n/fa-IR/dataset-documents.ts i18n/fa-IR/dataset-hit-testing.ts i18n/fa-IR/dataset-settings.ts i18n/fa-IR/dataset.ts i18n/fa-IR/education.ts i18n/fa-IR/explore.ts i18n/fa-IR/layout.ts i18n/fa-IR/login.ts i18n/fa-IR/plugin-tags.ts i18n/fa-IR/plugin.ts i18n/fa-IR/register.ts i18n/fa-IR/run-log.ts i18n/fa-IR/share-app.ts i18n/fa-IR/time.ts i18n/fa-IR/tools.ts i18n/fa-IR/workflow.ts i18n/fr-FR/app-annotation.ts i18n/fr-FR/app-api.ts i18n/fr-FR/app-debug.ts i18n/fr-FR/app-log.ts i18n/fr-FR/app-overview.ts i18n/fr-FR/app.ts i18n/fr-FR/billing.ts i18n/fr-FR/common.ts i18n/fr-FR/custom.ts i18n/fr-FR/dataset-creation.ts i18n/fr-FR/dataset-documents.ts i18n/fr-FR/dataset-hit-testing.ts i18n/fr-FR/dataset-settings.ts i18n/fr-FR/dataset.ts i18n/fr-FR/education.ts i18n/fr-FR/explore.ts i18n/fr-FR/layout.ts i18n/fr-FR/login.ts i18n/fr-FR/plugin-tags.ts i18n/fr-FR/plugin.ts i18n/fr-FR/register.ts i18n/fr-FR/run-log.ts i18n/fr-FR/share-app.ts i18n/fr-FR/time.ts i18n/fr-FR/tools.ts i18n/fr-FR/workflow.ts i18n/hi-IN/app-annotation.ts i18n/hi-IN/app-api.ts i18n/hi-IN/app-debug.ts i18n/hi-IN/app-log.ts i18n/hi-IN/app-overview.ts i18n/hi-IN/app.ts i18n/hi-IN/billing.ts i18n/hi-IN/common.ts i18n/hi-IN/custom.ts i18n/hi-IN/dataset-creation.ts i18n/hi-IN/dataset-documents.ts i18n/hi-IN/dataset-hit-testing.ts i18n/hi-IN/dataset-settings.ts i18n/hi-IN/dataset.ts i18n/hi-IN/education.ts i18n/hi-IN/explore.ts i18n/hi-IN/layout.ts i18n/hi-IN/login.ts i18n/hi-IN/plugin-tags.ts i18n/hi-IN/plugin.ts i18n/hi-IN/register.ts i18n/hi-IN/run-log.ts i18n/hi-IN/share-app.ts i18n/hi-IN/time.ts i18n/hi-IN/tools.ts i18n/hi-IN/workflow.ts i18n/i18next-config.ts i18n/index.ts i18n/it-IT/app-annotation.ts i18n/it-IT/app-api.ts i18n/it-IT/app-debug.ts i18n/it-IT/app-log.ts i18n/it-IT/app-overview.ts i18n/it-IT/app.ts i18n/it-IT/billing.ts i18n/it-IT/common.ts i18n/it-IT/custom.ts i18n/it-IT/dataset-creation.ts i18n/it-IT/dataset-documents.ts i18n/it-IT/dataset-hit-testing.ts i18n/it-IT/dataset-settings.ts i18n/it-IT/dataset.ts i18n/it-IT/education.ts i18n/it-IT/explore.ts i18n/it-IT/layout.ts i18n/it-IT/login.ts i18n/it-IT/plugin-tags.ts i18n/it-IT/plugin.ts i18n/it-IT/register.ts i18n/it-IT/run-log.ts i18n/it-IT/share-app.ts i18n/it-IT/time.ts i18n/it-IT/tools.ts i18n/it-IT/workflow.ts i18n/ja-JP/app-annotation.ts i18n/ja-JP/app-api.ts i18n/ja-JP/app-debug.ts i18n/ja-JP/app-log.ts i18n/ja-JP/app-overview.ts i18n/ja-JP/app.ts i18n/ja-JP/billing.ts i18n/ja-JP/common.ts i18n/ja-JP/custom.ts i18n/ja-JP/dataset-creation.ts i18n/ja-JP/dataset-documents.ts i18n/ja-JP/dataset-hit-testing.ts i18n/ja-JP/dataset-settings.ts i18n/ja-JP/dataset.ts i18n/ja-JP/education.ts i18n/ja-JP/explore.ts i18n/ja-JP/layout.ts i18n/ja-JP/login.ts i18n/ja-JP/plugin-tags.ts i18n/ja-JP/plugin.ts i18n/ja-JP/register.ts i18n/ja-JP/run-log.ts i18n/ja-JP/share-app.ts i18n/ja-JP/time.ts i18n/ja-JP/tools.ts i18n/ja-JP/workflow.ts i18n/ko-KR/app-annotation.ts i18n/ko-KR/app-api.ts i18n/ko-KR/app-debug.ts i18n/ko-KR/app-log.ts i18n/ko-KR/app-overview.ts i18n/ko-KR/app.ts i18n/ko-KR/billing.ts i18n/ko-KR/common.ts i18n/ko-KR/custom.ts i18n/ko-KR/dataset-creation.ts i18n/ko-KR/dataset-documents.ts i18n/ko-KR/dataset-hit-testing.ts i18n/ko-KR/dataset-settings.ts i18n/ko-KR/dataset.ts i18n/ko-KR/education.ts i18n/ko-KR/explore.ts i18n/ko-KR/layout.ts i18n/ko-KR/login.ts i18n/ko-KR/plugin-tags.ts i18n/ko-KR/plugin.ts i18n/ko-KR/register.ts i18n/ko-KR/run-log.ts i18n/ko-KR/share-app.ts i18n/ko-KR/time.ts i18n/ko-KR/tools.ts i18n/ko-KR/workflow.ts i18n/language.ts i18n/languages.json i18n/pl-PL/app-annotation.ts i18n/pl-PL/app-api.ts i18n/pl-PL/app-debug.ts i18n/pl-PL/app-log.ts i18n/pl-PL/app-overview.ts i18n/pl-PL/app.ts i18n/pl-PL/billing.ts i18n/pl-PL/common.ts i18n/pl-PL/custom.ts i18n/pl-PL/dataset-creation.ts i18n/pl-PL/dataset-documents.ts i18n/pl-PL/dataset-hit-testing.ts i18n/pl-PL/dataset-settings.ts i18n/pl-PL/dataset.ts i18n/pl-PL/education.ts i18n/pl-PL/explore.ts i18n/pl-PL/layout.ts i18n/pl-PL/login.ts i18n/pl-PL/plugin-tags.ts i18n/pl-PL/plugin.ts i18n/pl-PL/register.ts i18n/pl-PL/run-log.ts i18n/pl-PL/share-app.ts i18n/pl-PL/time.ts i18n/pl-PL/tools.ts i18n/pl-PL/workflow.ts i18n/pt-BR/app-annotation.ts i18n/pt-BR/app-api.ts i18n/pt-BR/app-debug.ts i18n/pt-BR/app-log.ts i18n/pt-BR/app-overview.ts i18n/pt-BR/app.ts i18n/pt-BR/billing.ts i18n/pt-BR/common.ts i18n/pt-BR/custom.ts i18n/pt-BR/dataset-creation.ts i18n/pt-BR/dataset-documents.ts i18n/pt-BR/dataset-hit-testing.ts i18n/pt-BR/dataset-settings.ts i18n/pt-BR/dataset.ts i18n/pt-BR/education.ts i18n/pt-BR/explore.ts i18n/pt-BR/layout.ts i18n/pt-BR/login.ts i18n/pt-BR/plugin-tags.ts i18n/pt-BR/plugin.ts i18n/pt-BR/register.ts i18n/pt-BR/run-log.ts i18n/pt-BR/share-app.ts i18n/pt-BR/time.ts i18n/pt-BR/tools.ts i18n/pt-BR/workflow.ts i18n/ro-RO/app-annotation.ts i18n/ro-RO/app-api.ts i18n/ro-RO/app-debug.ts i18n/ro-RO/app-log.ts i18n/ro-RO/app-overview.ts i18n/ro-RO/app.ts i18n/ro-RO/billing.ts i18n/ro-RO/common.ts i18n/ro-RO/custom.ts i18n/ro-RO/dataset-creation.ts i18n/ro-RO/dataset-documents.ts i18n/ro-RO/dataset-hit-testing.ts i18n/ro-RO/dataset-settings.ts i18n/ro-RO/dataset.ts i18n/ro-RO/education.ts i18n/ro-RO/explore.ts i18n/ro-RO/layout.ts i18n/ro-RO/login.ts i18n/ro-RO/plugin-tags.ts i18n/ro-RO/plugin.ts i18n/ro-RO/register.ts i18n/ro-RO/run-log.ts i18n/ro-RO/share-app.ts i18n/ro-RO/time.ts i18n/ro-RO/tools.ts i18n/ro-RO/workflow.ts i18n/ru-RU/app-annotation.ts i18n/ru-RU/app-api.ts i18n/ru-RU/app-debug.ts i18n/ru-RU/app-log.ts i18n/ru-RU/app-overview.ts i18n/ru-RU/app.ts i18n/ru-RU/billing.ts i18n/ru-RU/common.ts i18n/ru-RU/custom.ts i18n/ru-RU/dataset-creation.ts i18n/ru-RU/dataset-documents.ts i18n/ru-RU/dataset-hit-testing.ts i18n/ru-RU/dataset-settings.ts i18n/ru-RU/dataset.ts i18n/ru-RU/education.ts i18n/ru-RU/explore.ts i18n/ru-RU/layout.ts i18n/ru-RU/login.ts i18n/ru-RU/plugin-tags.ts i18n/ru-RU/plugin.ts i18n/ru-RU/register.ts i18n/ru-RU/run-log.ts i18n/ru-RU/share-app.ts i18n/ru-RU/time.ts i18n/ru-RU/tools.ts i18n/ru-RU/workflow.ts i18n/server.ts i18n/sl-SI/app-annotation.ts i18n/sl-SI/app-api.ts i18n/sl-SI/app-debug.ts i18n/sl-SI/app-log.ts i18n/sl-SI/app-overview.ts i18n/sl-SI/app.ts i18n/sl-SI/billing.ts i18n/sl-SI/common.ts i18n/sl-SI/custom.ts i18n/sl-SI/dataset-creation.ts i18n/sl-SI/dataset-documents.ts i18n/sl-SI/dataset-hit-testing.ts i18n/sl-SI/dataset-settings.ts i18n/sl-SI/dataset.ts i18n/sl-SI/education.ts i18n/sl-SI/explore.ts i18n/sl-SI/layout.ts i18n/sl-SI/login.ts i18n/sl-SI/plugin-tags.ts i18n/sl-SI/plugin.ts i18n/sl-SI/register.ts i18n/sl-SI/run-log.ts i18n/sl-SI/share-app.ts i18n/sl-SI/time.ts i18n/sl-SI/tools.ts i18n/sl-SI/workflow.ts i18n/th-TH/app-annotation.ts i18n/th-TH/app-api.ts i18n/th-TH/app-debug.ts i18n/th-TH/app-log.ts i18n/th-TH/app-overview.ts i18n/th-TH/app.ts i18n/th-TH/billing.ts i18n/th-TH/common.ts i18n/th-TH/custom.ts i18n/th-TH/dataset-creation.ts i18n/th-TH/dataset-documents.ts i18n/th-TH/dataset-hit-testing.ts i18n/th-TH/dataset-settings.ts i18n/th-TH/dataset.ts i18n/th-TH/education.ts i18n/th-TH/explore.ts i18n/th-TH/layout.ts i18n/th-TH/login.ts i18n/th-TH/plugin-tags.ts i18n/th-TH/plugin.ts i18n/th-TH/register.ts i18n/th-TH/run-log.ts i18n/th-TH/share-app.ts i18n/th-TH/time.ts i18n/th-TH/tools.ts i18n/th-TH/workflow.ts i18n/tr-TR/app-annotation.ts i18n/tr-TR/app-api.ts i18n/tr-TR/app-debug.ts i18n/tr-TR/app-log.ts i18n/tr-TR/app-overview.ts i18n/tr-TR/app.ts i18n/tr-TR/billing.ts i18n/tr-TR/common.ts i18n/tr-TR/custom.ts i18n/tr-TR/dataset-creation.ts i18n/tr-TR/dataset-documents.ts i18n/tr-TR/dataset-hit-testing.ts i18n/tr-TR/dataset-settings.ts i18n/tr-TR/dataset.ts i18n/tr-TR/education.ts i18n/tr-TR/explore.ts i18n/tr-TR/layout.ts i18n/tr-TR/login.ts i18n/tr-TR/plugin-tags.ts i18n/tr-TR/plugin.ts i18n/tr-TR/register.ts i18n/tr-TR/run-log.ts i18n/tr-TR/share-app.ts i18n/tr-TR/time.ts i18n/tr-TR/tools.ts i18n/tr-TR/workflow.ts i18n/uk-UA/app-annotation.ts i18n/uk-UA/app-api.ts i18n/uk-UA/app-debug.ts i18n/uk-UA/app-log.ts i18n/uk-UA/app-overview.ts i18n/uk-UA/app.ts i18n/uk-UA/billing.ts i18n/uk-UA/common.ts i18n/uk-UA/custom.ts i18n/uk-UA/dataset-creation.ts i18n/uk-UA/dataset-documents.ts i18n/uk-UA/dataset-hit-testing.ts i18n/uk-UA/dataset-settings.ts i18n/uk-UA/dataset.ts i18n/uk-UA/education.ts i18n/uk-UA/explore.ts i18n/uk-UA/layout.ts i18n/uk-UA/login.ts i18n/uk-UA/plugin-tags.ts i18n/uk-UA/plugin.ts i18n/uk-UA/register.ts i18n/uk-UA/run-log.ts i18n/uk-UA/share-app.ts i18n/uk-UA/time.ts i18n/uk-UA/tools.ts i18n/uk-UA/workflow.ts i18n/vi-VN/app-annotation.ts i18n/vi-VN/app-api.ts i18n/vi-VN/app-debug.ts i18n/vi-VN/app-log.ts i18n/vi-VN/app-overview.ts i18n/vi-VN/app.ts i18n/vi-VN/billing.ts i18n/vi-VN/common.ts i18n/vi-VN/custom.ts i18n/vi-VN/dataset-creation.ts i18n/vi-VN/dataset-documents.ts i18n/vi-VN/dataset-hit-testing.ts i18n/vi-VN/dataset-settings.ts i18n/vi-VN/dataset.ts i18n/vi-VN/education.ts i18n/vi-VN/explore.ts i18n/vi-VN/layout.ts i18n/vi-VN/login.ts i18n/vi-VN/plugin-tags.ts i18n/vi-VN/plugin.ts i18n/vi-VN/register.ts i18n/vi-VN/run-log.ts i18n/vi-VN/share-app.ts i18n/vi-VN/time.ts i18n/vi-VN/tools.ts i18n/vi-VN/workflow.ts i18n/zh-Hans/app-annotation.ts i18n/zh-Hans/app-api.ts i18n/zh-Hans/app-debug.ts i18n/zh-Hans/app-log.ts i18n/zh-Hans/app-overview.ts i18n/zh-Hans/app.ts i18n/zh-Hans/billing.ts i18n/zh-Hans/common.ts i18n/zh-Hans/custom.ts i18n/zh-Hans/dataset-creation.ts i18n/zh-Hans/dataset-documents.ts i18n/zh-Hans/dataset-hit-testing.ts i18n/zh-Hans/dataset-settings.ts i18n/zh-Hans/dataset.ts i18n/zh-Hans/education.ts i18n/zh-Hans/explore.ts i18n/zh-Hans/layout.ts i18n/zh-Hans/login.ts i18n/zh-Hans/plugin-tags.ts i18n/zh-Hans/plugin.ts i18n/zh-Hans/register.ts i18n/zh-Hans/run-log.ts i18n/zh-Hans/share-app.ts i18n/zh-Hans/time.ts i18n/zh-Hans/tools.ts i18n/zh-Hans/workflow.ts i18n/zh-Hant/app-annotation.ts i18n/zh-Hant/app-api.ts i18n/zh-Hant/app-debug.ts i18n/zh-Hant/app-log.ts i18n/zh-Hant/app-overview.ts i18n/zh-Hant/app.ts i18n/zh-Hant/billing.ts i18n/zh-Hant/common.ts i18n/zh-Hant/custom.ts i18n/zh-Hant/dataset-creation.ts i18n/zh-Hant/dataset-documents.ts i18n/zh-Hant/dataset-hit-testing.ts i18n/zh-Hant/dataset-settings.ts i18n/zh-Hant/dataset.ts i18n/zh-Hant/education.ts i18n/zh-Hant/explore.ts i18n/zh-Hant/layout.ts i18n/zh-Hant/login.ts i18n/zh-Hant/plugin-tags.ts i18n/zh-Hant/plugin.ts i18n/zh-Hant/register.ts i18n/zh-Hant/run-log.ts i18n/zh-Hant/share-app.ts i18n/zh-Hant/time.ts i18n/zh-Hant/tools.ts i18n/zh-Hant/workflow.ts jest.config.ts jest.setup.ts middleware.ts models/app.ts models/common.ts models/datasets.ts models/debug.ts models/explore.ts models/log.ts models/share.ts models/user.ts next.config.js package.json pnpm-lock.yaml postcss.config.js public/education/bg.png public/embed.js public/embed.min.js public/favicon.ico public/logo/logo-embedded-chat-avatar.png public/logo/logo-embedded-chat-header.png public/logo/logo-embedded-chat-header@2x.png public/logo/logo-embedded-chat-header@3x.png public/logo/logo-monochrome-white.svg public/logo/logo-site-dark.png public/logo/logo-site.png public/logo/logo.svg public/pdf.worker.min.mjs public/screenshots/dark/Agent.png public/screenshots/dark/Agent@2x.png public/screenshots/dark/Agent@3x.png public/screenshots/dark/Chatbot.png public/screenshots/dark/Chatbot@2x.png public/screenshots/dark/Chatbot@3x.png public/screenshots/dark/Chatflow.png public/screenshots/dark/Chatflow@2x.png public/screenshots/dark/Chatflow@3x.png public/screenshots/dark/TextGenerator.png public/screenshots/dark/TextGenerator@2x.png public/screenshots/dark/TextGenerator@3x.png public/screenshots/dark/Workflow.png public/screenshots/dark/Workflow@2x.png public/screenshots/dark/Workflow@3x.png public/screenshots/light/Agent.png public/screenshots/light/Agent@2x.png public/screenshots/light/Agent@3x.png public/screenshots/light/Chatbot.png public/screenshots/light/Chatbot@2x.png public/screenshots/light/Chatbot@3x.png public/screenshots/light/Chatflow.png public/screenshots/light/Chatflow@2x.png public/screenshots/light/Chatflow@3x.png public/screenshots/light/TextGenerator.png public/screenshots/light/TextGenerator@2x.png public/screenshots/light/TextGenerator@3x.png public/screenshots/light/Workflow.png public/screenshots/light/Workflow@2x.png public/screenshots/light/Workflow@3x.png public/vs/base/browser/ui/codicons/codicon/codicon.ttf public/vs/base/common/worker/simpleWorker.nls.de.js public/vs/base/common/worker/simpleWorker.nls.es.js public/vs/base/common/worker/simpleWorker.nls.fr.js public/vs/base/common/worker/simpleWorker.nls.it.js public/vs/base/common/worker/simpleWorker.nls.ja.js public/vs/base/common/worker/simpleWorker.nls.js public/vs/base/common/worker/simpleWorker.nls.ko.js public/vs/base/common/worker/simpleWorker.nls.ru.js public/vs/base/common/worker/simpleWorker.nls.zh-cn.js public/vs/base/common/worker/simpleWorker.nls.zh-tw.js public/vs/base/worker/workerMain.js public/vs/basic-languages/abap/abap.js public/vs/basic-languages/apex/apex.js public/vs/basic-languages/azcli/azcli.js public/vs/basic-languages/bat/bat.js public/vs/basic-languages/bicep/bicep.js public/vs/basic-languages/cameligo/cameligo.js public/vs/basic-languages/clojure/clojure.js public/vs/basic-languages/coffee/coffee.js public/vs/basic-languages/cpp/cpp.js public/vs/basic-languages/csharp/csharp.js public/vs/basic-languages/csp/csp.js public/vs/basic-languages/css/css.js public/vs/basic-languages/cypher/cypher.js public/vs/basic-languages/dart/dart.js public/vs/basic-languages/dockerfile/dockerfile.js public/vs/basic-languages/ecl/ecl.js public/vs/basic-languages/elixir/elixir.js public/vs/basic-languages/flow9/flow9.js public/vs/basic-languages/freemarker2/freemarker2.js public/vs/basic-languages/fsharp/fsharp.js public/vs/basic-languages/go/go.js public/vs/basic-languages/graphql/graphql.js public/vs/basic-languages/handlebars/handlebars.js public/vs/basic-languages/hcl/hcl.js public/vs/basic-languages/html/html.js public/vs/basic-languages/ini/ini.js public/vs/basic-languages/java/java.js public/vs/basic-languages/javascript/javascript.js public/vs/basic-languages/julia/julia.js public/vs/basic-languages/kotlin/kotlin.js public/vs/basic-languages/less/less.js public/vs/basic-languages/lexon/lexon.js public/vs/basic-languages/liquid/liquid.js public/vs/basic-languages/lua/lua.js public/vs/basic-languages/m3/m3.js public/vs/basic-languages/markdown/markdown.js public/vs/basic-languages/mdx/mdx.js public/vs/basic-languages/mips/mips.js public/vs/basic-languages/msdax/msdax.js public/vs/basic-languages/mysql/mysql.js public/vs/basic-languages/objective-c/objective-c.js public/vs/basic-languages/pascal/pascal.js public/vs/basic-languages/pascaligo/pascaligo.js public/vs/basic-languages/perl/perl.js public/vs/basic-languages/pgsql/pgsql.js public/vs/basic-languages/php/php.js public/vs/basic-languages/pla/pla.js public/vs/basic-languages/postiats/postiats.js public/vs/basic-languages/powerquery/powerquery.js public/vs/basic-languages/powershell/powershell.js public/vs/basic-languages/protobuf/protobuf.js public/vs/basic-languages/pug/pug.js public/vs/basic-languages/python/python.js public/vs/basic-languages/qsharp/qsharp.js public/vs/basic-languages/r/r.js public/vs/basic-languages/razor/razor.js public/vs/basic-languages/redis/redis.js public/vs/basic-languages/redshift/redshift.js public/vs/basic-languages/restructuredtext/restructuredtext.js public/vs/basic-languages/ruby/ruby.js public/vs/basic-languages/rust/rust.js public/vs/basic-languages/sb/sb.js public/vs/basic-languages/scala/scala.js public/vs/basic-languages/scheme/scheme.js public/vs/basic-languages/scss/scss.js public/vs/basic-languages/shell/shell.js public/vs/basic-languages/solidity/solidity.js public/vs/basic-languages/sophia/sophia.js public/vs/basic-languages/sparql/sparql.js public/vs/basic-languages/sql/sql.js public/vs/basic-languages/st/st.js public/vs/basic-languages/swift/swift.js public/vs/basic-languages/systemverilog/systemverilog.js public/vs/basic-languages/tcl/tcl.js public/vs/basic-languages/twig/twig.js public/vs/basic-languages/typescript/typescript.js public/vs/basic-languages/vb/vb.js public/vs/basic-languages/wgsl/wgsl.js public/vs/basic-languages/xml/xml.js public/vs/basic-languages/yaml/yaml.js public/vs/editor/editor.main.css public/vs/editor/editor.main.js public/vs/editor/editor.main.nls.de.js public/vs/editor/editor.main.nls.es.js public/vs/editor/editor.main.nls.fr.js public/vs/editor/editor.main.nls.it.js public/vs/editor/editor.main.nls.ja.js public/vs/editor/editor.main.nls.js public/vs/editor/editor.main.nls.ko.js public/vs/editor/editor.main.nls.ru.js public/vs/editor/editor.main.nls.zh-cn.js public/vs/editor/editor.main.nls.zh-tw.js public/vs/language/css/cssMode.js public/vs/language/css/cssWorker.js public/vs/language/html/htmlMode.js public/vs/language/html/htmlWorker.js public/vs/language/json/jsonMode.js public/vs/language/json/jsonWorker.js public/vs/language/typescript/tsMode.js public/vs/language/typescript/tsWorker.js public/vs/loader.js service/_tools_util.spec.ts service/_tools_util.ts service/annotation.ts service/apps.ts service/base.ts service/billing.ts service/common.ts service/datasets.ts service/debug.ts service/demo/index.tsx service/explore.ts service/fetch.ts service/knowledge/use-create-dataset.ts service/knowledge/use-document.ts service/knowledge/use-hit-testing.ts service/knowledge/use-import.ts service/knowledge/use-metadata.ts service/knowledge/use-segment.ts service/log.ts service/plugins.ts service/refresh-token.ts service/share.ts service/sso.ts service/strategy.ts service/tag.ts service/tools.ts service/use-apps.ts service/use-base.ts service/use-common.ts service/use-education.ts service/use-endpoints.ts service/use-models.ts service/use-plugins.ts service/use-strategy.ts service/use-tools.ts service/use-workflow.ts service/workflow.ts tailwind-common-config.ts tailwind.config.js themes/dark.css themes/light.css themes/manual-dark.css themes/manual-light.css themes/markdown-dark.css themes/markdown-light.css themes/tailwind-theme-var-define.ts tsconfig.json types/app.ts types/feature.ts types/workflow.ts typography.js utils/app-redirection.ts utils/classnames.spec.ts utils/classnames.ts utils/clipboard.ts utils/context.ts utils/emoji.ts utils/format.spec.ts utils/format.ts utils/get-icon.ts utils/index.spec.ts utils/index.ts utils/model-config.ts utils/permission.ts utils/semver.ts utils/time.ts utils/timezone.json utils/timezone.ts utils/tool-call.ts utils/var-basePath.js utils/var.ts utils/zod.spec.ts