| 'use client' | 'use client' | ||||
| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| import React, { useMemo, useState } from 'react' | |||||
| import React, { useCallback, useMemo, useState } from 'react' | |||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { useContext } from 'use-context-selector' | import { useContext } from 'use-context-selector' | ||||
| import copy from 'copy-to-clipboard' | import copy from 'copy-to-clipboard' | ||||
| import ToolPicker from '@/app/components/workflow/block-selector/tool-picker' | import ToolPicker from '@/app/components/workflow/block-selector/tool-picker' | ||||
| import type { ToolDefaultValue } from '@/app/components/workflow/block-selector/types' | import type { ToolDefaultValue } from '@/app/components/workflow/block-selector/types' | ||||
| import { canFindTool } from '@/utils' | import { canFindTool } from '@/utils' | ||||
| import { useMittContextSelector } from '@/context/mitt-context' | |||||
| type AgentToolWithMoreInfo = AgentTool & { icon: any; collection?: Collection } | null | type AgentToolWithMoreInfo = AgentTool & { icon: any; collection?: Collection } | null | ||||
| const AgentTools: FC = () => { | const AgentTools: FC = () => { | ||||
| const [isShowChooseTool, setIsShowChooseTool] = useState(false) | const [isShowChooseTool, setIsShowChooseTool] = useState(false) | ||||
| const { modelConfig, setModelConfig, collectionList } = useContext(ConfigContext) | const { modelConfig, setModelConfig, collectionList } = useContext(ConfigContext) | ||||
| const formattingChangedDispatcher = useFormattingChangedDispatcher() | const formattingChangedDispatcher = useFormattingChangedDispatcher() | ||||
| const [currentTool, setCurrentTool] = useState<AgentToolWithMoreInfo>(null) | const [currentTool, setCurrentTool] = useState<AgentToolWithMoreInfo>(null) | ||||
| const currentCollection = useMemo(() => { | const currentCollection = useMemo(() => { | ||||
| if (!currentTool) return null | if (!currentTool) return null | ||||
| collection, | collection, | ||||
| } | } | ||||
| }) | }) | ||||
| const useSubscribe = useMittContextSelector(s => s.useSubscribe) | |||||
| const handleUpdateToolsWhenInstallToolSuccess = useCallback((installedPluginNames: string[]) => { | |||||
| const newModelConfig = produce(modelConfig, (draft) => { | |||||
| draft.agentConfig.tools.forEach((item: any) => { | |||||
| if (item.isDeleted && installedPluginNames.includes(item.provider_id)) | |||||
| item.isDeleted = false | |||||
| }) | |||||
| }) | |||||
| setModelConfig(newModelConfig) | |||||
| }, [modelConfig, setModelConfig]) | |||||
| useSubscribe('plugin:install:success', handleUpdateToolsWhenInstallToolSuccess as any) | |||||
| const handleToolSettingChange = (value: Record<string, any>) => { | const handleToolSettingChange = (value: Record<string, any>) => { | ||||
| const newModelConfig = produce(modelConfig, (draft) => { | const newModelConfig = produce(modelConfig, (draft) => { | ||||
| disabled={false} | disabled={false} | ||||
| supportAddCustomTool | supportAddCustomTool | ||||
| onSelect={handleSelectTool} | onSelect={handleSelectTool} | ||||
| selectedTools={tools} | |||||
| selectedTools={tools as any} | |||||
| /> | /> | ||||
| </> | </> | ||||
| )} | )} |
| } from '@/utils' | } from '@/utils' | ||||
| import PluginDependency from '@/app/components/workflow/plugin-dependency' | import PluginDependency from '@/app/components/workflow/plugin-dependency' | ||||
| import { supportFunctionCall } from '@/utils/tool-call' | import { supportFunctionCall } from '@/utils/tool-call' | ||||
| import { MittProvider } from '@/context/mitt-context' | |||||
| type PublishConfig = { | type PublishConfig = { | ||||
| modelConfig: ModelConfig | modelConfig: ModelConfig | ||||
| }} | }} | ||||
| > | > | ||||
| <FeaturesProvider features={featuresData}> | <FeaturesProvider features={featuresData}> | ||||
| <> | |||||
| <MittProvider> | |||||
| <div className="flex h-full flex-col"> | <div className="flex h-full flex-col"> | ||||
| <div className='relative flex h-[200px] grow pt-14'> | <div className='relative flex h-[200px] grow pt-14'> | ||||
| {/* Header */} | {/* Header */} | ||||
| /> | /> | ||||
| )} | )} | ||||
| <PluginDependency /> | <PluginDependency /> | ||||
| </> | |||||
| </MittProvider> | |||||
| </FeaturesProvider> | </FeaturesProvider> | ||||
| </ConfigContext.Provider> | </ConfigContext.Provider> | ||||
| ) | ) |
| import { useInstallOrUpdate } from '@/service/use-plugins' | import { useInstallOrUpdate } from '@/service/use-plugins' | ||||
| import useRefreshPluginList from '../../hooks/use-refresh-plugin-list' | import useRefreshPluginList from '../../hooks/use-refresh-plugin-list' | ||||
| import { useCanInstallPluginFromMarketplace } from '@/app/components/plugins/plugin-page/use-permission' | import { useCanInstallPluginFromMarketplace } from '@/app/components/plugins/plugin-page/use-permission' | ||||
| import { useMittContextSelector } from '@/context/mitt-context' | |||||
| const i18nPrefix = 'plugin.installModal' | const i18nPrefix = 'plugin.installModal' | ||||
| type Props = { | type Props = { | ||||
| isHideButton, | isHideButton, | ||||
| }) => { | }) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const emit = useMittContextSelector(s => s.emit) | |||||
| const [selectedPlugins, setSelectedPlugins] = React.useState<Plugin[]>([]) | const [selectedPlugins, setSelectedPlugins] = React.useState<Plugin[]>([]) | ||||
| const [selectedIndexes, setSelectedIndexes] = React.useState<number[]>([]) | const [selectedIndexes, setSelectedIndexes] = React.useState<number[]>([]) | ||||
| const selectedPluginsNum = selectedPlugins.length | const selectedPluginsNum = selectedPlugins.length | ||||
| }) | }) | ||||
| })) | })) | ||||
| const hasInstallSuccess = res.some(r => r.success) | const hasInstallSuccess = res.some(r => r.success) | ||||
| if (hasInstallSuccess) | |||||
| if (hasInstallSuccess) { | |||||
| refreshPluginList(undefined, true) | refreshPluginList(undefined, true) | ||||
| emit('plugin:install:success', selectedPlugins.map((p) => { | |||||
| return `${p.plugin_id}/${p.name}` | |||||
| })) | |||||
| } | |||||
| }, | }, | ||||
| }) | }) | ||||
| const handleInstall = () => { | const handleInstall = () => { |
| import { createContext, useContext, useContextSelector } from 'use-context-selector' | |||||
| import { useMitt } from '@/hooks/use-mitt' | |||||
| import { noop } from 'lodash-es' | |||||
| type ContextValueType = ReturnType<typeof useMitt> | |||||
| export const MittContext = createContext<ContextValueType>({ | |||||
| emit: noop, | |||||
| useSubscribe: noop, | |||||
| }) | |||||
| export const MittProvider = ({ children }: { children: React.ReactNode }) => { | |||||
| const mitt = useMitt() | |||||
| return ( | |||||
| <MittContext.Provider value={mitt}> | |||||
| {children} | |||||
| </MittContext.Provider> | |||||
| ) | |||||
| } | |||||
| export const useMittContext = () => { | |||||
| return useContext(MittContext) | |||||
| } | |||||
| export function useMittContextSelector<T>(selector: (value: ContextValueType) => T): T { | |||||
| return useContextSelector(MittContext, selector) | |||||
| } |