From a864f841b6afdd0bd57f51c774f39637b255cea6 Mon Sep 17 00:00:00 2001 From: ljs Date: Thu, 8 Aug 2024 20:56:29 +0800 Subject: [PATCH] feat: select knowledge --- web/ui/src/modules/agent/agent-model.ts | 85 ++++++++++++-- web/ui/src/modules/agent/protocol.ts | 6 + .../ConfigList/KnowledgeModal/index.tsx | 104 +++++++----------- .../components/ConfigList/ToolModal/index.tsx | 22 +--- .../components/ConfigList/index.tsx | 34 ++++-- 5 files changed, 152 insertions(+), 99 deletions(-) diff --git a/web/ui/src/modules/agent/agent-model.ts b/web/ui/src/modules/agent/agent-model.ts index 4461f24..b81d92d 100644 --- a/web/ui/src/modules/agent/agent-model.ts +++ b/web/ui/src/modules/agent/agent-model.ts @@ -1,4 +1,5 @@ -import { Deferred, inject, prop, transient } from '@difizen/mana-app'; +import { inject, prop, transient } from '@difizen/mana-app'; +import { message } from 'antd'; import { AsyncModel } from '../../common/async-model.js'; import { AxiosClient } from '../axios-client/index.js'; @@ -7,7 +8,13 @@ import { ToolManager } from '../tool/index.js'; import { AgentConfigManager } from './agent-config-manager.js'; import type { AgentConfig } from './agent-config.js'; -import type { LLMMeta, PromptMeta, PlannerMeta, ToolMeta } from './protocol.js'; +import type { + LLMMeta, + PromptMeta, + PlannerMeta, + ToolMeta, + KnowledgeMeta, +} from './protocol.js'; import { AgentModelType, AgentModelOption } from './protocol.js'; class Prompt implements PromptMeta { @@ -36,6 +43,8 @@ class Prompt implements PromptMeta { @transient() export class AgentModel extends AsyncModel { + @inject(ToolManager) toolManager: ToolManager; + axios: AxiosClient; // configManager: AgentConfigManager; @@ -70,38 +79,73 @@ export class AgentModel extends AsyncModel { @prop() openingSpeech?: string; + /** + * ------ + * Tools + * ------ + */ + @prop() - tool: ToolMeta[]; + allTools: ToolMeta[] = []; - @inject(ToolManager) toolManager: ToolManager; + @prop() + tool: ToolMeta[] = []; @prop() - toolList: ToolModel[] = []; + allToolsLoading = false; + /** + * ------ + * Knowledge + * ------ + */ @prop() - toolListLoading = false; + selectedKnowledge: KnowledgeMeta[] = []; @prop() - selectedKnowledgeList: ToolModel[] = []; + knowledges: KnowledgeMeta[] = []; + + @prop() + knowledgesLoading = false; async updateToolList() { try { - this.toolListLoading = true; + this.allToolsLoading = true; const options = await this.toolManager.getTools(); - this.toolList = options.map(this.toolManager.getOrCreateTool); + this.allTools = options; } finally { - this.toolListLoading = false; + this.allToolsLoading = false; } } updateSelectedToolList(ids: React.Key[]) { - this.tool = this.toolList.filter((item) => ids.includes(item.id)); + this.tool = this.allTools.filter((item) => ids.includes(item.id)); } removeSelectedToolList(ids: React.Key[]) { this.tool = this.tool.filter((item) => !ids.includes(item.id)); } + async updateKnowledgeList() { + try { + this.knowledgesLoading = true; + const options = await this.fetchKnowdledgeList(); + this.knowledges = options; + } finally { + this.knowledgesLoading = false; + } + } + + updateSelectedKnowledgeList(ids: React.Key[]) { + this.selectedKnowledge = this.knowledges.filter((item) => ids.includes(item.id)); + } + + removeSelectedKnowledgeList(ids: React.Key[]) { + this.selectedKnowledge = this.selectedKnowledge.filter( + (item) => !ids.includes(item.id), + ); + } + // protected draftDeferred = new Deferred(); // get draftReady() { @@ -187,6 +231,7 @@ export class AgentModel extends AsyncModel { tool: this.tool, memory: this.memory, opening_speech: this.openingSpeech, + knowledge: this.selectedKnowledge, }; } @@ -204,4 +249,22 @@ export class AgentModel extends AsyncModel { } return false; } + + async fetchKnowdledgeList() { + try { + const res = await this.axios.put(`/api/v1/knowledge`); + if (res.status === 200 && res.data?.length) { + return res.data; + } + } catch (e) { + console.error('获取知识库失败'); + } + return [ + { + id: 'string', + nickname: '测试知识库', + description: '测试知识库', + }, + ]; + } } diff --git a/web/ui/src/modules/agent/protocol.ts b/web/ui/src/modules/agent/protocol.ts index df38218..786568c 100644 --- a/web/ui/src/modules/agent/protocol.ts +++ b/web/ui/src/modules/agent/protocol.ts @@ -12,6 +12,12 @@ export interface ToolMeta { description?: string; parameters: any[]; } + +export interface KnowledgeMeta { + id: string; + nickname: string; + description: string; +} export interface PlannerMeta { id: string; nickname: string; diff --git a/web/ui/src/views/agent-config/components/ConfigList/KnowledgeModal/index.tsx b/web/ui/src/views/agent-config/components/ConfigList/KnowledgeModal/index.tsx index 6b5032e..04ab60d 100644 --- a/web/ui/src/views/agent-config/components/ConfigList/KnowledgeModal/index.tsx +++ b/web/ui/src/views/agent-config/components/ConfigList/KnowledgeModal/index.tsx @@ -1,106 +1,84 @@ import type { TableColumnsType } from 'antd'; -import { Modal, Table } from 'antd'; -import { useState } from 'react'; +import { Avatar, Modal, Table } from 'antd'; +import type { TableRowSelection } from 'antd/es/table/interface.js'; +import { useMemo } from 'react'; -interface DataType { - key: React.Key; - id: string; - nickname: string; - avatar: number; - description: string; - address: string; - added: boolean; -} +import type { KnowledgeMeta } from '../../../../../modules/agent/protocol.js'; export const KnowledgeModal = ({ + dataSource, open, onCancel, + onOk, + loading, + selectedRowKeys = [], + setSelectedRowKeys, }: { open: boolean; + dataSource: KnowledgeMeta[]; onCancel: () => void; + onOk: (selectedRowKeys: React.Key[]) => void; + loading: boolean; + selectedRowKeys: React.Key[]; + setSelectedRowKeys: (selectedRowKeys: React.Key[]) => void; }) => { - function useKnowledgeTable() { - const dataSource = [ - { - id: '1', - nickname: '胡彦斌', - avatar: 32, - description: '西湖区湖底公园1号', - address: '西湖区湖底公园1号', - added: true, - }, - { - id: '2', - nickname: '胡彦斌', - avatar: 32, - description: '西湖区湖底公园1号', - address: '西湖区湖底公园1号', - added: true, - }, - ] as DataType[]; - - const columns: TableColumnsType = [ - { - title: 'nickname', - dataIndex: 'nickname', - key: 'nickname', - }, + const columns = useMemo(() => { + const c: TableColumnsType = [ { title: 'id', dataIndex: 'id', key: 'id', }, + { title: 'avatar', dataIndex: 'avatar', key: 'avatar', + render(value) { + return ; + }, }, { - title: 'description', - dataIndex: 'description', - key: 'description', + title: 'nickname', + dataIndex: 'nickname', + key: 'nickname', }, + { title: 'description', dataIndex: 'description', key: 'description', }, - { - title: 'added', - dataIndex: 'added', - key: 'added', - render: (text: boolean) => { - return text ? '是' : '否'; - }, - }, ]; - return { - dataSource, - columns, - }; - } - - const { dataSource, columns } = useKnowledgeTable(); + return c; + }, []); - const [selectedRowKeys, setSelectedRowKeys] = useState([]); - const [loading, setLoading] = useState(false); + // const [selectedRowKeys, setSelectedRowKeys] = + // useState(defaultSelectedRowKeys); const onSelectChange = (newSelectedRowKeys: React.Key[]) => { setSelectedRowKeys(newSelectedRowKeys); }; - const rowSelection: TableRowSelection = { + const rowSelection: TableRowSelection = { selectedRowKeys, onChange: onSelectChange, }; - const hasSelected = selectedRowKeys.length > 0; - return ( - onCancel()}> - + { + onOk(selectedRowKeys); + }} + onCancel={() => onCancel()} + loading={loading} + > + rowSelection={rowSelection} - dataSource={dataSource} + dataSource={dataSource || []} columns={columns} rowKey={'id'} > diff --git a/web/ui/src/views/agent-config/components/ConfigList/ToolModal/index.tsx b/web/ui/src/views/agent-config/components/ConfigList/ToolModal/index.tsx index 0c44cfb..50a74fa 100644 --- a/web/ui/src/views/agent-config/components/ConfigList/ToolModal/index.tsx +++ b/web/ui/src/views/agent-config/components/ConfigList/ToolModal/index.tsx @@ -1,20 +1,10 @@ -import { useInject, useMount, ViewInstance } from '@difizen/mana-app'; import type { TableColumnsType } from 'antd'; import { Avatar, Modal, Table } from 'antd'; import type { TableRowSelection } from 'antd/es/table/interface.js'; -import { useMemo, useState } from 'react'; +import { useMemo } from 'react'; -import { AgentConfig } from '../../../../../modules/agent/agent-config.js'; +import type { ToolMeta } from '../../../../../modules/agent/index.js'; import { ToolIcon } from '../../../../tool/tool-icon.js'; -import type { AgentConfigView } from '../../../view.js'; - -interface DataType { - id: string; - nickname: string; - avatar: string; - description: string; - parameters: string[]; -} export const ToolModal = ({ dataSource, @@ -26,7 +16,7 @@ export const ToolModal = ({ setSelectedRowKeys, }: { open: boolean; - dataSource: DataType[]; + dataSource: ToolMeta[]; onCancel: () => void; onOk: (selectedRowKeys: React.Key[]) => void; loading: boolean; @@ -34,7 +24,7 @@ export const ToolModal = ({ setSelectedRowKeys: (selectedRowKeys: React.Key[]) => void; }) => { const columns = useMemo(() => { - const c: TableColumnsType = [ + const c: TableColumnsType = [ { title: 'id', dataIndex: 'id', @@ -71,7 +61,7 @@ export const ToolModal = ({ setSelectedRowKeys(newSelectedRowKeys); }; - const rowSelection: TableRowSelection = { + const rowSelection: TableRowSelection = { selectedRowKeys, onChange: onSelectChange, }; @@ -87,7 +77,7 @@ export const ToolModal = ({ onCancel={() => onCancel()} loading={loading} > - + rowSelection={rowSelection} dataSource={dataSource || []} columns={columns} diff --git a/web/ui/src/views/agent-config/components/ConfigList/index.tsx b/web/ui/src/views/agent-config/components/ConfigList/index.tsx index 7ad971a..9040909 100644 --- a/web/ui/src/views/agent-config/components/ConfigList/index.tsx +++ b/web/ui/src/views/agent-config/components/ConfigList/index.tsx @@ -1,11 +1,11 @@ import './index.less'; -import { PlusOutlined } from '@ant-design/icons'; +import { FileTwoTone, PlusOutlined } from '@ant-design/icons'; import { useInject, useMount, ViewInstance } from '@difizen/mana-app'; import type { CollapseProps } from 'antd'; import { Avatar, Collapse, Space } from 'antd'; import { useCallback, useMemo, useState } from 'react'; -import type { ToolMeta } from '../../../../modules/agent/protocol.js'; +import type { KnowledgeMeta, ToolMeta } from '../../../../modules/agent/protocol.js'; import type { AgentConfigView } from '../../view.js'; import { SkillItem } from '../ItemCard/index.js'; @@ -27,7 +27,7 @@ const SkillConfigCard = ({ onAdd: (serviceType: ServiceType) => void; onDelete: (serviceType: ServiceType, itemKey: string) => void; tools: ToolMeta[]; - knowledge: any[]; + knowledge: KnowledgeMeta[]; }) => { const items: CollapseProps['items'] = useMemo(() => { return [ @@ -49,10 +49,13 @@ const SkillConfigCard = ({ {knowledge.map((item) => { return ( { + onDelete('knowledge', item.id); + }} key={item.id} - icon={} - title="title" - description="descriptiondescriptiondescription" + icon={} + title={item.nickname || '-'} + description={item.description || '-'} > ); })} @@ -121,6 +124,7 @@ export const ConfigList = () => { useMount(() => { instance.agent.updateToolList(); + instance.agent.updateKnowledgeList(); }); const onAdd = useCallback((addKey: ServiceType) => { @@ -132,12 +136,15 @@ export const ConfigList = () => { { if (serviceType === 'tool') { instance.agent.removeSelectedToolList([itemKey]); } + if (serviceType === 'knowledge') { + instance.agent.removeSelectedKnowledgeList([itemKey]); + } }} > @@ -147,6 +154,15 @@ export const ConfigList = () => { onCancel={() => { setCurServiceType(undefined); }} + dataSource={instance.agent.knowledges} + onOk={() => { + setCurServiceType(undefined); + }} + loading={instance.agent.allToolsLoading} + selectedRowKeys={instance.agent.selectedKnowledge.map((item) => item.id)} + setSelectedRowKeys={(keys) => { + instance.agent.updateSelectedKnowledgeList(keys); + }} > { onCancel={() => { setCurServiceType(undefined); }} - dataSource={instance.agent.toolList} + dataSource={instance.agent.allTools} onOk={() => { setCurServiceType(undefined); }} - loading={instance.agent.toolListLoading} + loading={instance.agent.allToolsLoading} selectedRowKeys={instance.agent.tool.map((item) => item.id)} setSelectedRowKeys={(keys) => { instance.agent.updateSelectedToolList(keys);