From 207b5894584036488a705cdb4c4ad631aa009ea3 Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 1 Nov 2024 11:22:08 +0800 Subject: [PATCH 01/18] chore: toolpicker add trigger --- .../plugins/test/tools-picker/page.tsx | 16 +++-- .../workflow/block-selector/tool-picker.tsx | 66 +++++++++++++++---- 2 files changed, 66 insertions(+), 16 deletions(-) diff --git a/web/app/(commonLayout)/plugins/test/tools-picker/page.tsx b/web/app/(commonLayout)/plugins/test/tools-picker/page.tsx index 37c3b3b1cf..0b6242a42e 100644 --- a/web/app/(commonLayout)/plugins/test/tools-picker/page.tsx +++ b/web/app/(commonLayout)/plugins/test/tools-picker/page.tsx @@ -3,11 +3,19 @@ import React from 'react' import ToolPicker from '@/app/components/workflow/block-selector/tool-picker' const ToolsPicker = () => { + const [show, setShow] = React.useState(true) return ( - { }} - /> +
+ Click me
} + isShow={show} + onShowChange={setShow} + disabled={false} + supportAddCustomTool={true} + onSelect={() => { }} + /> + + ) } diff --git a/web/app/components/workflow/block-selector/tool-picker.tsx b/web/app/components/workflow/block-selector/tool-picker.tsx index db59d044d2..ffa6f3233c 100644 --- a/web/app/components/workflow/block-selector/tool-picker.tsx +++ b/web/app/components/workflow/block-selector/tool-picker.tsx @@ -2,6 +2,15 @@ import type { FC } from 'react' import React from 'react' import { useEffect, useState } from 'react' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import type { + OffsetOptions, + Placement, +} from '@floating-ui/react' import AllTools from '@/app/components/workflow/block-selector/all-tools' import type { ToolDefaultValue } from './types' import { @@ -12,11 +21,23 @@ import { import type { BlockEnum, ToolWithProvider } from '@/app/components/workflow/types' type Props = { + disabled: boolean + trigger: React.ReactNode + placement?: Placement + offset?: OffsetOptions + isShow: boolean + onShowChange: (isShow: boolean) => void onSelect: (tool: ToolDefaultValue) => void supportAddCustomTool?: boolean } const ToolPicker: FC = ({ + disabled, + trigger, + placement = 'right-start', + offset = 0, + isShow, + onShowChange, onSelect, supportAddCustomTool, }) => { @@ -37,23 +58,44 @@ const ToolPicker: FC = ({ })() }, []) + const handleTriggerClick = () => { + if (disabled) return + onShowChange(true) + } + const handleSelect = (_type: BlockEnum, tool?: ToolDefaultValue) => { onSelect(tool!) } return ( -
- setSearchText(e.target.value)} /> - -
+ + + {trigger} + + + +
+ setSearchText(e.target.value)} /> + +
+
+
) } From 197f1b39573606b53c8bdff0ed5f231717bed67b Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Fri, 1 Nov 2024 11:26:36 +0800 Subject: [PATCH 02/18] feat: search box --- .../plugins/marketplace/search-box/index.tsx | 24 +++++++++++-------- .../search-box/search-box-wrapper.tsx | 6 ++++- .../marketplace/search-box/tags-filter.tsx | 10 ++++++-- .../workflow/block-selector/tool-picker.tsx | 10 +++++++- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/web/app/components/plugins/marketplace/search-box/index.tsx b/web/app/components/plugins/marketplace/search-box/index.tsx index 12682bd725..7ca9ce17e0 100644 --- a/web/app/components/plugins/marketplace/search-box/index.tsx +++ b/web/app/components/plugins/marketplace/search-box/index.tsx @@ -1,6 +1,5 @@ 'use client' import { RiCloseLine } from '@remixicon/react' -import { useMarketplaceContext } from '../context' import TagsFilter from './tags-filter' import ActionButton from '@/app/components/base/action-button' import cn from '@/utils/classnames' @@ -11,6 +10,8 @@ type SearchBoxProps = { inputClassName?: string tags: string[] onTagsChange: (tags: string[]) => void + size?: 'small' | 'large' + placeholder?: string } const SearchBox = ({ search, @@ -18,36 +19,39 @@ const SearchBox = ({ inputClassName, tags, onTagsChange, + size = 'small', + placeholder = 'Search tools...', }: SearchBoxProps) => { - const intersected = useMarketplaceContext(v => v.intersected) - const searchPluginText = useMarketplaceContext(v => v.searchPluginText) - const handleSearchPluginTextChange = useMarketplaceContext(v => v.handleSearchPluginTextChange) - return (
{ onSearchChange(e.target.value) }} + placeholder={placeholder} /> { - searchPluginText && ( - handleSearchPluginTextChange('')}> + search && ( + onSearchChange('')}> ) diff --git a/web/app/components/plugins/marketplace/search-box/search-box-wrapper.tsx b/web/app/components/plugins/marketplace/search-box/search-box-wrapper.tsx index 0758d7785b..a124d93eb4 100644 --- a/web/app/components/plugins/marketplace/search-box/search-box-wrapper.tsx +++ b/web/app/components/plugins/marketplace/search-box/search-box-wrapper.tsx @@ -12,11 +12,15 @@ const SearchBoxWrapper = () => { return ( ) } diff --git a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx index 51746fddb4..5114765544 100644 --- a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx +++ b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx @@ -18,10 +18,12 @@ import Input from '@/app/components/base/input' type TagsFilterProps = { tags: string[] onTagsChange: (tags: string[]) => void + size: 'small' | 'large' } const TagsFilter = ({ tags, onTagsChange, + size, }: TagsFilterProps) => { const [open, setOpen] = useState(false) const [searchText, setSearchText] = useState('') @@ -56,7 +58,9 @@ const TagsFilter = ({ > setOpen(v => !v)}>
@@ -65,6 +69,8 @@ const TagsFilter = ({
{ !selectedTagsLength && 'All Tags' @@ -95,7 +101,7 @@ const TagsFilter = ({ }
- +
= ({
- setSearchText(e.target.value)} /> + {}} + size='small' + placeholder='Search tools...' + /> Date: Thu, 31 Oct 2024 19:17:21 +0800 Subject: [PATCH 03/18] search model in provider settings --- .../header/account-setting/index.tsx | 4 +- .../model-provider-page/index.tsx | 68 +++++++++++++++---- .../system-model-selector/index.tsx | 1 + .../plugins/marketplace/context.tsx | 2 +- .../components/plugins/marketplace/hooks.ts | 2 +- web/app/components/tools/marketplace/hooks.ts | 2 +- 6 files changed, 59 insertions(+), 20 deletions(-) diff --git a/web/app/components/header/account-setting/index.tsx b/web/app/components/header/account-setting/index.tsx index c530d3268f..9df7065733 100644 --- a/web/app/components/header/account-setting/index.tsx +++ b/web/app/components/header/account-setting/index.tsx @@ -199,13 +199,13 @@ export default function AccountSetting({ )}
+ {activeMenu === 'provider' && } {activeMenu === 'members' && } {activeMenu === 'billing' && } - {activeMenu === 'language' && } - {activeMenu === 'provider' && } {activeMenu === 'data-source' && } {activeMenu === 'api-based-extension' && } {activeMenu === 'custom' && } + {activeMenu === 'language' && }
diff --git a/web/app/components/header/account-setting/model-provider-page/index.tsx b/web/app/components/header/account-setting/model-provider-page/index.tsx index e3542bc327..87f7c25b9c 100644 --- a/web/app/components/header/account-setting/model-provider-page/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/index.tsx @@ -1,13 +1,13 @@ -import { useMemo, useState } from 'react' +import { useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import Link from 'next/link' +import { useDebounce } from 'ahooks' import { RiAlertFill, RiArrowDownSLine, RiArrowRightUpLine, RiBrainLine, } from '@remixicon/react' -import { useContext } from 'use-context-selector' import SystemModelSelector from './system-model-selector' import ProviderAddedCard, { UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST } from './provider-added-card' // import ProviderCard from './provider-card' @@ -26,16 +26,23 @@ import { useUpdateModelProviders, } from './hooks' import Divider from '@/app/components/base/divider' +import Loading from '@/app/components/base/loading' import ProviderCard from '@/app/components/plugins/provider-card' -import I18n from '@/context/i18n' import { useProviderContext } from '@/context/provider-context' import { useModalContextSelector } from '@/context/modal-context' import { useEventEmitterContextContext } from '@/context/event-emitter' +import { + useMarketplacePlugins, +} from '@/app/components/plugins/marketplace/hooks' +import { PluginType } from '@/app/components/plugins/types' import cn from '@/utils/classnames' -import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' +type Props = { + searchText: string +} -const ModelProviderPage = () => { +const ModelProviderPage = ({ searchText }: Props) => { + const debouncedSearchText = useDebounce(searchText, { wait: 500 }) const { t } = useTranslation() const { eventEmitter } = useEventEmitterContextContext() const updateModelProviders = useUpdateModelProviders() @@ -67,6 +74,18 @@ const ModelProviderPage = () => { return [configuredProviders, notConfiguredProviders] }, [providers]) + const [filteredConfiguredProviders, filteredNotConfiguredProviders] = useMemo(() => { + const filteredConfiguredProviders = configuredProviders.filter( + provider => provider.provider.toLowerCase().includes(debouncedSearchText.toLowerCase()) + || Object.values(provider.label).some(text => text.toLowerCase().includes(debouncedSearchText.toLowerCase())), + ) + const filteredNotConfiguredProviders = notConfiguredProviders.filter( + provider => provider.provider.toLowerCase().includes(debouncedSearchText.toLowerCase()) + || Object.values(provider.label).some(text => text.toLowerCase().includes(debouncedSearchText.toLowerCase())), + ) + + return [filteredConfiguredProviders, filteredNotConfiguredProviders] + }, [configuredProviders, debouncedSearchText, notConfiguredProviders]) const handleOpenModal = ( provider: ModelProvider, @@ -102,10 +121,28 @@ const ModelProviderPage = () => { } const [collapse, setCollapse] = useState(false) - const { locale } = useContext(I18n) - // TODO #Plugin list API# - const pluginList = [toolNotion, extensionDallE, modelGPT4] + const { + plugins, + queryPlugins, + queryPluginsWithDebounced, + isLoading: isPluginsLoading, + } = useMarketplacePlugins() + + useEffect(() => { + if (searchText) { + queryPluginsWithDebounced({ + query: searchText, + category: PluginType.model, + }) + } + else { + queryPlugins({ + query: searchText, + category: PluginType.model, + }) + } + }, [queryPlugins, queryPluginsWithDebounced, searchText]) return (
@@ -132,7 +169,7 @@ const ModelProviderPage = () => { />
- {!configuredProviders?.length && ( + {!filteredConfiguredProviders?.length && (
@@ -141,9 +178,9 @@ const ModelProviderPage = () => {
{t('common.modelProvider.emptyProviderTip')}
)} - {!!configuredProviders?.length && ( + {!!filteredConfiguredProviders?.length && (
- {configuredProviders?.map(provider => ( + {filteredConfiguredProviders?.map(provider => ( { ))}
)} - {false && !!notConfiguredProviders?.length && ( + {!!filteredNotConfiguredProviders?.length && ( <>
{t('common.modelProvider.configureRequired')}
- {notConfiguredProviders?.map(provider => ( + {filteredNotConfiguredProviders?.map(provider => ( {
- {!collapse && ( + {!collapse && !isPluginsLoading && (
- {pluginList.map((plugin, index) => ( + {plugins.map((plugin, index) => ( ))}
)} + {!collapse && isPluginsLoading && }
) diff --git a/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx b/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx index d125bd99fb..578fcbe716 100644 --- a/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx @@ -132,6 +132,7 @@ const SystemModel: FC = ({ > setOpen(v => !v)}> diff --git a/web/app/components/plugins/provider-card.tsx b/web/app/components/plugins/provider-card.tsx index 7d9f21ea43..2ced311100 100644 --- a/web/app/components/plugins/provider-card.tsx +++ b/web/app/components/plugins/provider-card.tsx @@ -1,8 +1,6 @@ 'use client' import React from 'react' -import { useContext } from 'use-context-selector' import type { FC } from 'react' -import Link from 'next/link' import { RiArrowRightUpLine, RiVerifiedBadgeLine } from '@remixicon/react' import Badge from '../base/badge' import type { Plugin } from './types' @@ -11,70 +9,66 @@ import Icon from './card/base/card-icon' import Title from './card/base/title' import DownloadCount from './card/base/download-count' import Button from '@/app/components/base/button' +import { useGetLanguage } from '@/context/i18n' +import { MARKETPLACE_URL_PREFIX } from '@/config' import cn from '@/utils/classnames' -import I18n from '@/context/i18n' type Props = { className?: string payload: Plugin - installed?: boolean } const ProviderCard: FC = ({ className, payload, - installed = true, }) => { - const { locale } = useContext(I18n) + const language = useGetLanguage() const { org, label } = payload return (
- - {/* Header */} -
- -
-
- - <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> - </div> - <div className='mb-1 flex justify-between items-center h-4'> - <div className='flex items-center'> - <div className='text-text-tertiary system-xs-regular'>{org}</div> - <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> - <DownloadCount downloadCount={payload.install_count || 0} /> - </div> + {/* Header */} + <div className="flex"> + <Icon src={payload.icon} /> + <div className="ml-3 w-0 grow"> + <div className="flex items-center h-5"> + <Title title={label[language]} /> + <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + </div> + <div className='mb-1 flex justify-between items-center h-4'> + <div className='flex items-center'> + <div className='text-text-tertiary system-xs-regular'>{org}</div> + <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> + <DownloadCount downloadCount={payload.install_count || 0} /> </div> </div> </div> - <Description className='mt-3' text={payload.brief[locale]} descriptionLineRows={2}></Description> - <div className='mt-3 flex space-x-0.5'> - {['LLM', 'text embedding', 'speech2text'].map(tag => ( - <Badge key={tag} text={tag} /> - ))} - </div> - {!installed && ( - <div - className='hidden group-hover:flex items-center gap-2 absolute bottom-0 left-0 right-0 p-4 pt-8' - style={{ background: 'linear-gradient(0deg, #F9FAFB 60.27%, rgba(249, 250, 251, 0.00) 100%)' }} - > - <Button - className='flex-grow' - variant='primary' - > - Install - </Button> - <Button - className='flex-grow' - variant='secondary' - > - Details - <RiArrowRightUpLine className='w-4 h-4' /> - </Button> - </div> - )} - </Link> + </div> + <Description className='mt-3' text={payload.brief[language]} descriptionLineRows={2}></Description> + <div className='mt-3 flex space-x-0.5'> + {payload.tags.map(tag => ( + <Badge key={tag.name} text={tag.name} /> + ))} + </div> + <div + className='hidden group-hover:flex items-center gap-2 absolute bottom-0 left-0 right-0 p-4 pt-8 rounded-xl bg-gradient-to-tr from-[#f9fafb] to-[rgba(249,250,251,0)]' + > + <Button + className='flex-grow' + variant='primary' + > + Install + </Button> + <Button + className='flex-grow' + variant='secondary' + > + <a href={`${MARKETPLACE_URL_PREFIX}/plugin/${payload.org}/${payload.name}`} target='_blank' className='flex items-center gap-0.5'> + Details + <RiArrowRightUpLine className='w-4 h-4' /> + </a> + </Button> + </div> </div> ) } diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index ae16b0b300..3c7894a576 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -103,6 +103,7 @@ export type Plugin = { type: PluginType org: string name: string + plugin_id: string version: string latest_version: string icon: string From 96c3ec91af32766039862bc5c1e6845183c55159 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Thu, 31 Oct 2024 20:19:40 +0800 Subject: [PATCH 05/18] click handle of provider card --- .../plugins/marketplace/list/card-wrapper.tsx | 11 +++++++---- web/app/components/plugins/provider-card.tsx | 6 ++++-- web/i18n/en-US/plugin.ts | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/web/app/components/plugins/marketplace/list/card-wrapper.tsx b/web/app/components/plugins/marketplace/list/card-wrapper.tsx index c9d83f32ac..4ef5dccb65 100644 --- a/web/app/components/plugins/marketplace/list/card-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/card-wrapper.tsx @@ -1,5 +1,6 @@ 'use client' import { RiArrowRightUpLine } from '@remixicon/react' +import { useTranslation } from 'react-i18next' import Card from '@/app/components/plugins/card' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import type { Plugin } from '@/app/components/plugins/types' @@ -14,6 +15,7 @@ const CardWrapper = ({ plugin, showInstallButton, }: CardWrapperProps) => { + const { t } = useTranslation() return ( <div className='group relative rounded-xl cursor-pointer'> <Card @@ -33,14 +35,15 @@ const CardWrapper = ({ variant='primary' className='flex-1' > - Install + {t('plugin.detailPanel.operation.install')} </Button> <Button className='flex-1' > - <a href={`${MARKETPLACE_URL_PREFIX}/plugin/${plugin.org}/${plugin.name}`} target='_blank' className='flex items-center gap-0.5'></a> - Details - <RiArrowRightUpLine className='ml-1 w-4 h-4' /> + <a href={`${MARKETPLACE_URL_PREFIX}/plugin/${plugin.org}/${plugin.name}`} target='_blank' className='flex items-center gap-0.5'> + {t('plugin.detailPanel.operation.detail')} + <RiArrowRightUpLine className='ml-1 w-4 h-4' /> + </a> </Button> </div> ) diff --git a/web/app/components/plugins/provider-card.tsx b/web/app/components/plugins/provider-card.tsx index 2ced311100..15b78acd82 100644 --- a/web/app/components/plugins/provider-card.tsx +++ b/web/app/components/plugins/provider-card.tsx @@ -1,6 +1,7 @@ 'use client' import React from 'react' import type { FC } from 'react' +import { useTranslation } from 'react-i18next' import { RiArrowRightUpLine, RiVerifiedBadgeLine } from '@remixicon/react' import Badge from '../base/badge' import type { Plugin } from './types' @@ -22,6 +23,7 @@ const ProviderCard: FC<Props> = ({ className, payload, }) => { + const { t } = useTranslation() const language = useGetLanguage() const { org, label } = payload @@ -57,14 +59,14 @@ const ProviderCard: FC<Props> = ({ className='flex-grow' variant='primary' > - Install + {t('plugin.detailPanel.operation.install')} </Button> <Button className='flex-grow' variant='secondary' > <a href={`${MARKETPLACE_URL_PREFIX}/plugin/${payload.org}/${payload.name}`} target='_blank' className='flex items-center gap-0.5'> - Details + {t('plugin.detailPanel.operation.detail')} <RiArrowRightUpLine className='w-4 h-4' /> </a> </Button> diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index dc615d3a94..0801ee21b6 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -13,7 +13,7 @@ const translation = { }, operation: { install: 'Install', - detail: 'Detail', + detail: 'Details', update: 'Update', info: 'Plugin Info', checkUpdate: 'Check Update', From 32e4efb5246103e769a3363e7efca574dfb28fda Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 1 Nov 2024 11:59:29 +0800 Subject: [PATCH 06/18] Revert "logs" This reverts commit 06729f6d9d45a9625031be5f202fc6cd9481e5bf. --- web/models/log.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/web/models/log.ts b/web/models/log.ts index 99467c3f67..dc557bfe21 100644 --- a/web/models/log.ts +++ b/web/models/log.ts @@ -107,7 +107,6 @@ export type MessageContent = { agent_thoughts: any[] // TODO workflow_run_id: string parent_message_id: string | null - plugin_id: string } export type CompletionConversationGeneralDetail = { @@ -130,7 +129,6 @@ export type CompletionConversationGeneralDetail = { dislike: number } model_config: { - plugin_id: string provider: string model_id: string configs: Pick<ModelConfigDetail, 'prompt_template'> From 930425b896435e4d575351029916dd525b50f716 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 1 Nov 2024 11:59:36 +0800 Subject: [PATCH 07/18] Revert "annotation config" This reverts commit 633768cd2aae52929372ab5cdb11fd90a7920320. --- web/app/components/app/annotation/index.tsx | 3 +- web/app/components/app/annotation/type.ts | 3 +- .../toolbox/annotation/config-param.tsx | 124 ++++++++++++++++++ .../app/configuration/toolbox/index.tsx | 45 +++++++ .../annotation-reply/config-param-modal.tsx | 6 - web/models/debug.ts | 1 - web/service/annotation.ts | 4 +- 7 files changed, 172 insertions(+), 14 deletions(-) create mode 100644 web/app/components/app/configuration/toolbox/annotation/config-param.tsx create mode 100644 web/app/components/app/configuration/toolbox/index.tsx diff --git a/web/app/components/app/annotation/index.tsx b/web/app/components/app/annotation/index.tsx index e287f6970f..46ecdd5480 100644 --- a/web/app/components/app/annotation/index.tsx +++ b/web/app/components/app/annotation/index.tsx @@ -27,7 +27,7 @@ import AnnotationFullModal from '@/app/components/billing/annotation-full/modal' import { Settings04 } from '@/app/components/base/icons/src/vender/line/general' import type { App } from '@/types/app' -type Props = { +interface Props { appDetail: App } @@ -283,7 +283,6 @@ const Annotation: FC<Props> = ({ if ( embeddingModel.embedding_model_name !== annotationConfig?.embedding_model?.embedding_model_name || embeddingModel.embedding_provider_name !== annotationConfig?.embedding_model?.embedding_provider_name - || embeddingModel.plugin_id !== annotationConfig?.embedding_model?.plugin_id ) { const { job_id: jobId }: any = await updateAnnotationStatus(appDetail.id, AnnotationEnableStatus.enable, embeddingModel, score) await ensureJobCompleted(jobId, AnnotationEnableStatus.enable) diff --git a/web/app/components/app/annotation/type.ts b/web/app/components/app/annotation/type.ts index 28811f4617..5df6f51ace 100644 --- a/web/app/components/app/annotation/type.ts +++ b/web/app/components/app/annotation/type.ts @@ -23,9 +23,8 @@ export type HitHistoryItem = { } export type EmbeddingModelConfig = { - plugin_id: string - embedding_model_name: string embedding_provider_name: string + embedding_model_name: string } export enum AnnotationEnableStatus { diff --git a/web/app/components/app/configuration/toolbox/annotation/config-param.tsx b/web/app/components/app/configuration/toolbox/annotation/config-param.tsx new file mode 100644 index 0000000000..e418a76c34 --- /dev/null +++ b/web/app/components/app/configuration/toolbox/annotation/config-param.tsx @@ -0,0 +1,124 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import { useContext } from 'use-context-selector' +import { usePathname, useRouter } from 'next/navigation' +import ConfigParamModal from './config-param-modal' +import Panel from '@/app/components/app/configuration/base/feature-panel' +import { MessageFast } from '@/app/components/base/icons/src/vender/solid/communication' +import Tooltip from '@/app/components/base/tooltip' +import { LinkExternal02, Settings04 } from '@/app/components/base/icons/src/vender/line/general' +import ConfigContext from '@/context/debug-configuration' +import type { EmbeddingModelConfig } from '@/app/components/app/annotation/type' +import { fetchAnnotationConfig, updateAnnotationScore } from '@/service/annotation' +import type { AnnotationReplyConfig as AnnotationReplyConfigType } from '@/models/debug' + +type Props = { + onEmbeddingChange: (embeddingModel: EmbeddingModelConfig) => void + onScoreChange: (score: number, embeddingModel?: EmbeddingModelConfig) => void +} + +export const Item: FC<{ title: string; tooltip: string; children: JSX.Element }> = ({ + title, + tooltip, + children, +}) => { + return ( + <div> + <div className='flex items-center space-x-1'> + <div>{title}</div> + <Tooltip + popupContent={ + <div className='max-w-[200px] leading-[18px] text-[13px] font-medium text-gray-800'>{tooltip}</div> + } + /> + </div> + <div>{children}</div> + </div> + ) +} + +const AnnotationReplyConfig: FC<Props> = ({ + onEmbeddingChange, + onScoreChange, +}) => { + const { t } = useTranslation() + const router = useRouter() + const pathname = usePathname() + const matched = pathname.match(/\/app\/([^/]+)/) + const appId = (matched?.length && matched[1]) ? matched[1] : '' + const { + annotationConfig, + } = useContext(ConfigContext) + + const [isShowEdit, setIsShowEdit] = React.useState(false) + + return ( + <> + <Panel + className="mt-4" + headerIcon={ + <MessageFast className='w-4 h-4 text-[#444CE7]' /> + } + title={t('appDebug.feature.annotation.title')} + headerRight={ + <div className='flex items-center'> + <div + className='flex items-center rounded-md h-7 px-3 space-x-1 text-gray-700 cursor-pointer hover:bg-gray-200' + onClick={() => { setIsShowEdit(true) }} + > + <Settings04 className="w-[14px] h-[14px]" /> + <div className='text-xs font-medium'> + + {t('common.operation.params')} + </div> + </div> + <div + className='ml-1 flex items-center h-7 px-3 space-x-1 leading-[18px] text-xs font-medium text-gray-700 rounded-md cursor-pointer hover:bg-gray-200' + onClick={() => { + router.push(`/app/${appId}/annotations`) + }}> + <div>{t('appDebug.feature.annotation.cacheManagement')}</div> + <LinkExternal02 className='w-3.5 h-3.5' /> + </div> + </div> + } + noBodySpacing + /> + {isShowEdit && ( + <ConfigParamModal + appId={appId} + isShow + onHide={() => { + setIsShowEdit(false) + }} + onSave={async (embeddingModel, score) => { + const annotationConfig = await fetchAnnotationConfig(appId) as AnnotationReplyConfigType + let isEmbeddingModelChanged = false + if ( + embeddingModel.embedding_model_name !== annotationConfig.embedding_model.embedding_model_name + || embeddingModel.embedding_provider_name !== annotationConfig.embedding_model.embedding_provider_name + ) { + await onEmbeddingChange(embeddingModel) + isEmbeddingModelChanged = true + } + + if (score !== annotationConfig.score_threshold) { + await updateAnnotationScore(appId, annotationConfig.id, score) + if (isEmbeddingModelChanged) + onScoreChange(score, embeddingModel) + + else + onScoreChange(score) + } + + setIsShowEdit(false) + }} + annotationConfig={annotationConfig} + /> + )} + </> + ) +} +export default React.memo(AnnotationReplyConfig) diff --git a/web/app/components/app/configuration/toolbox/index.tsx b/web/app/components/app/configuration/toolbox/index.tsx new file mode 100644 index 0000000000..00ea301a42 --- /dev/null +++ b/web/app/components/app/configuration/toolbox/index.tsx @@ -0,0 +1,45 @@ +'use client' + +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import GroupName from '../base/group-name' +import Moderation from './moderation' +import Annotation from './annotation/config-param' +import type { EmbeddingModelConfig } from '@/app/components/app/annotation/type' + +export type ToolboxProps = { + showModerationSettings: boolean + showAnnotation: boolean + onEmbeddingChange: (embeddingModel: EmbeddingModelConfig) => void + onScoreChange: (score: number, embeddingModel?: EmbeddingModelConfig) => void +} + +const Toolbox: FC<ToolboxProps> = ({ + showModerationSettings, + showAnnotation, + onEmbeddingChange, + onScoreChange, +}) => { + const { t } = useTranslation() + + return ( + <div className='mt-7'> + <GroupName name={t('appDebug.feature.toolbox.title')} /> + { + showModerationSettings && ( + <Moderation /> + ) + } + { + showAnnotation && ( + <Annotation + onEmbeddingChange={onEmbeddingChange} + onScoreChange={onScoreChange} + /> + ) + } + </div> + ) +} +export default React.memo(Toolbox) diff --git a/web/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.tsx index 6309498d20..801f1348ee 100644 --- a/web/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.tsx +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.tsx @@ -18,7 +18,6 @@ type Props = { isShow: boolean onHide: () => void onSave: (embeddingModel: { - plugin_id: string embedding_provider_name: string embedding_model_name: string }, score: number) => void @@ -44,13 +43,11 @@ const ConfigParamModal: FC<Props> = ({ const [isLoading, setLoading] = useState(false) const [embeddingModel, setEmbeddingModel] = useState(oldAnnotationConfig.embedding_model ? { - plugin_id: oldAnnotationConfig.embedding_model.plugin_id, providerName: oldAnnotationConfig.embedding_model.embedding_provider_name, modelName: oldAnnotationConfig.embedding_model.embedding_model_name, } : (embeddingsDefaultModel ? { - plugin_id: embeddingsDefaultModel.provider.plugin_id, providerName: embeddingsDefaultModel.provider.provider, modelName: embeddingsDefaultModel.model, } @@ -70,7 +67,6 @@ const ConfigParamModal: FC<Props> = ({ } setLoading(true) await onSave({ - plugin_id: embeddingModel.plugin_id, embedding_provider_name: embeddingModel.providerName, embedding_model_name: embeddingModel.modelName, }, annotationConfig.score_threshold) @@ -111,14 +107,12 @@ const ConfigParamModal: FC<Props> = ({ <div className='pt-1'> <ModelSelector defaultModel={embeddingModel && { - plugin_id: '', provider: embeddingModel.providerName, model: embeddingModel.modelName, }} modelList={embeddingsModelList} onSelect={(val) => { setEmbeddingModel({ - plugin_id: val.plugin_id, providerName: val.provider, modelName: val.model, }) diff --git a/web/models/debug.ts b/web/models/debug.ts index fe85544fa7..64a6cb7f84 100644 --- a/web/models/debug.ts +++ b/web/models/debug.ts @@ -93,7 +93,6 @@ export type AnnotationReplyConfig = { enabled: boolean score_threshold: number embedding_model: { - plugin_id: string embedding_provider_name: string embedding_model_name: string } diff --git a/web/service/annotation.ts b/web/service/annotation.ts index 868f82bedc..5096a4f58a 100644 --- a/web/service/annotation.ts +++ b/web/service/annotation.ts @@ -13,9 +13,7 @@ export const updateAnnotationStatus = (appId: string, action: AnnotationEnableSt if (embeddingModel) { body = { ...body, - embedding_model_plugin_id: embeddingModel.plugin_id, - embedding_provider_name: embeddingModel.embedding_provider_name, - embedding_model_name: embeddingModel.embedding_model_name, + ...embeddingModel, } } From f2a5da918b89735c5c64d996e71c0c14a1cf1126 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 1 Nov 2024 11:59:38 +0800 Subject: [PATCH 08/18] Revert "other providers" This reverts commit 339dfe5e029dba251ab024de4b414e916ed85b5a. --- .../model-provider-page/hooks.ts | 1 - .../provider-added-card/credential-panel.tsx | 2 +- web/hooks/use-pay.tsx | 68 ++++++++++++++++++- web/service/common.ts | 4 ++ 4 files changed, 71 insertions(+), 4 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/hooks.ts b/web/app/components/header/account-setting/model-provider-page/hooks.ts index e34c09d651..36aba3bc39 100644 --- a/web/app/components/header/account-setting/model-provider-page/hooks.ts +++ b/web/app/components/header/account-setting/model-provider-page/hooks.ts @@ -199,7 +199,6 @@ export const useUpdateModelList = () => { return updateModelList } -// deprecated ??? export const useAnthropicBuyQuota = () => { const [loading, setLoading] = useState(false) diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx index 9d0c979de2..ac82dce3bf 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx @@ -41,7 +41,7 @@ const CredentialPanel: FC<CredentialPanelProps> = ({ const handleChangePriority = async (key: PreferredProviderTypeEnum) => { const res = await changeModelProviderPriority({ - url: `/workspaces/current/model-providers/${provider.plugin_id}/${provider.provider}/preferred-provider-type`, + url: `/workspaces/current/model-providers/${provider.provider}/preferred-provider-type`, body: { preferred_provider_type: key, }, diff --git a/web/hooks/use-pay.tsx b/web/hooks/use-pay.tsx index 3ba23b6763..344f03955c 100644 --- a/web/hooks/use-pay.tsx +++ b/web/hooks/use-pay.tsx @@ -4,8 +4,11 @@ import { useCallback, useEffect, useState } from 'react' import { useRouter, useSearchParams } from 'next/navigation' import { useTranslation } from 'react-i18next' import useSWR from 'swr' +import { useContext } from 'use-context-selector' +import I18n from '@/context/i18n' import { fetchDataSourceNotionBinding, + fetchFreeQuotaVerify, } from '@/service/common' import type { IConfirm } from '@/app/components/base/confirm' import Confirm from '@/app/components/base/confirm' @@ -50,6 +53,66 @@ export const useBillingPay = () => { return confirm } +const QUOTA_RECEIVE_STATUS: Record<string, any> = { + spark: { + success: { + 'en': 'Successful collection, the quota will be automatically increased after 5 minutes.', + 'zh-Hans': '领取成功,将在 5 分钟后自动增加配额', + }, + fail: { + 'en': 'Failure to collect', + 'zh-Hans': '领取失败', + }, + }, + zhipuai: { + success: { + 'en': 'Successful collection', + 'zh-Hans': '领取成功', + }, + fail: { + 'en': 'Failure to collect', + 'zh-Hans': '领取失败', + }, + }, +} + +const FREE_CHECK_PROVIDER = ['spark', 'zhipuai'] +export const useCheckFreeQuota = () => { + const { locale } = useContext(I18n) + const router = useRouter() + const [shouldVerify, setShouldVerify] = useState(false) + const searchParams = useSearchParams() + const type = searchParams.get('type') + const provider = searchParams.get('provider') + const result = searchParams.get('result') + const token = searchParams.get('token') + + const { data, error } = useSWR( + shouldVerify + ? `/workspaces/current/model-providers/${provider}/free-quota-qualification-verify?token=${token}` + : null, + fetchFreeQuotaVerify, + ) + + useEffect(() => { + if (error) + router.replace('/') + }, [error, router]) + + useEffect(() => { + if (type === 'provider_apply_callback' && FREE_CHECK_PROVIDER.includes(provider as string) && result === 'success') + setShouldVerify(true) + }, [type, provider, result]) + + return (data && provider) + ? { + type: data.flag ? 'info' : 'warning', + title: data.flag ? QUOTA_RECEIVE_STATUS[provider as string].success[locale] : QUOTA_RECEIVE_STATUS[provider].fail[locale], + desc: !data.flag ? data.reason : undefined, + } + : null +} + export const useCheckNotion = () => { const router = useRouter() const [confirm, setConfirm] = useState<ConfirmType | null>(null) @@ -91,6 +154,7 @@ export const CheckModal = () => { const { t } = useTranslation() const [showPayStatusModal, setShowPayStatusModal] = useState(true) const anthropicConfirmInfo = useAnthropicCheckPay() + const freeQuotaConfirmInfo = useCheckFreeQuota() const notionConfirmInfo = useCheckNotion() const billingConfirmInfo = useBillingPay() @@ -99,7 +163,7 @@ export const CheckModal = () => { router.replace('/') }, [router]) - const confirmInfo = anthropicConfirmInfo || notionConfirmInfo || billingConfirmInfo + const confirmInfo = anthropicConfirmInfo || freeQuotaConfirmInfo || notionConfirmInfo || billingConfirmInfo if (!confirmInfo || !showPayStatusModal) return null @@ -112,7 +176,7 @@ export const CheckModal = () => { showCancel={false} type={confirmInfo.type === 'info' ? 'info' : 'warning' } title={confirmInfo.title} - content={(confirmInfo as unknown as { desc: string }).desc || ''} + content={(confirmInfo as { desc: string }).desc || ''} confirmText={(confirmInfo.type === 'info' && t('common.operation.ok')) || ''} /> ) diff --git a/web/service/common.ts b/web/service/common.ts index 70586b6ff6..1fc9b60f45 100644 --- a/web/service/common.ts +++ b/web/service/common.ts @@ -257,6 +257,10 @@ export const fetchFileUploadConfig: Fetcher<FileUploadConfigResponse, { url: str return get<FileUploadConfigResponse>(url) } +export const fetchFreeQuotaVerify: Fetcher<{ result: string; flag: boolean; reason: string }, string> = (url) => { + return get(url) as Promise<{ result: string; flag: boolean; reason: string }> +} + export const fetchNotionConnection: Fetcher<{ data: string }, string> = (url) => { return get(url) as Promise<{ data: string }> } From c39be7852ff98391ed91e8834c598a17dd7a93eb Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 1 Nov 2024 11:59:40 +0800 Subject: [PATCH 09/18] Revert "parameters and rules" This reverts commit 22696fa75be09f8b13d4fb01ece2e92cf46e0fd9. --- .../params-config/config-content.tsx | 11 ++-- .../model-parameter-trigger.tsx | 4 +- .../app/configuration/debug/types.ts | 1 - .../components/app/configuration/index.tsx | 14 ++--- .../model-parameter-modal/index.tsx | 17 ++---- .../model-selector/index.tsx | 4 +- .../model-selector/popup-item.tsx | 8 +-- .../model-selector/popup.tsx | 2 +- .../components/workflow/nodes/llm/panel.tsx | 1 - .../workflow/nodes/llm/use-config.ts | 3 +- .../nodes/parameter-extractor/panel.tsx | 1 - .../nodes/question-classifier/panel.tsx | 1 - .../nodes/question-classifier/types.ts | 2 +- web/app/components/workflow/types.ts | 51 +++++++++--------- web/models/debug.ts | 52 +++++++++---------- web/service/debug.ts | 8 +-- 16 files changed, 75 insertions(+), 105 deletions(-) diff --git a/web/app/components/app/configuration/dataset-config/params-config/config-content.tsx b/web/app/components/app/configuration/dataset-config/params-config/config-content.tsx index aa911d45e8..6b1983f5e2 100644 --- a/web/app/components/app/configuration/dataset-config/params-config/config-content.tsx +++ b/web/app/components/app/configuration/dataset-config/params-config/config-content.tsx @@ -25,7 +25,7 @@ import { useSelectedDatasetsMode } from '@/app/components/workflow/nodes/knowled import Switch from '@/app/components/base/switch' import Toast from '@/app/components/base/toast' -type Props = { +interface Props { datasetConfigs: DatasetConfigs onChange: (configs: DatasetConfigs, isRetrievalModeChange?: boolean) => void isInWorkflow?: boolean @@ -71,7 +71,6 @@ const ConfigContent: FC<Props> = ({ ? { ...rerankDefaultModel, provider: rerankDefaultModel.provider.provider, - plugin_id: rerankDefaultModel.provider.plugin_id, } : undefined, ) @@ -81,14 +80,12 @@ const ConfigContent: FC<Props> = ({ return { provider_name: datasetConfigs.reranking_model.reranking_provider_name, model_name: datasetConfigs.reranking_model.reranking_model_name, - plugin_id: datasetConfigs.reranking_model.reranking_plugin_id, } } else if (rerankDefaultModel) { return { provider_name: rerankDefaultModel.provider.provider, model_name: rerankDefaultModel.model, - plugin_id: rerankDefaultModel.provider.plugin_id, } } })() @@ -175,7 +172,7 @@ const ConfigContent: FC<Props> = ({ return false return datasetConfigs.reranking_enable - }, [canManuallyToggleRerank, datasetConfigs.reranking_enable, isRerankDefaultModelValid]) + }, [canManuallyToggleRerank, datasetConfigs.reranking_enable]) const handleDisabledSwitchClick = useCallback(() => { if (!currentRerankModel && !showRerankModel) @@ -303,14 +300,13 @@ const ConfigContent: FC<Props> = ({ </div> <div> <ModelSelector - defaultModel={rerankModel && { provider: rerankModel?.provider_name, model: rerankModel?.model_name, plugin_id: rerankModel?.plugin_id }} + defaultModel={rerankModel && { provider: rerankModel?.provider_name, model: rerankModel?.model_name }} onSelect={(v) => { onChange({ ...datasetConfigs, reranking_model: { reranking_provider_name: v.provider, reranking_model_name: v.model, - reranking_plugin_id: v.plugin_id, }, }) }} @@ -388,7 +384,6 @@ const ConfigContent: FC<Props> = ({ portalToFollowElemContentClassName='!z-[1002]' isAdvancedMode={true} mode={model?.mode} - pluginId={model?.plugin_id} provider={model?.provider} completionParams={model?.completion_params} modelId={model?.name} diff --git a/web/app/components/app/configuration/debug/debug-with-multiple-model/model-parameter-trigger.tsx b/web/app/components/app/configuration/debug/debug-with-multiple-model/model-parameter-trigger.tsx index 380d7363f6..155ebe21ca 100644 --- a/web/app/components/app/configuration/debug/debug-with-multiple-model/model-parameter-trigger.tsx +++ b/web/app/components/app/configuration/debug/debug-with-multiple-model/model-parameter-trigger.tsx @@ -36,13 +36,12 @@ const ModelParameterTrigger: FC<ModelParameterTriggerProps> = ({ const language = useLanguage() const index = multipleModelConfigs.findIndex(v => v.id === modelAndParameter.id) - const handleSelectModel = ({ modelId, provider, pluginId }: { modelId: string; provider: string; pluginId: string }) => { + const handleSelectModel = ({ modelId, provider }: { modelId: string; provider: string }) => { const newModelConfigs = [...multipleModelConfigs] newModelConfigs[index] = { ...newModelConfigs[index], model: modelId, provider, - plugin_id: pluginId, } onMultipleModelConfigsChange(true, newModelConfigs) } @@ -59,7 +58,6 @@ const ModelParameterTrigger: FC<ModelParameterTriggerProps> = ({ <ModelParameterModal mode={mode} isAdvancedMode={isAdvancedMode} - pluginId={modelAndParameter.plugin_id} provider={modelAndParameter.provider} modelId={modelAndParameter.model} completionParams={modelAndParameter.parameters} diff --git a/web/app/components/app/configuration/debug/types.ts b/web/app/components/app/configuration/debug/types.ts index cd51112262..ada665a7d2 100644 --- a/web/app/components/app/configuration/debug/types.ts +++ b/web/app/components/app/configuration/debug/types.ts @@ -1,7 +1,6 @@ export type ModelAndParameter = { id: string model: string - plugin_id: string provider: string parameters: Record<string, any> } diff --git a/web/app/components/app/configuration/index.tsx b/web/app/components/app/configuration/index.tsx index c74881d7f8..af50fc65c3 100644 --- a/web/app/components/app/configuration/index.tsx +++ b/web/app/components/app/configuration/index.tsx @@ -72,7 +72,7 @@ import { SupportUploadFileTypes } from '@/app/components/workflow/types' import NewFeaturePanel from '@/app/components/base/features/new-feature-panel' import { fetchFileUploadConfig } from '@/service/common' -type PublishConfig = { +interface PublishConfig { modelConfig: ModelConfig completionParams: FormValue } @@ -156,7 +156,6 @@ const Configuration: FC = () => { const setCompletionParams = (value: FormValue) => { const params = { ...value } - // eslint-disable-next-line ts/no-use-before-define if ((!params.stop || params.stop.length === 0) && (modeModeTypeRef.current === ModelModeType.completion)) { params.stop = getTempStop() setTempStop([]) @@ -165,7 +164,6 @@ const Configuration: FC = () => { } const [modelConfig, doSetModelConfig] = useState<ModelConfig>({ - plugin_id: 'langgenius', provider: 'openai', model_id: 'gpt-3.5-turbo', mode: ModelModeType.unset, @@ -200,7 +198,6 @@ const Configuration: FC = () => { reranking_model: { reranking_provider_name: '', reranking_model_name: '', - reranking_plugin_id: '', }, top_k: DATASET_DEFAULT.top_k, score_threshold_enabled: false, @@ -282,7 +279,6 @@ const Configuration: FC = () => { reranking_model: restConfigs.reranking_model && { reranking_provider_name: restConfigs.reranking_model.reranking_provider_name, reranking_model_name: restConfigs.reranking_model.reranking_model_name, - reranking_plugin_id: restConfigs.reranking_model.reranking_plugin_id, }, retrieval_model, score_threshold_enabled, @@ -324,7 +320,6 @@ const Configuration: FC = () => { textGenerationModelList, } = useTextGenerationCurrentProviderAndModelAndModelList( { - plugin_id: modelConfig.plugin_id, provider: modelConfig.provider, model: modelConfig.model_id, }, @@ -355,7 +350,6 @@ const Configuration: FC = () => { const [canReturnToSimpleMode, setCanReturnToSimpleMode] = useState(true) const setPromptMode = async (mode: PromptMode) => { if (mode === PromptMode.advanced) { - // eslint-disable-next-line ts/no-use-before-define await migrateToDefaultPrompt() setCanReturnToSimpleMode(true) } @@ -551,7 +545,6 @@ const Configuration: FC = () => { const config = { modelConfig: { - plugin_id: model.plugin_id, provider: model.provider, model_id: model.name, mode: model.mode, @@ -770,8 +763,8 @@ const Configuration: FC = () => { handleMultipleModelConfigsChange( true, [ - { id: `${Date.now()}`, model: modelConfig.model_id, plugin_id: modelConfig.plugin_id, provider: modelConfig.provider, parameters: completionParams }, - { id: `${Date.now()}-no-repeat`, model: '', plugin_id: '', provider: '', parameters: {} }, + { id: `${Date.now()}`, model: modelConfig.model_id, provider: modelConfig.provider, parameters: completionParams }, + { id: `${Date.now()}-no-repeat`, model: '', provider: '', parameters: {} }, ], ) setAppSiderbarExpand('collapse') @@ -893,7 +886,6 @@ const Configuration: FC = () => { <ModelParameterModal isAdvancedMode={isAdvancedMode} mode={mode} - pluginId={modelConfig.plugin_id} provider={modelConfig.provider} completionParams={completionParams} modelId={modelConfig.model_id} diff --git a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx index c489778732..e21aa33d7a 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx @@ -38,9 +38,8 @@ export type ModelParameterModalProps = { isAdvancedMode: boolean mode: string modelId: string - pluginId: string provider: string - setModel: (model: { modelId: string; provider: string; pluginId: string; mode?: string; features?: string[] }) => void + setModel: (model: { modelId: string; provider: string; mode?: string; features?: string[] }) => void completionParams: FormValue onCompletionParamsChange: (newParams: FormValue) => void hideDebugWithMultipleModel?: boolean @@ -75,7 +74,6 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({ portalToFollowElemContentClassName, isAdvancedMode, modelId, - pluginId, provider, setModel, completionParams, @@ -90,17 +88,13 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({ const { t } = useTranslation() const { isAPIKeySet } = useProviderContext() const [open, setOpen] = useState(false) - const { data: parameterRulesData, isLoading } = useSWR((provider && modelId) ? `/workspaces/current/model-providers/${pluginId}/${provider}/models/parameter-rules?model=${modelId}` : null, fetchModelParameterRules) + const { data: parameterRulesData, isLoading } = useSWR((provider && modelId) ? `/workspaces/current/model-providers/${provider}/models/parameter-rules?model=${modelId}` : null, fetchModelParameterRules) const { currentProvider, currentModel, activeTextGenerationModelList, } = useTextGenerationCurrentProviderAndModelAndModelList( - { - plugin_id: pluginId, - provider, - model: modelId, - }, + { provider, model: modelId }, ) const hasDeprecated = !currentProvider || !currentModel @@ -118,12 +112,11 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({ }) } - const handleChangeModel = ({ provider, model, plugin_id }: DefaultModel) => { + const handleChangeModel = ({ provider, model }: DefaultModel) => { const targetProvider = activeTextGenerationModelList.find(modelItem => modelItem.provider === provider) const targetModelItem = targetProvider?.models.find(modelItem => modelItem.model === model) setModel({ modelId: model, - pluginId: plugin_id, provider, mode: targetModelItem?.model_properties.mode as string, features: targetModelItem?.features || [], @@ -208,7 +201,7 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({ {t('common.modelProvider.model').toLocaleUpperCase()} </div> <ModelSelector - defaultModel={(provider || modelId) ? { plugin_id: pluginId, provider, model: modelId } : undefined} + defaultModel={(provider || modelId) ? { provider, model: modelId } : undefined} modelList={activeTextGenerationModelList} onSelect={handleChangeModel} triggerClassName='max-w-[295px]' diff --git a/web/app/components/header/account-setting/model-provider-page/model-selector/index.tsx b/web/app/components/header/account-setting/model-provider-page/model-selector/index.tsx index a3c5a70b67..c6dd76a04f 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-selector/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-selector/index.tsx @@ -41,11 +41,11 @@ const ModelSelector: FC<ModelSelectorProps> = ({ defaultModel, ) - const handleSelect = (pluginId: string, provider: string, model: ModelItem) => { + const handleSelect = (provider: string, model: ModelItem) => { setOpen(false) if (onSelect) - onSelect({ plugin_id: pluginId, provider, model: model.model }) + onSelect({ provider, model: model.model }) } const handleToggle = () => { diff --git a/web/app/components/header/account-setting/model-provider-page/model-selector/popup-item.tsx b/web/app/components/header/account-setting/model-provider-page/model-selector/popup-item.tsx index ce62494220..d62131ac4c 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-selector/popup-item.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-selector/popup-item.tsx @@ -25,7 +25,7 @@ import Tooltip from '@/app/components/base/tooltip' type PopupItemProps = { defaultModel?: DefaultModel model: Model - onSelect: (pluginId: string, provider: string, model: ModelItem) => void + onSelect: (provider: string, model: ModelItem) => void } const PopupItem: FC<PopupItemProps> = ({ defaultModel, @@ -39,11 +39,11 @@ const PopupItem: FC<PopupItemProps> = ({ const updateModelList = useUpdateModelList() const updateModelProviders = useUpdateModelProviders() const currentProvider = modelProviders.find(provider => provider.provider === model.provider)! - const handleSelect = (pluginId: string, provider: string, modelItem: ModelItem) => { + const handleSelect = (provider: string, modelItem: ModelItem) => { if (modelItem.status !== ModelStatusEnum.active) return - onSelect(pluginId, provider, modelItem) + onSelect(provider, modelItem) } const handleOpenModelModal = () => { setShowModelModal({ @@ -80,7 +80,7 @@ const PopupItem: FC<PopupItemProps> = ({ group relative flex items-center px-3 py-1.5 h-8 rounded-lg ${modelItem.status === ModelStatusEnum.active ? 'cursor-pointer hover:bg-gray-50' : 'cursor-not-allowed hover:bg-gray-50/60'} `} - onClick={() => handleSelect(model.plugin_id, model.provider, modelItem)} + onClick={() => handleSelect(model.provider, modelItem)} > <ModelIcon className={` diff --git a/web/app/components/header/account-setting/model-provider-page/model-selector/popup.tsx b/web/app/components/header/account-setting/model-provider-page/model-selector/popup.tsx index dea7e86dca..1a910aba08 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-selector/popup.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-selector/popup.tsx @@ -15,7 +15,7 @@ import { XCircle } from '@/app/components/base/icons/src/vender/solid/general' type PopupProps = { defaultModel?: DefaultModel modelList: Model[] - onSelect: (pluginId: string, provider: string, model: ModelItem) => void + onSelect: (provider: string, model: ModelItem) => void } const Popup: FC<PopupProps> = ({ defaultModel, diff --git a/web/app/components/workflow/nodes/llm/panel.tsx b/web/app/components/workflow/nodes/llm/panel.tsx index 038522df46..76607b29b1 100644 --- a/web/app/components/workflow/nodes/llm/panel.tsx +++ b/web/app/components/workflow/nodes/llm/panel.tsx @@ -132,7 +132,6 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({ isInWorkflow isAdvancedMode={true} mode={model?.mode} - pluginId={model?.plugin_id} provider={model?.provider} completionParams={model?.completion_params} modelId={model?.name} diff --git a/web/app/components/workflow/nodes/llm/use-config.ts b/web/app/components/workflow/nodes/llm/use-config.ts index 7715383020..33742b0726 100644 --- a/web/app/components/workflow/nodes/llm/use-config.ts +++ b/web/app/components/workflow/nodes/llm/use-config.ts @@ -123,7 +123,7 @@ const useConfig = (id: string, payload: LLMNodeType) => { }, }) - const handleModelChanged = useCallback((model: { provider: string; modelId: string; pluginId: string; mode?: string }) => { + const handleModelChanged = useCallback((model: { provider: string; modelId: string; mode?: string }) => { const newInputs = produce(inputRef.current, (draft) => { draft.model.provider = model.provider draft.model.name = model.modelId @@ -139,7 +139,6 @@ const useConfig = (id: string, payload: LLMNodeType) => { useEffect(() => { if (currentProvider?.provider && currentModel?.model && !model.provider) { handleModelChanged({ - pluginId: currentProvider?.plugin_id, provider: currentProvider?.provider, modelId: currentModel?.model, mode: currentModel?.model_properties?.mode as string, diff --git a/web/app/components/workflow/nodes/parameter-extractor/panel.tsx b/web/app/components/workflow/nodes/parameter-extractor/panel.tsx index edadc2e4ba..e9d3856c71 100644 --- a/web/app/components/workflow/nodes/parameter-extractor/panel.tsx +++ b/web/app/components/workflow/nodes/parameter-extractor/panel.tsx @@ -77,7 +77,6 @@ const Panel: FC<NodePanelProps<ParameterExtractorNodeType>> = ({ isInWorkflow isAdvancedMode={true} mode={model?.mode} - pluginId={model?.plugin_id} provider={model?.provider} completionParams={model?.completion_params} modelId={model?.name} diff --git a/web/app/components/workflow/nodes/question-classifier/panel.tsx b/web/app/components/workflow/nodes/question-classifier/panel.tsx index 4b2866204b..523ec50019 100644 --- a/web/app/components/workflow/nodes/question-classifier/panel.tsx +++ b/web/app/components/workflow/nodes/question-classifier/panel.tsx @@ -65,7 +65,6 @@ const Panel: FC<NodePanelProps<QuestionClassifierNodeType>> = ({ isInWorkflow isAdvancedMode={true} mode={model?.mode} - pluginId={model?.plugin_id} provider={model?.provider} completionParams={model.completion_params} modelId={model.name} diff --git a/web/app/components/workflow/nodes/question-classifier/types.ts b/web/app/components/workflow/nodes/question-classifier/types.ts index ddc16b4501..ca102b083e 100644 --- a/web/app/components/workflow/nodes/question-classifier/types.ts +++ b/web/app/components/workflow/nodes/question-classifier/types.ts @@ -1,6 +1,6 @@ import type { CommonNodeType, Memory, ModelConfig, ValueSelector, VisionSetting } from '@/app/components/workflow/types' -export type Topic = { +export interface Topic { id: string name: string } diff --git a/web/app/components/workflow/types.ts b/web/app/components/workflow/types.ts index ef26d9465f..811ec0d70c 100644 --- a/web/app/components/workflow/types.ts +++ b/web/app/components/workflow/types.ts @@ -37,7 +37,7 @@ export enum ControlMode { Hand = 'hand', } -export type Branch = { +export interface Branch { id: string name: string } @@ -68,7 +68,7 @@ export type CommonNodeType<T = {}> = { height?: number } & T & Partial<Pick<ToolDefaultValue, 'provider_id' | 'provider_type' | 'provider_name' | 'tool_name'>> -export type CommonEdgeType = { +export interface CommonEdgeType { _hovering?: boolean _connectedNodeIsHovering?: boolean _connectedNodeIsSelected?: boolean @@ -82,14 +82,14 @@ export type CommonEdgeType = { export type Node<T = {}> = ReactFlowNode<CommonNodeType<T>> export type SelectedNode = Pick<Node, 'id' | 'data'> -export type NodeProps<T = unknown> = { id: string; data: CommonNodeType<T> } -export type NodePanelProps<T> = { +export interface NodeProps<T = unknown> { id: string; data: CommonNodeType<T> } +export interface NodePanelProps<T> { id: string data: CommonNodeType<T> } export type Edge = ReactFlowEdge<CommonEdgeType> -export type WorkflowDataUpdater = { +export interface WorkflowDataUpdater { nodes: Node[] edges: Edge[] viewport: Viewport @@ -97,7 +97,7 @@ export type WorkflowDataUpdater = { export type ValueSelector = string[] // [nodeId, key | obj key path] -export type Variable = { +export interface Variable { variable: string label?: string | { nodeType: BlockEnum @@ -112,14 +112,14 @@ export type Variable = { isParagraph?: boolean } -export type EnvironmentVariable = { +export interface EnvironmentVariable { id: string name: string value: any value_type: 'string' | 'number' | 'secret' } -export type ConversationVariable = { +export interface ConversationVariable { id: string name: string value_type: ChatVarType @@ -127,13 +127,13 @@ export type ConversationVariable = { description: string } -export type GlobalVariable = { +export interface GlobalVariable { name: string value_type: 'string' | 'number' description: string } -export type VariableWithValue = { +export interface VariableWithValue { key: string value: string } @@ -169,8 +169,7 @@ export type InputVar = { value_selector?: ValueSelector } & Partial<UploadFileSetting> -export type ModelConfig = { - plugin_id: string +export interface ModelConfig { provider: string name: string mode: string @@ -188,7 +187,7 @@ export enum EditionType { jinja2 = 'jinja2', } -export type PromptItem = { +export interface PromptItem { id?: string role?: PromptRole text: string @@ -201,12 +200,12 @@ export enum MemoryRole { assistant = 'assistant', } -export type RolePrefix = { +export interface RolePrefix { user: string assistant: string } -export type Memory = { +export interface Memory { role_prefix?: RolePrefix window: { enabled: boolean @@ -230,7 +229,7 @@ export enum VarType { any = 'any', } -export type Var = { +export interface Var { variable: string type: VarType children?: Var[] // if type is obj, has the children struct @@ -241,21 +240,21 @@ export type Var = { des?: string } -export type NodeOutPutVar = { +export interface NodeOutPutVar { nodeId: string title: string vars: Var[] isStartNode?: boolean } -export type Block = { +export interface Block { classification?: string type: BlockEnum title: string description?: string } -export type NodeDefault<T> = { +export interface NodeDefault<T> { defaultValue: Partial<T> getAvailablePrevNodes: (isChatMode: boolean) => BlockEnum[] getAvailableNextNodes: (isChatMode: boolean) => BlockEnum[] @@ -295,19 +294,19 @@ export type OnNodeAdd = ( } ) => void -export type CheckValidRes = { +export interface CheckValidRes { isValid: boolean errorMessage?: string } -export type RunFile = { +export interface RunFile { type: string transfer_method: TransferMethod[] url?: string upload_file_id?: string } -export type WorkflowRunningData = { +export interface WorkflowRunningData { task_id?: string message_id?: string conversation_id?: string @@ -332,7 +331,7 @@ export type WorkflowRunningData = { tracing?: NodeTracing[] } -export type HistoryWorkflowData = { +export interface HistoryWorkflowData { id: string sequence_number: number status: string @@ -344,7 +343,7 @@ export enum ChangeType { remove = 'remove', } -export type MoreInfo = { +export interface MoreInfo { type: ChangeType payload?: { beforeKey: string @@ -364,7 +363,7 @@ export enum SupportUploadFileTypes { custom = 'custom', } -export type UploadFileSetting = { +export interface UploadFileSetting { allowed_file_upload_methods: TransferMethod[] allowed_file_types: SupportUploadFileTypes[] allowed_file_extensions?: string[] @@ -372,7 +371,7 @@ export type UploadFileSetting = { number_limits?: number } -export type VisionSetting = { +export interface VisionSetting { variable_selector: ValueSelector detail: Resolution } diff --git a/web/models/debug.ts b/web/models/debug.ts index 64a6cb7f84..301248b234 100644 --- a/web/models/debug.ts +++ b/web/models/debug.ts @@ -10,25 +10,25 @@ export enum PromptMode { advanced = 'advanced', } -export type PromptItem = { +export interface PromptItem { role?: PromptRole text: string } -export type ChatPromptConfig = { +export interface ChatPromptConfig { prompt: PromptItem[] } -export type ConversationHistoriesRole = { +export interface ConversationHistoriesRole { user_prefix: string assistant_prefix: string } -export type CompletionPromptConfig = { +export interface CompletionPromptConfig { prompt: PromptItem conversation_histories_role: ConversationHistoriesRole } -export type BlockStatus = { +export interface BlockStatus { context: boolean history: boolean query: boolean @@ -40,7 +40,7 @@ export enum PromptRole { assistant = 'assistant', } -export type PromptVariable = { +export interface PromptVariable { key: string name: string type: string // "string" | "number" | "select", @@ -55,7 +55,7 @@ export type PromptVariable = { icon_background?: string } -export type CompletionParams = { +export interface CompletionParams { max_tokens: number temperature: number top_p: number @@ -66,12 +66,12 @@ export type CompletionParams = { export type ModelId = 'gpt-3.5-turbo' | 'text-davinci-003' -export type PromptConfig = { +export interface PromptConfig { prompt_template: string prompt_variables: PromptVariable[] } -export type MoreLikeThisConfig = { +export interface MoreLikeThisConfig { enabled: boolean } @@ -79,7 +79,7 @@ export type SuggestedQuestionsAfterAnswerConfig = MoreLikeThisConfig export type SpeechToTextConfig = MoreLikeThisConfig -export type TextToSpeechConfig = { +export interface TextToSpeechConfig { enabled: boolean voice?: string language?: string @@ -88,7 +88,7 @@ export type TextToSpeechConfig = { export type CitationConfig = MoreLikeThisConfig -export type AnnotationReplyConfig = { +export interface AnnotationReplyConfig { id: string enabled: boolean score_threshold: number @@ -98,7 +98,7 @@ export type AnnotationReplyConfig = { } } -export type ModerationContentConfig = { +export interface ModerationContentConfig { enabled: boolean preset_response?: string } @@ -113,15 +113,14 @@ export type ModerationConfig = MoreLikeThisConfig & { } export type RetrieverResourceConfig = MoreLikeThisConfig -export type AgentConfig = { +export interface AgentConfig { enabled: boolean strategy: AgentStrategy max_iteration: number tools: ToolItem[] } // frontend use. Not the same as backend -export type ModelConfig = { - plugin_id: string +export interface ModelConfig { provider: string // LLM Provider: for example "OPENAI" model_id: string mode: ModelModeType @@ -139,17 +138,16 @@ export type ModelConfig = { dataSets: any[] agentConfig: AgentConfig } -export type DatasetConfigItem = { +export interface DatasetConfigItem { enable: boolean value: number } -export type DatasetConfigs = { +export interface DatasetConfigs { retrieval_model: RETRIEVE_TYPE reranking_model: { reranking_provider_name: string reranking_model_name: string - reranking_plugin_id: string } top_k: number score_threshold_enabled: boolean @@ -174,39 +172,39 @@ export type DatasetConfigs = { reranking_enable?: boolean } -export type DebugRequestBody = { +export interface DebugRequestBody { inputs: Inputs query: string completion_params: CompletionParams model_config: ModelConfig } -export type DebugResponse = { +export interface DebugResponse { id: string answer: string created_at: string } -export type DebugResponseStream = { +export interface DebugResponseStream { id: string data: string created_at: string } -export type FeedBackRequestBody = { +export interface FeedBackRequestBody { message_id: string rating: 'like' | 'dislike' content?: string from_source: 'api' | 'log' } -export type FeedBackResponse = { +export interface FeedBackResponse { message_id: string rating: 'like' | 'dislike' } // Log session list -export type LogSessionListQuery = { +export interface LogSessionListQuery { keyword?: string start?: string // format datetime(YYYY-mm-dd HH:ii) end?: string // format datetime(YYYY-mm-dd HH:ii) @@ -214,7 +212,7 @@ export type LogSessionListQuery = { limit: number // default 20. 1-100 } -export type LogSessionListResponse = { +export interface LogSessionListResponse { data: { id: string conversation_id: string @@ -228,7 +226,7 @@ export type LogSessionListResponse = { } // log session detail and debug -export type LogSessionDetailResponse = { +export interface LogSessionDetailResponse { id: string conversation_id: string model_provider: string @@ -242,7 +240,7 @@ export type LogSessionDetailResponse = { from_source: 'api' | 'log' } -export type SavedMessage = { +export interface SavedMessage { id: string answer: string } diff --git a/web/service/debug.ts b/web/service/debug.ts index 887fde02c6..093cddfd62 100644 --- a/web/service/debug.ts +++ b/web/service/debug.ts @@ -3,13 +3,13 @@ import type { IOnCompleted, IOnData, IOnError, IOnFile, IOnMessageEnd, IOnMessag import type { ChatPromptConfig, CompletionPromptConfig } from '@/models/debug' import type { ModelModeType } from '@/types/app' import type { ModelParameterRule } from '@/app/components/header/account-setting/model-provider-page/declarations' -export type AutomaticRes = { +export interface AutomaticRes { prompt: string variables: string[] opening_statement: string error?: string } -export type CodeGenRes = { +export interface CodeGenRes { code: string language: string[] error?: string @@ -82,8 +82,8 @@ export const generateRuleCode = (body: Record<string, any>) => { }) } -export const fetchModelParams = (pluginID: string, providerName: string, modelId: string) => { - return get(`workspaces/current/model-providers/${pluginID}/${providerName}/models/parameter-rules`, { +export const fetchModelParams = (providerName: string, modelId: string) => { + return get(`workspaces/current/model-providers/${providerName}/models/parameter-rules`, { params: { model: modelId, }, From 1d871dae0d9dba0bef9a36b327438a36edb7da1d Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 1 Nov 2024 11:59:43 +0800 Subject: [PATCH 10/18] Revert "credentials of models" This reverts commit 2ed73b763d34d4ea2f7911cf0c11b77bcbeccde1. --- .../model-provider-page/model-modal/index.tsx | 2 -- .../model-provider-page/utils.ts | 19 +++++++++---------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx index a1a56b19d1..0bb6942428 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx @@ -229,7 +229,6 @@ const ModelModal: FC<ModelModalProps> = ({ setLoading(true) const res = await saveCredentials( providerFormSchemaPredefined, - provider.plugin_id, provider.provider, encodeSecretValues(value), { @@ -256,7 +255,6 @@ const ModelModal: FC<ModelModalProps> = ({ const res = await removeCredentials( providerFormSchemaPredefined, - provider.plugin_id, provider.provider, value, ) diff --git a/web/app/components/header/account-setting/model-provider-page/utils.ts b/web/app/components/header/account-setting/model-provider-page/utils.ts index d3af826f61..cdc517581c 100644 --- a/web/app/components/header/account-setting/model-provider-page/utils.ts +++ b/web/app/components/header/account-setting/model-provider-page/utils.ts @@ -26,15 +26,14 @@ export const isNullOrUndefined = (value: any) => { return value === undefined || value === null } -// deprecated ??? -export const validateCredentials = async (predefined: boolean, pluginID: string, provider: string, v: FormValue) => { +export const validateCredentials = async (predefined: boolean, provider: string, v: FormValue) => { let body, url if (predefined) { body = { credentials: v, } - url = `/workspaces/current/model-providers/${pluginID}/${provider}/credentials/validate` + url = `/workspaces/current/model-providers/${provider}/credentials/validate` } else { const { __model_name, __model_type, ...credentials } = v @@ -43,7 +42,7 @@ export const validateCredentials = async (predefined: boolean, pluginID: string, model_type: __model_type, credentials, } - url = `/workspaces/current/model-providers/${pluginID}/${provider}/models/credentials/validate` + url = `/workspaces/current/model-providers/${provider}/models/credentials/validate` } try { const res = await validateModelProvider({ url, body }) @@ -81,7 +80,7 @@ export const validateLoadBalancingCredentials = async (predefined: boolean, plug } } -export const saveCredentials = async (predefined: boolean, pluginID: string, provider: string, v: FormValue, loadBalancing?: ModelLoadBalancingConfig) => { +export const saveCredentials = async (predefined: boolean, provider: string, v: FormValue, loadBalancing?: ModelLoadBalancingConfig) => { let body, url if (predefined) { @@ -90,7 +89,7 @@ export const saveCredentials = async (predefined: boolean, pluginID: string, pro credentials: v, load_balancing: loadBalancing, } - url = `/workspaces/current/model-providers/${pluginID}/${provider}` + url = `/workspaces/current/model-providers/${provider}` } else { const { __model_name, __model_type, ...credentials } = v @@ -100,7 +99,7 @@ export const saveCredentials = async (predefined: boolean, pluginID: string, pro credentials, load_balancing: loadBalancing, } - url = `/workspaces/current/model-providers/${pluginID}/${provider}/models` + url = `/workspaces/current/model-providers/${provider}/models` } return setModelProvider({ url, body }) @@ -120,12 +119,12 @@ export const savePredefinedLoadBalancingConfig = async (provider: string, v: For return setModelProvider({ url, body }) } -export const removeCredentials = async (predefined: boolean, pluginID: string, provider: string, v: FormValue) => { +export const removeCredentials = async (predefined: boolean, provider: string, v: FormValue) => { let url = '' let body if (predefined) { - url = `/workspaces/current/model-providers/${pluginID}/${provider}` + url = `/workspaces/current/model-providers/${provider}` } else { if (v) { @@ -134,7 +133,7 @@ export const removeCredentials = async (predefined: boolean, pluginID: string, p model: __model_name, model_type: __model_type, } - url = `/workspaces/current/model-providers/${pluginID}/${provider}/models` + url = `/workspaces/current/model-providers/${provider}/models` } } From c82b6413573479ff6a165a5ff71d986e5fab4e2e Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 1 Nov 2024 11:59:45 +0800 Subject: [PATCH 11/18] Revert "get credentials of provider" This reverts commit 72ef04d3e43e8acebf127daf06a837bc3500412b. --- .../header/account-setting/model-provider-page/hooks.ts | 7 +++---- .../model-provider-page/model-modal/index.tsx | 2 +- .../provider-added-card/model-load-balancing-modal.tsx | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/hooks.ts b/web/app/components/header/account-setting/model-provider-page/hooks.ts index 36aba3bc39..95bbd24f4a 100644 --- a/web/app/components/header/account-setting/model-provider-page/hooks.ts +++ b/web/app/components/header/account-setting/model-provider-page/hooks.ts @@ -11,7 +11,6 @@ import type { DefaultModel, DefaultModelResponse, Model, - ModelProvider, ModelTypeEnum, } from './declarations' import { @@ -64,20 +63,20 @@ export const useLanguage = () => { } export const useProviderCredentialsAndLoadBalancing = ( - provider: ModelProvider, + provider: string, configurationMethod: ConfigurationMethodEnum, configured?: boolean, currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields, ) => { const { data: predefinedFormSchemasValue, mutate: mutatePredefined } = useSWR( (configurationMethod === ConfigurationMethodEnum.predefinedModel && configured) - ? `/workspaces/current/model-providers/${provider.plugin_id}/${provider.provider}/credentials` + ? `/workspaces/current/model-providers/${provider}/credentials` : null, fetchModelProviderCredentials, ) const { data: customFormSchemasValue, mutate: mutateCustomized } = useSWR( (configurationMethod === ConfigurationMethodEnum.customizableModel && currentCustomConfigurationModelFixedFields) - ? `/workspaces/current/model-providers/${provider.plugin_id}/${provider.provider}/models/credentials?model=${currentCustomConfigurationModelFixedFields?.__model_name}&model_type=${currentCustomConfigurationModelFixedFields?.__model_type}` + ? `/workspaces/current/model-providers/${provider}/models/credentials?model=${currentCustomConfigurationModelFixedFields?.__model_name}&model_type=${currentCustomConfigurationModelFixedFields?.__model_type}` : null, fetchModelProviderCredentials, ) diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx index 0bb6942428..967bcccdca 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/index.tsx @@ -72,7 +72,7 @@ const ModelModal: FC<ModelModalProps> = ({ loadBalancing: originalConfig, mutate, } = useProviderCredentialsAndLoadBalancing( - provider, + provider.provider, configurateMethod, providerFormSchemaPredefined && provider.custom_configuration.status === CustomConfigurationStatusEnum.active, currentCustomConfigurationModelFixedFields, diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx index a58d6e13e7..84af503af4 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx @@ -30,7 +30,7 @@ const ModelLoadBalancingModal = ({ provider, model, open = false, onClose, onSav const [loading, setLoading] = useState(false) const { data, mutate } = useSWR( - `/workspaces/current/model-providers/${provider.plugin_id}/${provider.provider}/models/credentials?model=${model.model}&model_type=${model.model_type}`, + `/workspaces/current/model-providers/${provider.provider}/models/credentials?model=${model.model}&model_type=${model.model_type}`, fetchModelLoadBalancingConfig, ) From 22766c27c78249a4c5bd1ce25d5d1468929d7cd7 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 1 Nov 2024 11:59:48 +0800 Subject: [PATCH 12/18] Revert "model list of provider" This reverts commit 766ac3e255147cea3219df1f1c718ecbdeb529ce. --- .../account-setting/model-provider-page/index.tsx | 2 +- .../provider-added-card/credential-panel.tsx | 2 +- .../provider-added-card/index.tsx | 12 ++++++------ .../provider-added-card/model-list.tsx | 2 +- .../model-load-balancing-modal.tsx | 4 ++-- web/context/modal-context.tsx | 8 ++++---- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/index.tsx b/web/app/components/header/account-setting/model-provider-page/index.tsx index 3a45424a8a..6d508f0de1 100644 --- a/web/app/components/header/account-setting/model-provider-page/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/index.tsx @@ -110,7 +110,7 @@ const ModelProviderPage = ({ searchText }: Props) => { if (configurationMethod === ConfigurationMethodEnum.customizableModel && provider.custom_configuration.status === CustomConfigurationStatusEnum.active) { eventEmitter?.emit({ type: UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST, - payload: provider, + payload: provider.provider, } as any) if (CustomConfigurationModelFixedFields?.__model_type) diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx index ac82dce3bf..e7f865f198 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx @@ -57,7 +57,7 @@ const CredentialPanel: FC<CredentialPanelProps> = ({ eventEmitter?.emit({ type: UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST, - payload: provider, + payload: provider.provider, } as any) } } diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx index 7b7702d6b8..46ef6add24 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx @@ -52,12 +52,12 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({ const showQuota = systemConfig.enabled && [...MODEL_PROVIDER_QUOTA_GET_PAID].includes(provider.provider) && !IS_CE_EDITION const showCredential = configurationMethods.includes(ConfigurationMethodEnum.predefinedModel) && isCurrentWorkspaceManager - const getModelList = async (pluginID: string, providerName: string) => { + const getModelList = async (providerName: string) => { if (loading) return try { setLoading(true) - const modelsData = await fetchModelProviderModelList(`/workspaces/current/model-providers/${pluginID}/${providerName}/models`) + const modelsData = await fetchModelProviderModelList(`/workspaces/current/model-providers/${providerName}/models`) setModelList(modelsData.data) setCollapsed(false) setFetched(true) @@ -72,12 +72,12 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({ return } - getModelList(provider.plugin_id, provider.provider) + getModelList(provider.provider) } eventEmitter?.useSubscription((v: any) => { - if (v?.type === UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST && v.payload.provider === provider.provider) - getModelList(v.payload.plugin_id, v.payload.provider) + if (v?.type === UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST && v.payload === provider.provider) + getModelList(v.payload) }) return ( @@ -172,7 +172,7 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({ models={modelList} onCollapse={() => setCollapsed(true)} onConfig={currentCustomConfigurationModelFixedFields => onOpenModal(ConfigurationMethodEnum.customizableModel, currentCustomConfigurationModelFixedFields)} - onChange={(provider: ModelProvider) => getModelList(provider.plugin_id, provider.provider)} + onChange={(provider: string) => getModelList(provider)} /> ) } diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx index 3b6a4ccbe5..5e70a0def1 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx @@ -23,7 +23,7 @@ type ModelListProps = { models: ModelItem[] onCollapse: () => void onConfig: (currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields) => void - onChange?: (provider: ModelProvider) => void + onChange?: (provider: string) => void } const ModelList: FC<ModelListProps> = ({ provider, diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx index 84af503af4..edbb4665e9 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-load-balancing-modal.tsx @@ -19,7 +19,7 @@ export type ModelLoadBalancingModalProps = { model: ModelItem open?: boolean onClose?: () => void - onSave?: (provider: ModelProvider) => void + onSave?: (provider: string) => void } // model balancing config modal @@ -94,7 +94,7 @@ const ModelLoadBalancingModal = ({ provider, model, open = false, onClose, onSav if (res.result === 'success') { notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') }) mutate() - onSave?.(provider) + onSave?.(provider.provider) onClose?.() } } diff --git a/web/context/modal-context.tsx b/web/context/modal-context.tsx index c8383ae336..60d53f1e98 100644 --- a/web/context/modal-context.tsx +++ b/web/context/modal-context.tsx @@ -32,7 +32,7 @@ import OpeningSettingModal from '@/app/components/base/features/new-feature-pane import type { OpeningStatement } from '@/app/components/base/features/types' import type { InputVar } from '@/app/components/workflow/types' -export type ModalState<T> = { +export interface ModalState<T> { payload: T onCancelCallback?: () => void onSaveCallback?: (newPayload: T) => void @@ -43,7 +43,7 @@ export type ModalState<T> = { datasetBindings?: { id: string; name: string }[] } -export type ModelModalType = { +export interface ModelModalType { currentProvider: ModelProvider currentConfigurationMethod: ConfigurationMethodEnum currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields @@ -52,7 +52,7 @@ export type LoadBalancingEntryModalType = ModelModalType & { entry?: ModelLoadBalancingConfigEntry index?: number } -export type ModalContextState = { +export interface ModalContextState { setShowAccountSettingModal: Dispatch<SetStateAction<ModalState<string> | null>> setShowApiBasedExtensionModal: Dispatch<SetStateAction<ModalState<ApiBasedExtension> | null>> setShowModerationSettingModal: Dispatch<SetStateAction<ModalState<ModerationConfig> | null>> @@ -90,7 +90,7 @@ export const useModalContext = () => useContext(ModalContext) export const useModalContextSelector = <T,>(selector: (state: ModalContextState) => T): T => useContextSelector(ModalContext, selector) -type ModalContextProviderProps = { +interface ModalContextProviderProps { children: React.ReactNode } export const ModalContextProvider = ({ From e7dcc53b5557bf4acb87ca141b3993116f110b9f Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 1 Nov 2024 11:59:51 +0800 Subject: [PATCH 13/18] Revert "load balance" This reverts commit 378a9dd850f9e2103ce066339ed69d5decb9a887. --- .../model-modal/model-load-balancing-entry-modal.tsx | 1 - .../provider-added-card/model-list-item.tsx | 6 +++--- .../header/account-setting/model-provider-page/utils.ts | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/model-modal/model-load-balancing-entry-modal.tsx b/web/app/components/header/account-setting/model-provider-page/model-modal/model-load-balancing-entry-modal.tsx index bd453ce59b..1c318b9baf 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-modal/model-load-balancing-entry-modal.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-modal/model-load-balancing-entry-modal.tsx @@ -209,7 +209,6 @@ const ModelLoadBalancingEntryModal: FC<ModelModalProps> = ({ const res = await validateLoadBalancingCredentials( providerFormSchemaPredefined, - provider.plugin_id, provider.provider, { ...value, diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list-item.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list-item.tsx index a299d6a134..3fc73a62b2 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list-item.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list-item.tsx @@ -33,10 +33,10 @@ const ModelListItem = ({ model, provider, isConfigurable, onConfig, onModifyLoad const toggleModelEnablingStatus = useCallback(async (enabled: boolean) => { if (enabled) - await enableModel(`/workspaces/current/model-providers/${provider.plugin_id}/${provider.provider}/models/enable`, { model: model.model, model_type: model.model_type }) + await enableModel(`/workspaces/current/model-providers/${provider.provider}/models/enable`, { model: model.model, model_type: model.model_type }) else - await disableModel(`/workspaces/current/model-providers/${provider.plugin_id}/${provider.provider}/models/disable`, { model: model.model, model_type: model.model_type }) - }, [model.model, model.model_type, provider.plugin_id, provider.provider]) + await disableModel(`/workspaces/current/model-providers/${provider.provider}/models/disable`, { model: model.model, model_type: model.model_type }) + }, [model.model, model.model_type, provider.provider]) const { run: debouncedToggleModelEnablingStatus } = useDebounceFn(toggleModelEnablingStatus, { wait: 500 }) diff --git a/web/app/components/header/account-setting/model-provider-page/utils.ts b/web/app/components/header/account-setting/model-provider-page/utils.ts index cdc517581c..165926b2bb 100644 --- a/web/app/components/header/account-setting/model-provider-page/utils.ts +++ b/web/app/components/header/account-setting/model-provider-page/utils.ts @@ -56,14 +56,14 @@ export const validateCredentials = async (predefined: boolean, provider: string, } } -export const validateLoadBalancingCredentials = async (predefined: boolean, pluginID: string, provider: string, v: FormValue, id?: string): Promise<{ +export const validateLoadBalancingCredentials = async (predefined: boolean, provider: string, v: FormValue, id?: string): Promise<{ status: ValidatedStatus message?: string }> => { const { __model_name, __model_type, ...credentials } = v try { const res = await validateModelLoadBalancingCredentials({ - url: `/workspaces/current/model-providers/${pluginID}/${provider}/models/load-balancing-configs/${id ? `${id}/` : ''}credentials-validate`, + url: `/workspaces/current/model-providers/${provider}/models/load-balancing-configs/${id ? `${id}/` : ''}credentials-validate`, body: { model: __model_name, model_type: __model_type, From 7752f374e5b3e5ac3641a859fe38749297c618e9 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 1 Nov 2024 11:59:53 +0800 Subject: [PATCH 14/18] Revert "update model provider api responses" This reverts commit c8dc5e484937136b4466bf3a37d6de58606a0234. --- .../model-provider-page/declarations.ts | 32 ++++++++----------- .../model-provider-page/hooks.ts | 9 ++---- .../system-model-selector/index.tsx | 1 - web/service/common.ts | 8 ++--- 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/declarations.ts b/web/app/components/header/account-setting/model-provider-page/declarations.ts index 930ae4b852..c50a17c6b2 100644 --- a/web/app/components/header/account-setting/model-provider-page/declarations.ts +++ b/web/app/components/header/account-setting/model-provider-page/declarations.ts @@ -1,6 +1,6 @@ export type FormValue = Record<string, any> -export type TypeWithI18N<T = string> = { +export interface TypeWithI18N<T = string> { en_US: T zh_Hans: T [key: string]: T @@ -17,7 +17,7 @@ export enum FormTypeEnum { file = 'file', } -export type FormOption = { +export interface FormOption { label: TypeWithI18N value: string show_on: FormShowOnObject[] @@ -89,12 +89,12 @@ export enum CustomConfigurationStatusEnum { noConfigure = 'no-configure', } -export type FormShowOnObject = { +export interface FormShowOnObject { variable: string value: string } -export type CredentialFormSchemaBase = { +export interface CredentialFormSchemaBase { variable: string label: TypeWithI18N type: FormTypeEnum @@ -112,7 +112,7 @@ export type CredentialFormSchemaRadio = CredentialFormSchemaBase & { options: Fo export type CredentialFormSchemaSecretInput = CredentialFormSchemaBase & { placeholder?: TypeWithI18N } export type CredentialFormSchema = CredentialFormSchemaTextInput | CredentialFormSchemaSelect | CredentialFormSchemaRadio | CredentialFormSchemaSecretInput -export type ModelItem = { +export interface ModelItem { model: string label: TypeWithI18N model_type: ModelTypeEnum @@ -141,7 +141,7 @@ export enum QuotaUnitEnum { credits = 'credits', } -export type QuotaConfiguration = { +export interface QuotaConfiguration { quota_type: CurrentSystemQuotaTypeEnum quota_unit: QuotaUnitEnum quota_limit: number @@ -150,8 +150,7 @@ export type QuotaConfiguration = { is_valid: boolean } -export type ModelProvider = { - plugin_id: string +export interface ModelProvider { provider: string label: TypeWithI18N description?: TypeWithI18N @@ -185,8 +184,7 @@ export type ModelProvider = { } } -export type Model = { - plugin_id: string +export interface Model { provider: string icon_large: TypeWithI18N icon_small: TypeWithI18N @@ -195,29 +193,27 @@ export type Model = { status: ModelStatusEnum } -export type DefaultModelResponse = { +export interface DefaultModelResponse { model: string model_type: ModelTypeEnum provider: { - plugin_id: string provider: string icon_large: TypeWithI18N icon_small: TypeWithI18N } } -export type DefaultModel = { - plugin_id: string +export interface DefaultModel { provider: string model: string } -export type CustomConfigurationModelFixedFields = { +export interface CustomConfigurationModelFixedFields { __model_name: string __model_type: ModelTypeEnum } -export type ModelParameterRule = { +export interface ModelParameterRule { default?: number | string | boolean | string[] help?: TypeWithI18N label: TypeWithI18N @@ -232,7 +228,7 @@ export type ModelParameterRule = { tagPlaceholder?: TypeWithI18N } -export type ModelLoadBalancingConfigEntry = { +export interface ModelLoadBalancingConfigEntry { /** model balancing config entry id */ id?: string /** is config entry enabled */ @@ -247,7 +243,7 @@ export type ModelLoadBalancingConfigEntry = { ttl?: number } -export type ModelLoadBalancingConfig = { +export interface ModelLoadBalancingConfig { enabled: boolean configs: ModelLoadBalancingConfigEntry[] } diff --git a/web/app/components/header/account-setting/model-provider-page/hooks.ts b/web/app/components/header/account-setting/model-provider-page/hooks.ts index 95bbd24f4a..54396cc538 100644 --- a/web/app/components/header/account-setting/model-provider-page/hooks.ts +++ b/web/app/components/header/account-setting/model-provider-page/hooks.ts @@ -36,12 +36,11 @@ export const useSystemDefaultModelAndModelList: UseDefaultModelAndModelList = ( modelList, ) => { const currentDefaultModel = useMemo(() => { - const currentProvider = modelList.find(provider => provider.provider === defaultModel?.provider.provider && provider.plugin_id === defaultModel?.provider.plugin_id) + const currentProvider = modelList.find(provider => provider.provider === defaultModel?.provider.provider) const currentModel = currentProvider?.models.find(model => model.model === defaultModel?.model) const currentDefaultModel = currentProvider && currentModel && { model: currentModel.model, provider: currentProvider.provider, - plugin_id: currentProvider.plugin_id, } return currentDefaultModel @@ -173,11 +172,7 @@ export const useModelListAndDefaultModelAndCurrentProviderAndModel = (type: Mode const { modelList, defaultModel } = useModelListAndDefaultModel(type) const { currentProvider, currentModel } = useCurrentProviderAndModel( modelList, - { - plugin_id: defaultModel?.provider.plugin_id || '', - provider: defaultModel?.provider.provider || '', - model: defaultModel?.model || '', - }, + { provider: defaultModel?.provider.provider || '', model: defaultModel?.model || '' }, ) return { diff --git a/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx b/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx index 578fcbe716..2e1e6400d1 100644 --- a/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx @@ -94,7 +94,6 @@ const SystemModel: FC<SystemModelSelectorProps> = ({ model_settings: [ModelTypeEnum.textGeneration, ModelTypeEnum.textEmbedding, ModelTypeEnum.rerank, ModelTypeEnum.speech2text, ModelTypeEnum.tts].map((modelType) => { return { model_type: modelType, - plugin_id: getCurrentDefaultModelByModelType(modelType)?.plugin_id, provider: getCurrentDefaultModelByModelType(modelType)?.provider, model: getCurrentDefaultModelByModelType(modelType)?.model, } diff --git a/web/service/common.ts b/web/service/common.ts index 1fc9b60f45..d3c07f3c1d 100644 --- a/web/service/common.ts +++ b/web/service/common.ts @@ -38,11 +38,11 @@ import type { import type { RETRIEVE_METHOD } from '@/types/app' import type { SystemFeatures } from '@/types/feature' -type LoginSuccess = { +interface LoginSuccess { result: 'success' data: { access_token: string;refresh_token: string } } -type LoginFail = { +interface LoginFail { result: 'fail' data: string code: string @@ -183,7 +183,7 @@ export const fetchModelProviders: Fetcher<{ data: ModelProvider[] }, string> = ( return get<{ data: ModelProvider[] }>(url) } -export type ModelProviderCredentials = { +export interface ModelProviderCredentials { credentials?: Record<string, string | undefined | boolean> load_balancing: ModelLoadBalancingConfig } @@ -297,7 +297,7 @@ export const moderate = (url: string, body: { app_id: string; text: string }) => return post(url, { body }) as Promise<ModerateResponse> } -type RetrievalMethodsRes = { +interface RetrievalMethodsRes { retrieval_method: RETRIEVE_METHOD[] } export const fetchSupportRetrievalMethods: Fetcher<RetrievalMethodsRes, string> = (url) => { From 1a92064260312655458120d69def72debe4b5118 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 1 Nov 2024 12:09:17 +0800 Subject: [PATCH 15/18] remove unused components --- .../toolbox/annotation/config-param.tsx | 124 ------- .../app/configuration/toolbox/index.tsx | 45 --- .../feature-panel/opening-statement/index.tsx | 327 ------------------ web/hooks/use-pay.tsx | 68 +--- web/service/common.ts | 12 +- 5 files changed, 6 insertions(+), 570 deletions(-) delete mode 100644 web/app/components/app/configuration/toolbox/annotation/config-param.tsx delete mode 100644 web/app/components/app/configuration/toolbox/index.tsx delete mode 100644 web/app/components/base/features/feature-panel/opening-statement/index.tsx diff --git a/web/app/components/app/configuration/toolbox/annotation/config-param.tsx b/web/app/components/app/configuration/toolbox/annotation/config-param.tsx deleted file mode 100644 index e418a76c34..0000000000 --- a/web/app/components/app/configuration/toolbox/annotation/config-param.tsx +++ /dev/null @@ -1,124 +0,0 @@ -'use client' -import type { FC } from 'react' -import React from 'react' -import { useTranslation } from 'react-i18next' -import { useContext } from 'use-context-selector' -import { usePathname, useRouter } from 'next/navigation' -import ConfigParamModal from './config-param-modal' -import Panel from '@/app/components/app/configuration/base/feature-panel' -import { MessageFast } from '@/app/components/base/icons/src/vender/solid/communication' -import Tooltip from '@/app/components/base/tooltip' -import { LinkExternal02, Settings04 } from '@/app/components/base/icons/src/vender/line/general' -import ConfigContext from '@/context/debug-configuration' -import type { EmbeddingModelConfig } from '@/app/components/app/annotation/type' -import { fetchAnnotationConfig, updateAnnotationScore } from '@/service/annotation' -import type { AnnotationReplyConfig as AnnotationReplyConfigType } from '@/models/debug' - -type Props = { - onEmbeddingChange: (embeddingModel: EmbeddingModelConfig) => void - onScoreChange: (score: number, embeddingModel?: EmbeddingModelConfig) => void -} - -export const Item: FC<{ title: string; tooltip: string; children: JSX.Element }> = ({ - title, - tooltip, - children, -}) => { - return ( - <div> - <div className='flex items-center space-x-1'> - <div>{title}</div> - <Tooltip - popupContent={ - <div className='max-w-[200px] leading-[18px] text-[13px] font-medium text-gray-800'>{tooltip}</div> - } - /> - </div> - <div>{children}</div> - </div> - ) -} - -const AnnotationReplyConfig: FC<Props> = ({ - onEmbeddingChange, - onScoreChange, -}) => { - const { t } = useTranslation() - const router = useRouter() - const pathname = usePathname() - const matched = pathname.match(/\/app\/([^/]+)/) - const appId = (matched?.length && matched[1]) ? matched[1] : '' - const { - annotationConfig, - } = useContext(ConfigContext) - - const [isShowEdit, setIsShowEdit] = React.useState(false) - - return ( - <> - <Panel - className="mt-4" - headerIcon={ - <MessageFast className='w-4 h-4 text-[#444CE7]' /> - } - title={t('appDebug.feature.annotation.title')} - headerRight={ - <div className='flex items-center'> - <div - className='flex items-center rounded-md h-7 px-3 space-x-1 text-gray-700 cursor-pointer hover:bg-gray-200' - onClick={() => { setIsShowEdit(true) }} - > - <Settings04 className="w-[14px] h-[14px]" /> - <div className='text-xs font-medium'> - - {t('common.operation.params')} - </div> - </div> - <div - className='ml-1 flex items-center h-7 px-3 space-x-1 leading-[18px] text-xs font-medium text-gray-700 rounded-md cursor-pointer hover:bg-gray-200' - onClick={() => { - router.push(`/app/${appId}/annotations`) - }}> - <div>{t('appDebug.feature.annotation.cacheManagement')}</div> - <LinkExternal02 className='w-3.5 h-3.5' /> - </div> - </div> - } - noBodySpacing - /> - {isShowEdit && ( - <ConfigParamModal - appId={appId} - isShow - onHide={() => { - setIsShowEdit(false) - }} - onSave={async (embeddingModel, score) => { - const annotationConfig = await fetchAnnotationConfig(appId) as AnnotationReplyConfigType - let isEmbeddingModelChanged = false - if ( - embeddingModel.embedding_model_name !== annotationConfig.embedding_model.embedding_model_name - || embeddingModel.embedding_provider_name !== annotationConfig.embedding_model.embedding_provider_name - ) { - await onEmbeddingChange(embeddingModel) - isEmbeddingModelChanged = true - } - - if (score !== annotationConfig.score_threshold) { - await updateAnnotationScore(appId, annotationConfig.id, score) - if (isEmbeddingModelChanged) - onScoreChange(score, embeddingModel) - - else - onScoreChange(score) - } - - setIsShowEdit(false) - }} - annotationConfig={annotationConfig} - /> - )} - </> - ) -} -export default React.memo(AnnotationReplyConfig) diff --git a/web/app/components/app/configuration/toolbox/index.tsx b/web/app/components/app/configuration/toolbox/index.tsx deleted file mode 100644 index 00ea301a42..0000000000 --- a/web/app/components/app/configuration/toolbox/index.tsx +++ /dev/null @@ -1,45 +0,0 @@ -'use client' - -import type { FC } from 'react' -import React from 'react' -import { useTranslation } from 'react-i18next' -import GroupName from '../base/group-name' -import Moderation from './moderation' -import Annotation from './annotation/config-param' -import type { EmbeddingModelConfig } from '@/app/components/app/annotation/type' - -export type ToolboxProps = { - showModerationSettings: boolean - showAnnotation: boolean - onEmbeddingChange: (embeddingModel: EmbeddingModelConfig) => void - onScoreChange: (score: number, embeddingModel?: EmbeddingModelConfig) => void -} - -const Toolbox: FC<ToolboxProps> = ({ - showModerationSettings, - showAnnotation, - onEmbeddingChange, - onScoreChange, -}) => { - const { t } = useTranslation() - - return ( - <div className='mt-7'> - <GroupName name={t('appDebug.feature.toolbox.title')} /> - { - showModerationSettings && ( - <Moderation /> - ) - } - { - showAnnotation && ( - <Annotation - onEmbeddingChange={onEmbeddingChange} - onScoreChange={onScoreChange} - /> - ) - } - </div> - ) -} -export default React.memo(Toolbox) diff --git a/web/app/components/base/features/feature-panel/opening-statement/index.tsx b/web/app/components/base/features/feature-panel/opening-statement/index.tsx deleted file mode 100644 index 5d742f8bff..0000000000 --- a/web/app/components/base/features/feature-panel/opening-statement/index.tsx +++ /dev/null @@ -1,327 +0,0 @@ -'use client' -import type { FC } from 'react' -import React, { useEffect, useRef, useState } from 'react' -import produce from 'immer' -import { - RiAddLine, - RiDeleteBinLine, -} from '@remixicon/react' -import { useTranslation } from 'react-i18next' -import { useBoolean } from 'ahooks' -import { ReactSortable } from 'react-sortablejs' -import { - useFeatures, - useFeaturesStore, -} from '../../hooks' -import type { OnFeaturesChange } from '../../types' -import cn from '@/utils/classnames' -import Panel from '@/app/components/app/configuration/base/feature-panel' -import Button from '@/app/components/base/button' -import OperationBtn from '@/app/components/app/configuration/base/operation-btn' -import { getInputKeys } from '@/app/components/base/block-input' -import ConfirmAddVar from '@/app/components/app/configuration/config-prompt/confirm-add-var' -import { getNewVar } from '@/utils/var' -import { varHighlightHTML } from '@/app/components/app/configuration/base/var-highlight' -import type { PromptVariable } from '@/models/debug' -import type { InputVar } from '@/app/components/workflow/types' - -const MAX_QUESTION_NUM = 5 - -export type OpeningStatementProps = { - onChange?: OnFeaturesChange - readonly?: boolean - promptVariables?: PromptVariable[] - onAutoAddPromptVariable: (variable: PromptVariable[]) => void - workflowVariables?: InputVar[] -} - -// regex to match the {{}} and replace it with a span -const regex = /\{\{([^}]+)\}\}/g - -const OpeningStatement: FC<OpeningStatementProps> = ({ - onChange, - readonly, - promptVariables = [], - onAutoAddPromptVariable, - workflowVariables = [], -}) => { - const { t } = useTranslation() - const featureStore = useFeaturesStore() - const openingStatement = useFeatures(s => s.features.opening) - const value = openingStatement?.opening_statement || '' - const suggestedQuestions = openingStatement?.suggested_questions || [] - const [notIncludeKeys, setNotIncludeKeys] = useState<string[]>([]) - - const hasValue = !!(value || '').trim() - const inputRef = useRef<HTMLTextAreaElement>(null) - - const [isFocus, { setTrue: didSetFocus, setFalse: setBlur }] = useBoolean(false) - - const setFocus = () => { - didSetFocus() - setTimeout(() => { - const input = inputRef.current - if (input) { - input.focus() - input.setSelectionRange(input.value.length, input.value.length) - } - }, 0) - } - - const [tempValue, setTempValue] = useState(value) - useEffect(() => { - setTempValue(value || '') - }, [value]) - - const [tempSuggestedQuestions, setTempSuggestedQuestions] = useState(suggestedQuestions || []) - const notEmptyQuestions = tempSuggestedQuestions.filter(question => !!question && question.trim()) - const coloredContent = (tempValue || '') - .replace(/</g, '<') - .replace(/>/g, '>') - .replace(regex, varHighlightHTML({ name: '$1' })) // `<span class="${highLightClassName}">{{$1}}</span>` - .replace(/\n/g, '<br />') - - const handleEdit = () => { - if (readonly) - return - setFocus() - } - - const [isShowConfirmAddVar, { setTrue: showConfirmAddVar, setFalse: hideConfirmAddVar }] = useBoolean(false) - - const handleCancel = () => { - setBlur() - setTempValue(value) - setTempSuggestedQuestions(suggestedQuestions) - } - - const handleConfirm = () => { - const keys = getInputKeys(tempValue) - const promptKeys = promptVariables.map(item => item.key) - const workflowVariableKeys = workflowVariables.map(item => item.variable) - let notIncludeKeys: string[] = [] - - if (promptKeys.length === 0 && workflowVariables.length === 0) { - if (keys.length > 0) - notIncludeKeys = keys - } - else { - if (workflowVariables.length > 0) - notIncludeKeys = keys.filter(key => !workflowVariableKeys.includes(key)) - - else notIncludeKeys = keys.filter(key => !promptKeys.includes(key)) - } - - if (notIncludeKeys.length > 0) { - setNotIncludeKeys(notIncludeKeys) - showConfirmAddVar() - return - } - setBlur() - const { getState } = featureStore! - const { - features, - setFeatures, - } = getState() - - const newFeatures = produce(features, (draft) => { - if (draft.opening) { - draft.opening.opening_statement = tempValue - draft.opening.suggested_questions = tempSuggestedQuestions - } - }) - setFeatures(newFeatures) - - if (onChange) - onChange(newFeatures) - } - - const cancelAutoAddVar = () => { - const { getState } = featureStore! - const { - features, - setFeatures, - } = getState() - - const newFeatures = produce(features, (draft) => { - if (draft.opening) - draft.opening.opening_statement = tempValue - }) - setFeatures(newFeatures) - - if (onChange) - onChange(newFeatures) - hideConfirmAddVar() - setBlur() - } - - const autoAddVar = () => { - const { getState } = featureStore! - const { - features, - setFeatures, - } = getState() - - const newFeatures = produce(features, (draft) => { - if (draft.opening) - draft.opening.opening_statement = tempValue - }) - setFeatures(newFeatures) - if (onChange) - onChange(newFeatures) - onAutoAddPromptVariable([...notIncludeKeys.map(key => getNewVar(key, 'string'))]) - hideConfirmAddVar() - setBlur() - } - - const headerRight = !readonly ? ( - isFocus ? ( - <div className='flex items-center space-x-1'> - <Button - variant='ghost' - size='small' - onClick={handleCancel} - > - {t('common.operation.cancel')} - </Button> - <Button size='small' onClick={handleConfirm} variant="primary">{t('common.operation.save')}</Button> - </div> - ) : ( - <OperationBtn type='edit' actionName={hasValue ? '' : t('appDebug.openingStatement.writeOpener') as string} onClick={handleEdit} /> - ) - ) : null - - const renderQuestions = () => { - return isFocus ? ( - <div> - <div className='flex items-center py-2'> - <div className='shrink-0 flex space-x-0.5 leading-[18px] text-xs font-medium text-gray-500'> - <div className='uppercase'>{t('appDebug.openingStatement.openingQuestion')}</div> - <div>·</div> - <div>{tempSuggestedQuestions.length}/{MAX_QUESTION_NUM}</div> - </div> - <div className='ml-3 grow w-0 h-px bg-[#243, 244, 246]'></div> - </div> - <ReactSortable - className="space-y-1" - list={tempSuggestedQuestions.map((name, index) => { - return { - id: index, - name, - } - })} - setList={list => setTempSuggestedQuestions(list.map(item => item.name))} - handle='.handle' - ghostClass="opacity-50" - animation={150} - > - {tempSuggestedQuestions.map((question, index) => { - return ( - <div className='group relative rounded-lg border border-gray-200 flex items-center pl-2.5 hover:border-gray-300 hover:bg-white' key={index}> - <div className='handle flex items-center justify-center w-4 h-4 cursor-grab'> - <svg width="6" height="10" viewBox="0 0 6 10" fill="none" xmlns="http://www.w3.org/2000/svg"> - <path fillRule="evenodd" clipRule="evenodd" d="M1 2C1.55228 2 2 1.55228 2 1C2 0.447715 1.55228 0 1 0C0.447715 0 0 0.447715 0 1C0 1.55228 0.447715 2 1 2ZM1 6C1.55228 6 2 5.55228 2 5C2 4.44772 1.55228 4 1 4C0.447715 4 0 4.44772 0 5C0 5.55228 0.447715 6 1 6ZM6 1C6 1.55228 5.55228 2 5 2C4.44772 2 4 1.55228 4 1C4 0.447715 4.44772 0 5 0C5.55228 0 6 0.447715 6 1ZM5 6C5.55228 6 6 5.55228 6 5C6 4.44772 5.55228 4 5 4C4.44772 4 4 4.44772 4 5C4 5.55228 4.44772 6 5 6ZM2 9C2 9.55229 1.55228 10 1 10C0.447715 10 0 9.55229 0 9C0 8.44771 0.447715 8 1 8C1.55228 8 2 8.44771 2 9ZM5 10C5.55228 10 6 9.55229 6 9C6 8.44771 5.55228 8 5 8C4.44772 8 4 8.44771 4 9C4 9.55229 4.44772 10 5 10Z" fill="#98A2B3" /> - </svg> - </div> - <input - type="input" - value={question || ''} - onChange={(e) => { - const value = e.target.value - setTempSuggestedQuestions(tempSuggestedQuestions.map((item, i) => { - if (index === i) - return value - - return item - })) - }} - className={'w-full overflow-x-auto pl-1.5 pr-8 text-sm leading-9 text-gray-900 border-0 grow h-9 bg-transparent focus:outline-none cursor-pointer rounded-lg'} - /> - - <div - className='block absolute top-1/2 translate-y-[-50%] right-1.5 p-1 rounded-md cursor-pointer hover:bg-[#FEE4E2] hover:text-[#D92D20]' - onClick={() => { - setTempSuggestedQuestions(tempSuggestedQuestions.filter((_, i) => index !== i)) - }} - > - <RiDeleteBinLine className='w-3.5 h-3.5' /> - </div> - </div> - ) - })}</ReactSortable> - {tempSuggestedQuestions.length < MAX_QUESTION_NUM && ( - <div - onClick={() => { setTempSuggestedQuestions([...tempSuggestedQuestions, '']) }} - className='mt-1 flex items-center h-9 px-3 gap-2 rounded-lg cursor-pointer text-gray-400 bg-gray-100 hover:bg-gray-200'> - <RiAddLine className='w-4 h-4' /> - <div className='text-gray-500 text-[13px]'>{t('appDebug.variableConfig.addOption')}</div> - </div> - )} - </div> - ) : ( - <div className='mt-1.5 flex flex-wrap'> - {notEmptyQuestions.map((question, index) => { - return ( - <div key={index} className='mt-1 mr-1 max-w-full truncate last:mr-0 shrink-0 leading-8 items-center px-2.5 rounded-lg border border-gray-200 shadow-xs bg-white text-[13px] font-normal text-gray-900 cursor-pointer'> - {question} - </div> - ) - })} - </div> - ) - } - - return ( - <Panel - className={cn(isShowConfirmAddVar && 'h-[220px]', 'relative !bg-gray-25')} - title={t('appDebug.openingStatement.title')} - headerIcon={ - <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="M8.33353 1.33301C4.83572 1.33301 2.00019 4.16854 2.00019 7.66634C2.00019 8.37301 2.11619 9.05395 2.3307 9.69036C2.36843 9.80229 2.39063 9.86853 2.40507 9.91738L2.40979 9.93383L2.40729 9.93903C2.39015 9.97437 2.36469 10.0218 2.31705 10.11L1.2158 12.1484C1.14755 12.2746 1.07633 12.4064 1.02735 12.5209C0.978668 12.6348 0.899813 12.8437 0.938613 13.0914C0.984094 13.3817 1.15495 13.6373 1.40581 13.7903C1.61981 13.9208 1.843 13.9279 1.96683 13.9264C2.09141 13.925 2.24036 13.9095 2.38314 13.8947L5.81978 13.5395C5.87482 13.5338 5.9036 13.5309 5.92468 13.5292L5.92739 13.529L5.93564 13.532C5.96154 13.5413 5.99666 13.5548 6.0573 13.5781C6.76459 13.8506 7.53244 13.9997 8.33353 13.9997C11.8313 13.9997 14.6669 11.1641 14.6669 7.66634C14.6669 4.16854 11.8313 1.33301 8.33353 1.33301ZM5.9799 5.72116C6.73142 5.08698 7.73164 5.27327 8.33144 5.96584C8.93125 5.27327 9.91854 5.09365 10.683 5.72116C11.4474 6.34867 11.5403 7.41567 10.9501 8.16572C10.5845 8.6304 9.6668 9.47911 9.02142 10.0576C8.78435 10.2702 8.66582 10.3764 8.52357 10.4192C8.40154 10.456 8.26134 10.456 8.13931 10.4192C7.99706 10.3764 7.87853 10.2702 7.64147 10.0576C6.99609 9.47911 6.07839 8.6304 5.71276 8.16572C5.12259 7.41567 5.22839 6.35534 5.9799 5.72116Z" fill="#E74694" /> - </svg> - } - headerRight={headerRight} - hasHeaderBottomBorder={!hasValue} - isFocus={isFocus} - > - <div className='text-gray-700 text-sm'> - {(hasValue || (!hasValue && isFocus)) ? ( - <> - {isFocus - ? ( - <div> - <textarea - ref={inputRef} - value={tempValue} - rows={3} - onChange={e => setTempValue(e.target.value)} - className="w-full px-0 text-sm border-0 bg-transparent focus:outline-none " - placeholder={t('appDebug.openingStatement.placeholder') as string} - > - </textarea> - </div> - ) - : ( - <div dangerouslySetInnerHTML={{ - __html: coloredContent, - }}></div> - )} - {renderQuestions()} - </>) : ( - <div className='pt-2 pb-1 text-xs text-gray-500'>{t('appDebug.openingStatement.noDataPlaceHolder')}</div> - )} - - {isShowConfirmAddVar && ( - <ConfirmAddVar - varNameArr={notIncludeKeys} - onConfirm={autoAddVar} - onCancel={cancelAutoAddVar} - onHide={hideConfirmAddVar} - /> - )} - - </div> - </Panel> - ) -} -export default React.memo(OpeningStatement) diff --git a/web/hooks/use-pay.tsx b/web/hooks/use-pay.tsx index 344f03955c..3ba23b6763 100644 --- a/web/hooks/use-pay.tsx +++ b/web/hooks/use-pay.tsx @@ -4,11 +4,8 @@ import { useCallback, useEffect, useState } from 'react' import { useRouter, useSearchParams } from 'next/navigation' import { useTranslation } from 'react-i18next' import useSWR from 'swr' -import { useContext } from 'use-context-selector' -import I18n from '@/context/i18n' import { fetchDataSourceNotionBinding, - fetchFreeQuotaVerify, } from '@/service/common' import type { IConfirm } from '@/app/components/base/confirm' import Confirm from '@/app/components/base/confirm' @@ -53,66 +50,6 @@ export const useBillingPay = () => { return confirm } -const QUOTA_RECEIVE_STATUS: Record<string, any> = { - spark: { - success: { - 'en': 'Successful collection, the quota will be automatically increased after 5 minutes.', - 'zh-Hans': '领取成功,将在 5 分钟后自动增加配额', - }, - fail: { - 'en': 'Failure to collect', - 'zh-Hans': '领取失败', - }, - }, - zhipuai: { - success: { - 'en': 'Successful collection', - 'zh-Hans': '领取成功', - }, - fail: { - 'en': 'Failure to collect', - 'zh-Hans': '领取失败', - }, - }, -} - -const FREE_CHECK_PROVIDER = ['spark', 'zhipuai'] -export const useCheckFreeQuota = () => { - const { locale } = useContext(I18n) - const router = useRouter() - const [shouldVerify, setShouldVerify] = useState(false) - const searchParams = useSearchParams() - const type = searchParams.get('type') - const provider = searchParams.get('provider') - const result = searchParams.get('result') - const token = searchParams.get('token') - - const { data, error } = useSWR( - shouldVerify - ? `/workspaces/current/model-providers/${provider}/free-quota-qualification-verify?token=${token}` - : null, - fetchFreeQuotaVerify, - ) - - useEffect(() => { - if (error) - router.replace('/') - }, [error, router]) - - useEffect(() => { - if (type === 'provider_apply_callback' && FREE_CHECK_PROVIDER.includes(provider as string) && result === 'success') - setShouldVerify(true) - }, [type, provider, result]) - - return (data && provider) - ? { - type: data.flag ? 'info' : 'warning', - title: data.flag ? QUOTA_RECEIVE_STATUS[provider as string].success[locale] : QUOTA_RECEIVE_STATUS[provider].fail[locale], - desc: !data.flag ? data.reason : undefined, - } - : null -} - export const useCheckNotion = () => { const router = useRouter() const [confirm, setConfirm] = useState<ConfirmType | null>(null) @@ -154,7 +91,6 @@ export const CheckModal = () => { const { t } = useTranslation() const [showPayStatusModal, setShowPayStatusModal] = useState(true) const anthropicConfirmInfo = useAnthropicCheckPay() - const freeQuotaConfirmInfo = useCheckFreeQuota() const notionConfirmInfo = useCheckNotion() const billingConfirmInfo = useBillingPay() @@ -163,7 +99,7 @@ export const CheckModal = () => { router.replace('/') }, [router]) - const confirmInfo = anthropicConfirmInfo || freeQuotaConfirmInfo || notionConfirmInfo || billingConfirmInfo + const confirmInfo = anthropicConfirmInfo || notionConfirmInfo || billingConfirmInfo if (!confirmInfo || !showPayStatusModal) return null @@ -176,7 +112,7 @@ export const CheckModal = () => { showCancel={false} type={confirmInfo.type === 'info' ? 'info' : 'warning' } title={confirmInfo.title} - content={(confirmInfo as { desc: string }).desc || ''} + content={(confirmInfo as unknown as { desc: string }).desc || ''} confirmText={(confirmInfo.type === 'info' && t('common.operation.ok')) || ''} /> ) diff --git a/web/service/common.ts b/web/service/common.ts index d3c07f3c1d..70586b6ff6 100644 --- a/web/service/common.ts +++ b/web/service/common.ts @@ -38,11 +38,11 @@ import type { import type { RETRIEVE_METHOD } from '@/types/app' import type { SystemFeatures } from '@/types/feature' -interface LoginSuccess { +type LoginSuccess = { result: 'success' data: { access_token: string;refresh_token: string } } -interface LoginFail { +type LoginFail = { result: 'fail' data: string code: string @@ -183,7 +183,7 @@ export const fetchModelProviders: Fetcher<{ data: ModelProvider[] }, string> = ( return get<{ data: ModelProvider[] }>(url) } -export interface ModelProviderCredentials { +export type ModelProviderCredentials = { credentials?: Record<string, string | undefined | boolean> load_balancing: ModelLoadBalancingConfig } @@ -257,10 +257,6 @@ export const fetchFileUploadConfig: Fetcher<FileUploadConfigResponse, { url: str return get<FileUploadConfigResponse>(url) } -export const fetchFreeQuotaVerify: Fetcher<{ result: string; flag: boolean; reason: string }, string> = (url) => { - return get(url) as Promise<{ result: string; flag: boolean; reason: string }> -} - export const fetchNotionConnection: Fetcher<{ data: string }, string> = (url) => { return get(url) as Promise<{ data: string }> } @@ -297,7 +293,7 @@ export const moderate = (url: string, body: { app_id: string; text: string }) => return post(url, { body }) as Promise<ModerateResponse> } -interface RetrievalMethodsRes { +type RetrievalMethodsRes = { retrieval_method: RETRIEVE_METHOD[] } export const fetchSupportRetrievalMethods: Fetcher<RetrievalMethodsRes, string> = (url) => { From 66be03f6229bbb1f0185e0312a93a5c228b1f9ee Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Fri, 1 Nov 2024 14:02:10 +0800 Subject: [PATCH 16/18] fix: search tools ui and some ui problem --- .../market-place-plugin/list.tsx | 12 ++++++---- .../workflow/block-selector/tool-picker.tsx | 22 +++++++++++-------- web/i18n/en-US/plugin.ts | 1 + web/i18n/zh-Hans/plugin.ts | 1 + 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/web/app/components/workflow/block-selector/market-place-plugin/list.tsx b/web/app/components/workflow/block-selector/market-place-plugin/list.tsx index 3da4e04af5..6c82bd5c0c 100644 --- a/web/app/components/workflow/block-selector/market-place-plugin/list.tsx +++ b/web/app/components/workflow/block-selector/market-place-plugin/list.tsx @@ -1,5 +1,5 @@ 'use client' -import React, { forwardRef, useImperativeHandle, useMemo, useRef } from 'react' +import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react' import { useTranslation } from 'react-i18next' import useStickyScroll, { ScrollPosition } from '../use-sticky-scroll' import Item from './item' @@ -30,7 +30,6 @@ const List = ({ wrapElemRef, nextToStickyELemRef, }) - const stickyClassName = useMemo(() => { switch (scrollPosition) { case ScrollPosition.aboveTheWrap: @@ -38,7 +37,7 @@ const List = ({ case ScrollPosition.showing: return 'bottom-0 pt-3 pb-1' case ScrollPosition.belowTheWrap: - return 'bottom-0 items-center rounded-b-xl border-t border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg cursor-pointer' + return 'bottom-0 items-center rounded-b-xl border-t border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg rounded-b-lg cursor-pointer' } }, [scrollPosition]) @@ -46,6 +45,11 @@ const List = ({ handleScroll, })) + useEffect(() => { + handleScroll() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [list]) + const handleHeadClick = () => { if (scrollPosition === ScrollPosition.belowTheWrap) { nextToStickyELemRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' }) @@ -57,7 +61,7 @@ const List = ({ if (hasSearchText) { return ( <Link - className='sticky bottom-0 z-10 flex h-8 px-4 py-1 system-sm-medium items-center rounded-b-xl border-t border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg text-text-accent-light-mode-only cursor-pointer' + className='sticky bottom-0 z-10 flex h-8 px-4 py-1 system-sm-medium items-center border-t border-[0.5px] border-components-panel-border bg-components-panel-bg-blur rounded-b-lg shadow-lg text-text-accent-light-mode-only cursor-pointer' href={`${marketplaceUrlPrefix}/plugins`} target='_blank' > diff --git a/web/app/components/workflow/block-selector/tool-picker.tsx b/web/app/components/workflow/block-selector/tool-picker.tsx index 9ae8d625f9..f06bef73b9 100644 --- a/web/app/components/workflow/block-selector/tool-picker.tsx +++ b/web/app/components/workflow/block-selector/tool-picker.tsx @@ -20,6 +20,7 @@ import { } from '@/service/tools' import type { BlockEnum, ToolWithProvider } from '@/app/components/workflow/types' import SearchBox from '@/app/components/plugins/marketplace/search-box' +import { useTranslation } from 'react-i18next' type Props = { disabled: boolean @@ -42,6 +43,7 @@ const ToolPicker: FC<Props> = ({ onSelect, supportAddCustomTool, }) => { + const { t } = useTranslation() const [searchText, setSearchText] = useState('') const [buildInTools, setBuildInTools] = useState<ToolWithProvider[]>([]) @@ -83,15 +85,17 @@ const ToolPicker: FC<Props> = ({ </PortalToFollowElemTrigger> <PortalToFollowElemContent className='z-[1000]'> - <div className="relative w-[320px] min-h-20 bg-white"> - <SearchBox - search={searchText} - onSearchChange={setSearchText} - tags={[]} - onTagsChange={() => {}} - size='small' - placeholder='Search tools...' - /> + <div className="relative w-[320px] min-h-20 rounded-xl bg-components-panel-bg-blur border-[0.5px] border-components-panel-border shadow-lg"> + <div className='p-2 pb-1'> + <SearchBox + search={searchText} + onSearchChange={setSearchText} + tags={[]} + onTagsChange={() => { }} + size='small' + placeholder={t('plugin.searchTools')!} + /> + </div> <AllTools className='mt-1' searchText={searchText} diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 0801ee21b6..d9897445bf 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -4,6 +4,7 @@ const translation = { searchInMarketplace: 'Search in Marketplace', fromMarketplace: 'From Marketplace', endpointsEnabled: '{{num}} sets of endpoints enabled', + searchTools: 'Search tools...', detailPanel: { categoryTip: { marketplace: 'Installed from Marketplace', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index a8b8b2dafa..5ced92c19e 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -4,6 +4,7 @@ const translation = { searchInMarketplace: '在 Marketplace 中搜索', fromMarketplace: '来自市场', endpointsEnabled: '{{num}} 组端点已启用', + searchTools: '搜索工具...', detailPanel: { categoryTip: { marketplace: '从 Marketplace 安装', From 9f08206503bdc5b543daded8a5dfc66456933b19 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Fri, 1 Nov 2024 14:41:27 +0800 Subject: [PATCH 17/18] feat: can choose tool in agent page --- .../config/agent/agent-tools/index.tsx | 35 +++++++++++++++---- .../workflow/block-selector/all-tools.tsx | 9 +++-- .../workflow/block-selector/tool-picker.tsx | 1 - 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/web/app/components/app/configuration/config/agent/agent-tools/index.tsx b/web/app/components/app/configuration/config/agent/agent-tools/index.tsx index b66f331f5b..bbc352b9b4 100644 --- a/web/app/components/app/configuration/config/agent/agent-tools/index.tsx +++ b/web/app/components/app/configuration/config/agent/agent-tools/index.tsx @@ -27,10 +27,12 @@ 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 AddToolModal from '@/app/components/tools/add-tool-modal' +// import AddToolModal from '@/app/components/tools/add-tool-modal' 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' type AgentToolWithMoreInfo = AgentTool & { icon: any; collection?: Collection } | null const AgentTools: FC = () => { @@ -81,6 +83,21 @@ const AgentTools: FC = () => { 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: {}, + enabled: true, + }) + }) + setModelConfig(newModelConfig) + } + return ( <> <Panel @@ -107,7 +124,14 @@ const AgentTools: FC = () => { {tools.length < MAX_TOOLS_NUM && ( <> <div className='ml-3 mr-1 h-3.5 w-px bg-gray-200'></div> - <OperationBtn type="add" onClick={() => setIsShowChooseTool(true)} /> + <ToolPicker + trigger={<OperationBtn type="add" />} + isShow={isShowChooseTool} + onShowChange={setIsShowChooseTool} + disabled={false} + supportAddCustomTool + onSelect={handleSelectTool} + /> </> )} </div> @@ -125,8 +149,8 @@ const AgentTools: FC = () => { {item.isDeleted && <DefaultToolIcon className='w-5 h-5' />} {!item.isDeleted && ( <div className={cn((item.notAuthor || !item.enabled) && 'opacity-50')}> - {typeof item.icon === 'string' && <div className='w-5 h-5 bg-cover bg-center rounded-md' style={{ backgroundImage: `url(${item.icon})` }}/>} - {typeof item.icon !== 'string' && <AppIcon className='rounded-md' size='xs' icon={item.icon?.content} background={item.icon?.background}/>} + {typeof item.icon === 'string' && <div className='w-5 h-5 bg-cover bg-center rounded-md' 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 @@ -245,9 +269,6 @@ const AgentTools: FC = () => { ))} </div > </Panel > - {isShowChooseTool && ( - <AddToolModal onHide={() => setIsShowChooseTool(false)} /> - )} {isShowSettingTool && ( <SettingBuiltInTool toolName={currentTool?.tool_name as string} diff --git a/web/app/components/workflow/block-selector/all-tools.tsx b/web/app/components/workflow/block-selector/all-tools.tsx index db80492ace..2b93ed32e5 100644 --- a/web/app/components/workflow/block-selector/all-tools.tsx +++ b/web/app/components/workflow/block-selector/all-tools.tsx @@ -84,9 +84,12 @@ const AllTools = ({ </div> <ViewTypeSelect viewType={activeView} onChange={setActiveView} /> {supportAddCustomTool && ( - <ActionButton> - <RiAddLine className='w-4 h-4' /> - </ActionButton> + <div className='flex items-center'> + <div className='mr-1.5 w-px h-3.5 bg-divider-regular'></div> + <ActionButton className='bg-components-button-primary-bg hover:bg-components-button-primary-bg text-components-button-primary-text hover:text-components-button-primary-text'> + <RiAddLine className='w-4 h-4' /> + </ActionButton> + </div> )} </div> <div diff --git a/web/app/components/workflow/block-selector/tool-picker.tsx b/web/app/components/workflow/block-selector/tool-picker.tsx index f06bef73b9..9cc9686f84 100644 --- a/web/app/components/workflow/block-selector/tool-picker.tsx +++ b/web/app/components/workflow/block-selector/tool-picker.tsx @@ -78,7 +78,6 @@ const ToolPicker: FC<Props> = ({ onOpenChange={onShowChange} > <PortalToFollowElemTrigger - asChild onClick={handleTriggerClick} > {trigger} From 245bb02c886ab79e50c9344f6ce3ae8e2399641b Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Fri, 1 Nov 2024 14:51:35 +0800 Subject: [PATCH 18/18] chore: add on start to install --- .../install-from-local-package/steps/install.tsx | 6 +++++- .../install-from-marketplace/steps/install.tsx | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx index 08b21ad1ff..8461eeb425 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -13,10 +13,11 @@ import checkTaskStatus from '../../base/check-task-status' const i18nPrefix = 'plugin.installModal' -interface Props { +type Props = { uniqueIdentifier: string payload: PluginDeclaration onCancel: () => void + onStartToInstall?: () => void onInstalled: () => void onFailed: (message?: string) => void } @@ -25,6 +26,7 @@ const Installed: FC<Props> = ({ uniqueIdentifier, payload, onCancel, + onStartToInstall, onInstalled, onFailed, }) => { @@ -43,6 +45,8 @@ const Installed: FC<Props> = ({ const handleInstall = async () => { if (isInstalling) return setIsInstalling(true) + onStartToInstall?.() + try { const { all_installed: isInstalled, diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx index 8a6c5d3c0e..f1f5fecf93 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx @@ -18,6 +18,7 @@ type Props = { uniqueIdentifier: string payload: PluginManifestInMarket onCancel: () => void + onStartToInstall?: () => void onInstalled: () => void onFailed: (message?: string) => void } @@ -26,6 +27,7 @@ const Installed: FC<Props> = ({ uniqueIdentifier, payload, onCancel, + onStartToInstall, onInstalled, onFailed, }) => { @@ -43,6 +45,7 @@ const Installed: FC<Props> = ({ const handleInstall = async () => { if (isInstalling) return + onStartToInstall?.() setIsInstalling(true) try { @@ -90,7 +93,7 @@ const Installed: FC<Props> = ({ </> ) }</>) - }, [payload]) + }, [payload.latest_version, supportCheckInstalled]) return ( <>