diff --git a/web/client/api/request.ts b/web/client/api/request.ts index 6a0dac335..de36fe2f6 100644 --- a/web/client/api/request.ts +++ b/web/client/api/request.ts @@ -4,6 +4,7 @@ import { PostAgentMyPluginResponse, PostAgentPluginResponse, PostAgentQueryParams, + PostDbgptMyQueryParams, } from "@/types/agent"; import { GetAppInfoParams, IApp, IAgent, IAppData } from "@/types/app"; import { @@ -312,12 +313,24 @@ export const postAgentQuery = (data: PostAgentQueryParams) => { data ); }; +export const postDbgptsQuery = (data: PostAgentQueryParams) => { + return POST( + `/api/v1/serve/dbgpts/hub/query_page?page=${data?.page_index}&page_size=${data?.page_size}`, + data + ); +}; export const postAgentHubUpdate = (data?: PostAgentHubUpdateParams) => { return POST( "/api/v1/agent/hub/update", data ?? { channel: "", url: "", branch: "", authorization: "" } ); }; +export const postDbgptsHubUpdate = (data?: PostAgentHubUpdateParams) => { + return POST( + "/api/v1/serve/dbgpts/hub/source/refresh", + data ?? { channel: "", url: "", branch: "", authorization: "" } + ); +}; export const postAgentMy = (user?: string) => { return POST( "/api/v1/agent/my", @@ -325,18 +338,36 @@ export const postAgentMy = (user?: string) => { { params: { user } } ); }; +export const postDbgptsMy = (data?: PostDbgptMyQueryParams) => { + return POST( + `/api/v1/serve/dbgpts/my/query_page?page=${data?.page_index}&page_size=${data?.page_size}`, + data + ); +}; export const postAgentInstall = (pluginName: string, user?: string) => { return POST("/api/v1/agent/install", undefined, { params: { plugin_name: pluginName, user }, timeout: 60000, }); }; +export const postDbgptsInstall = (pluginName: string, user?: string) => { + return POST("/api/v1/serve/dbgpts/hub/install", undefined, { + params: { plugin_name: pluginName, user }, + timeout: 60000, + }); +}; export const postAgentUninstall = (pluginName: string, user?: string) => { return POST("/api/v1/agent/uninstall", undefined, { params: { plugin_name: pluginName, user }, timeout: 60000, }); }; +export const postDbgptsUninstall = (pluginName: string, user?: string) => { + return POST("/api/v1/serve/dbgpts/my/uninstall", undefined, { + params: { plugin_name: pluginName, user }, + timeout: 60000, + }); +}; export const postAgentUpload = ( user = "", data: FormData, diff --git a/web/locales/en/common.ts b/web/locales/en/common.ts index acb87747a..15040540d 100644 --- a/web/locales/en/common.ts +++ b/web/locales/en/common.ts @@ -323,5 +323,11 @@ export const CommonEn = { All: "All", Please_input_prompt_name: "Please input prompt name", Copy_Btn: 'Copy', - Delete_Btn: 'Delete' + Delete_Btn: 'Delete', + dbgpts_community: 'DBGPTS Community', + my_dbgpts: 'My DBGPTS', + Refresh_dbgpts: 'Refresh from the community Git repository', + workflow: 'Workflow', + resources: 'Resources', + app: 'App', } as const; diff --git a/web/locales/zh/common.ts b/web/locales/zh/common.ts index b641eebc8..70111fa10 100644 --- a/web/locales/zh/common.ts +++ b/web/locales/zh/common.ts @@ -325,5 +325,11 @@ export const CommonZh: Resources["translation"] = { All: "全部", Please_input_prompt_name: "请输入prompt名称", Copy_Btn: '复制', - Delete_Btn: '删除' + Delete_Btn: '删除', + dbgpts_community: 'DBGPTS社区', + my_dbgpts: '我的DBGPTS', + Refresh_dbgpts: '从社区Git仓库刷新', + workflow: '工作流', + resources: '资源', + app: '应用', } as const; diff --git a/web/new-components/common/blurredCard/index.tsx b/web/new-components/common/blurredCard/index.tsx index 18b51bd13..2a74e5c57 100644 --- a/web/new-components/common/blurredCard/index.tsx +++ b/web/new-components/common/blurredCard/index.tsx @@ -37,7 +37,7 @@ const BlurredCard: React.FC<{ className="backdrop-filter backdrop-blur-lg cursor-pointer bg-white bg-opacity-70 border-2 border-white rounded-lg shadow p-4 relative w-full h-full dark:border-[#6f7f95] dark:bg-[#6f7f95] dark:bg-opacity-60" >
-
+
{scene ? ( @@ -45,7 +45,7 @@ const BlurredCard: React.FC<{ logo && {name} )}
-
+
{/** 先简单判断下 */} {name.length > 6 ? ( @@ -71,7 +71,7 @@ const BlurredCard: React.FC<{
, path: '/knowledge', }, + // { + // key: 'agent', + // name: t('Plugins'), + // path: '/agent', + // icon: , + // }, { - key: 'agent', - name: t('Plugins'), - path: '/agent', + key: 'dbgpts', + name: t('dbgpts_community'), + path: '/dbgpts', icon: , }, { diff --git a/web/pages/construct/agent/index.tsx b/web/pages/construct/agent/index.tsx index e470051f9..4463442b7 100644 --- a/web/pages/construct/agent/index.tsx +++ b/web/pages/construct/agent/index.tsx @@ -94,7 +94,6 @@ function Agent() { label: t('My_Plugins'), }, ]; - console.log(agents); return ( diff --git a/web/pages/construct/dbgpts/index.tsx b/web/pages/construct/dbgpts/index.tsx new file mode 100644 index 000000000..39cfd2c82 --- /dev/null +++ b/web/pages/construct/dbgpts/index.tsx @@ -0,0 +1,254 @@ +import ConstructLayout from '@/new-components/layout/Construct'; +import MarketPlugins from '@/components/agent/market-plugins'; +import MyPlugins from '@/components/agent/my-plugins'; +import { IAgentPlugin, PostAgentQueryParams } from '@/types/agent'; +import { ClearOutlined, DownloadOutlined, PlusOutlined, SearchOutlined, SyncOutlined } from '@ant-design/icons'; +import { useRequest } from 'ahooks'; +import { Button, Input, Segmented, SegmentedProps, Tabs, Form, message, Spin, Tag } from 'antd'; +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { apiInterceptors, postDbgptsHubUpdate, postDbgptsInstall, postDbgptsQuery, postDbgptsUninstall, postDbgptsMy } from '@/client/api'; +import { useTranslation } from 'react-i18next'; +import BlurredCard, { ChatButton } from '@/new-components/common/blurredCard'; +import moment from 'moment'; +import cls from 'classnames'; +function Agent() { + const { t } = useTranslation(); + + const [searchValue, setSearchValue] = useState(''); + const [activeKey, setActiveKey] = useState('market'); + const [uploading, setUploading] = useState(false); + const [isError, setIsError] = useState(false); + const [actionIndex, setActionIndex] = useState(); + + const [form] = Form.useForm(); + const [typeStr, setTypeStr] = useState('all'); + + const pagination = useMemo<{ pageNo: number; pageSize: number }>( + () => ({ + pageNo: 1, + pageSize: 20, + }), + [], + ); + + const { + data: agents = [], + loading, + refresh, + } = useRequest( + async () => { + if (activeKey === 'my') { + const [err, res] = await apiInterceptors(postDbgptsMy({ + name: searchValue || undefined, + type: typeStr === 'all' ? undefined : typeStr, + page_index: pagination.pageNo, + page_size: pagination.pageSize, + })); + setIsError(!!err); + return res?.items ?? []; + } + const queryParams: PostAgentQueryParams = { + page_index: pagination.pageNo, + page_size: pagination.pageSize, + name: searchValue || undefined, + type: typeStr === 'all' ? undefined : typeStr, + }; + const [err, res] = await apiInterceptors(postDbgptsQuery(queryParams)); + setIsError(!!err); + return res?.items ?? []; + }, + { + manual: true, + }, + ); + + const updateFromGithub = async () => { + try { + setUploading(true); + const [err] = await apiInterceptors(postDbgptsHubUpdate()); + if (err) return; + message.success('success'); + refresh(); + } finally { + setUploading(false); + } + }; + useEffect(() => { + refresh(); + }, [activeKey, typeStr]); + const pluginAction = useCallback( + async (name: string, index: number, isInstall: boolean) => { + if (actionIndex) return; + setActionIndex(index); + const [err] = await apiInterceptors((isInstall ? postDbgptsInstall : postDbgptsUninstall)(name)); + if (!err) { + message.success('success'); + refresh(); + } + setActionIndex(undefined); + }, + [actionIndex, refresh], + ); + const items: SegmentedProps['options'] = [ + { + value: 'market', + label: 'DBGPTS', + }, + { + value: 'my', + label: t('my_dbgpts'), + }, + ]; + + const typeItems: SegmentedProps['options'] = [ + { + value: 'all', + label: t('All'), + }, + { + value: 'workflow', + label: t('workflow'), + }, + { + value: 'agents', + label: 'Agent', + }, + { + value: 'resources', + label: t('resources'), + }, + { + value: 'apps', + label: t('app'), + }, + { + value: 'operators', + label: t('operators'), + }, + ]; + + const logoUrl = { + workflow: '/pictures/flow.png', + agents: '/pictures/agent.png', + resources: '/pictures/database.png', + apps: '/pictures/app.png', + operators: '/pictures/knowledge.png', + } + + return ( + +
+ +
+
+ { + setActiveKey(key as string); + }} + value={activeKey} + /> + {/* } + placeholder={t('please_enter_the_keywords')} + value={searchValue} + onChange={(e) => setSearchValue(e.target.value)} + onPressEnter={refresh} + allowClear + className="w-[230px] h-[40px] border-1 border-white backdrop-filter backdrop-blur-lg bg-white bg-opacity-30 dark:border-[#6f7f95] dark:bg-[#6f7f95] dark:bg-opacity-60" + /> */} +
+
+ +
+
+
+ { + setTypeStr(key as string); + }} + value={typeStr} + /> + } + placeholder={t('please_enter_the_keywords')} + value={searchValue} + onChange={(e) => setSearchValue(e.target.value)} + onPressEnter={refresh} + allowClear + className="w-[230px] h-[40px] border-1 border-white ml-4 backdrop-filter backdrop-blur-lg bg-white bg-opacity-30 dark:border-[#6f7f95] dark:bg-[#6f7f95] dark:bg-opacity-60" + /> +
+
+ {agents.map((agent, index) => ( + { + if (agent.storage_url) window.open(agent.storage_url, '_blank'); + }} + description={agent.description} + name={agent.name} + key={agent.id} + Tags={ +
+ {agent.author && {agent.author}} + {agent.version && v{agent.version}} + {/* {agent.type && Type {agent.type}} */} + {agent.storage_channel && {agent.storage_channel}} +
+ } + LeftBottom={ +
+ {agent.author && {agent.author}} + {agent.author && } + {agent?.gmt_created && {moment(agent?.gmt_created).fromNow() + ' ' + t('update')}} +
+ } + RightTop={ + agent.type && {agent.type} + } + rightTopHover={false} + RightBottom={ + agent.installed || activeKey == 'my' ? ( + } + text="Uninstall" + onClick={() => { + pluginAction(agent.name, index, false); + }} + /> + ) : ( + } + text="Install" + onClick={() => { + pluginAction(agent.name, index, true); + }} + /> + ) + } + /> + ))} +
+ {/* {activeKey !== 'market' ? : } */} +
+
+
+ ); +} + +export default Agent; diff --git a/web/types/agent.ts b/web/types/agent.ts index d1cd068d3..20a032059 100644 --- a/web/types/agent.ts +++ b/web/types/agent.ts @@ -6,18 +6,23 @@ export type PostAgentHubUpdateParams = { }; export type PostAgentQueryParams = { + page_index?: number; + page_size?: number; + name?: string; + description?: string; + author?: string; + email?: string; + type?: string; + version?: string; + storage_channel?: string; + storage_url?: string; +}; + +export type PostDbgptMyQueryParams = { + type: string | undefined; + name: string | undefined; page_index: number; page_size: number; - filter?: { - name?: string; - description?: string; - author?: string; - email?: string; - type?: string; - version?: string; - storage_channel?: string; - storage_url?: string; - }; }; export type IAgentPlugin = { @@ -41,6 +46,7 @@ export type PostAgentPluginResponse = { total_page: number; total_row_count: number; datas: IAgentPlugin[]; + items: IAgentPlugin[]; }; export type IMyPlugin = { @@ -56,9 +62,12 @@ export type IMyPlugin = { use_count: number; created_at: string; description: string; + data?: any; }; -export type PostAgentMyPluginResponse = IMyPlugin[]; +export type PostAgentMyPluginResponse = { + items: IMyPlugin[]; +} export type GetDBGPTsListResponse = { app_code: string;