aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiBotController.java
@@ -177,7 +177,7 @@ function_call(aiMessageResponse, emitter, needClose, historiesPrompt, llm, prompt, false); } catch (Exception e) { emitter.completeWithError(e); } } if (needClose[0]) { System.out.println("function chat complete"); @@ -526,7 +526,7 @@ List<AiBotPlugins> aiBotPlugins = aiBotPluginsService.getMapper().selectListWithRelationsByQuery(queryWrapper); // 根据插件iD查询该插件下面有哪些插件工具,转换成Function for (AiBotPlugins aiBotPlugin: aiBotPlugins){ BigInteger pluginId = aiBotPlugin.getPluginId(); BigInteger pluginId = aiBotPlugin.getPluginToolId(); QueryWrapper queryTool = QueryWrapper.create() .select("*") .from("tb_ai_plugin_tool") @@ -539,4 +539,4 @@ } } } } aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiBotPluginsController.java
@@ -1,5 +1,6 @@ package tech.aiflowy.ai.controller; import org.springframework.web.bind.annotation.PostMapping; import tech.aiflowy.common.domain.Result; import tech.aiflowy.common.tree.Tree; import tech.aiflowy.common.web.controller.BaseCurdController; @@ -9,7 +10,9 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import tech.aiflowy.common.web.jsonbody.JsonBody; import javax.annotation.Resource; import java.util.List; /** @@ -26,6 +29,9 @@ super(service); } @Resource private AiBotPluginsService aiBotPluginsService; @GetMapping("list") public Result list(AiBotPlugins entity, Boolean asTree, String sortKey, String sortType){ @@ -36,7 +42,20 @@ List<AiBotPlugins> list = Tree.tryToTree(aiBotPlugins, asTree); return Result.success(list); return Result.success(list); } } @PostMapping("/getList") public Result getList(@JsonBody(value = "botId", required = true) String botId){ // QueryWrapper queryWrapper = QueryWrapper.create().select("plugin_id").where("bot_id = ?", botId); // List<AiBotPlugins> list = service.list(queryWrapper); return aiBotPluginsService.getList(botId); } @PostMapping("/doRemove") public Result doRemove(@JsonBody(value = "botId", required = true) String botId, @JsonBody(value = "pluginId", required = true) String pluginId){ return aiBotPluginsService.doRemove(botId, pluginId); } } aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiDocumentController.java
@@ -1,32 +1,14 @@ package tech.aiflowy.ai.controller; import com.agentsflex.core.document.DocumentSplitter; import com.agentsflex.core.document.splitter.RegexDocumentSplitter; import com.agentsflex.core.document.splitter.SimpleTokenizeSplitter; import com.agentsflex.core.llm.embedding.EmbeddingOptions; import org.springframework.core.io.ClassPathResource; import tech.aiflowy.ai.entity.AiDocument; import tech.aiflowy.ai.entity.AiDocumentChunk; import tech.aiflowy.ai.entity.AiKnowledge; import tech.aiflowy.ai.entity.AiLlm; import tech.aiflowy.ai.entity.base.AiKnowledgeBase; import tech.aiflowy.ai.service.*; import tech.aiflowy.ai.service.impl.AiDocumentServiceImpl; import tech.aiflowy.common.ai.DocumentParserFactory; import tech.aiflowy.common.ai.ExcelDocumentSplitter; import tech.aiflowy.common.domain.Result; import tech.aiflowy.common.tree.Tree; import tech.aiflowy.common.util.RequestUtil; import tech.aiflowy.common.util.StringUtil; import tech.aiflowy.common.web.controller.BaseCurdController; import tech.aiflowy.common.web.jsonbody.JsonBody; import tech.aiflowy.core.utils.JudgeFileTypeUtil; import tech.aiflowy.common.filestorage.FileStorageService; import cn.dev33.satoken.stp.StpUtil; import com.agentsflex.core.document.Document; import com.agentsflex.core.document.DocumentParser; import com.agentsflex.core.document.DocumentSplitter; import com.agentsflex.core.document.splitter.RegexDocumentSplitter; import com.agentsflex.core.document.splitter.SimpleDocumentSplitter; import com.agentsflex.core.document.splitter.SimpleTokenizeSplitter; import com.agentsflex.core.llm.Llm; import com.agentsflex.core.llm.embedding.EmbeddingOptions; import com.agentsflex.core.store.DocumentStore; import com.agentsflex.core.store.StoreOptions; import com.agentsflex.core.store.StoreResult; @@ -36,10 +18,30 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.http.MediaType; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import tech.aiflowy.ai.entity.AiDocument; import tech.aiflowy.ai.entity.AiDocumentChunk; import tech.aiflowy.ai.entity.AiKnowledge; import tech.aiflowy.ai.entity.AiLlm; import tech.aiflowy.ai.service.AiDocumentChunkService; import tech.aiflowy.ai.service.AiDocumentService; import tech.aiflowy.ai.service.AiKnowledgeService; import tech.aiflowy.ai.service.AiLlmService; import tech.aiflowy.ai.service.impl.AiDocumentServiceImpl; import tech.aiflowy.common.ai.DocumentParserFactory; import tech.aiflowy.common.ai.ExcelDocumentSplitter; import tech.aiflowy.common.domain.Result; import tech.aiflowy.common.filestorage.FileStorageService; import tech.aiflowy.common.tree.Tree; import tech.aiflowy.common.util.RequestUtil; import tech.aiflowy.common.util.StringUtil; import tech.aiflowy.common.web.controller.BaseCurdController; import tech.aiflowy.common.web.jsonbody.JsonBody; import tech.aiflowy.core.utils.JudgeFileTypeUtil; import javax.annotation.Resource; import java.io.File; aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiPluginController.java
@@ -52,4 +52,11 @@ return aiPluginService.updatePlugin(aiPlugin); } } @PostMapping("/getList") public Result getList(@JsonBody(value = "botId", required = true) String botId){ // QueryWrapper queryWrapper = QueryWrapper.create().select("plugin_id").where("bot_id = ?", botId); // List<AiBotPlugins> list = service.list(queryWrapper); return aiPluginService.getList(botId); } } aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiPluginToolController.java
@@ -50,4 +50,10 @@ return aiPluginToolService.updatePlugin(aiPluginTool); } } @PostMapping("/tool/list") public Result getPluginToolList(@JsonBody(value = "botId", required = true) BigInteger botId){ return aiPluginToolService.getPluginToolList(botId); } } aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/controller/AiPluginsController.java
@@ -49,7 +49,7 @@ @Override protected void onRemoveAfter(Collection<Serializable> ids) { QueryWrapper wrapper = QueryWrapper.create(); wrapper.in(AiBotPlugins::getPluginId, ids); wrapper.in(AiBotPlugins::getPluginToolId, ids); aiBotPluginsService.remove(wrapper); } } } aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/entity/base/AiBotPluginsBase.java
@@ -15,7 +15,7 @@ private BigInteger botId; private BigInteger pluginId; private BigInteger pluginToolId; private String options; @@ -35,12 +35,12 @@ this.botId = botId; } public BigInteger getPluginId() { return pluginId; public BigInteger getPluginToolId() { return pluginToolId; } public void setPluginId(BigInteger pluginId) { this.pluginId = pluginId; public void setPluginToolId(BigInteger pluginToolId) { this.pluginToolId = pluginToolId; } public String getOptions() { aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/service/AiBotPluginsService.java
@@ -2,6 +2,7 @@ import com.mybatisflex.core.service.IService; import tech.aiflowy.ai.entity.AiBotPlugins; import tech.aiflowy.common.domain.Result; /** * 服务层。 @@ -11,4 +12,7 @@ */ public interface AiBotPluginsService extends IService<AiBotPlugins> { Result getList(String botId); Result doRemove(String botId, String pluginId); } aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/service/AiPluginService.java
@@ -17,4 +17,6 @@ Result removePlugin(String id); Result updatePlugin(AiPlugin aiPlugin); Result getList(String botId); } aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/service/AiPluginToolService.java
@@ -22,4 +22,6 @@ Result updatePlugin(AiPluginTool aiPluginTool); Result searchPluginToolByPluginId(BigInteger pluginId); Result getPluginToolList(BigInteger botId); } aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/service/impl/AiBotPluginsServiceImpl.java
@@ -1,10 +1,18 @@ package tech.aiflowy.ai.service.impl; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.spring.service.impl.ServiceImpl; import tech.aiflowy.ai.entity.AiBotPlugins; import tech.aiflowy.ai.entity.AiPlugin; import tech.aiflowy.ai.mapper.AiBotPluginsMapper; import tech.aiflowy.ai.mapper.AiPluginMapper; import tech.aiflowy.ai.service.AiBotPluginsService; import org.springframework.stereotype.Service; import tech.aiflowy.common.domain.Result; import javax.annotation.Resource; import java.math.BigInteger; import java.util.List; /** * 服务层实现。 @@ -15,4 +23,31 @@ @Service public class AiBotPluginsServiceImpl extends ServiceImpl<AiBotPluginsMapper, AiBotPlugins> implements AiBotPluginsService{ @Resource private AiBotPluginsMapper aiBotPluginsMapper; @Resource private AiPluginMapper aiPluginMapper; @Override public Result getList(String botId) { QueryWrapper queryWrapper = QueryWrapper.create().select("plugin_tool_id").where("bot_id = ?", botId); List<BigInteger> pluginIds = aiBotPluginsMapper.selectListByQueryAs(queryWrapper, BigInteger.class); List<AiPlugin> aiPlugins = aiPluginMapper.selectListByIds(pluginIds); return Result.success(aiPlugins); } @Override public Result doRemove(String botId, String pluginToolId) { QueryWrapper queryWrapper = QueryWrapper.create().select("id") .from("tb_ai_bot_plugins") .where("bot_id = ?", botId) .where("plugin_tool_id = ?", pluginToolId); BigInteger id = aiBotPluginsMapper.selectOneByQueryAs(queryWrapper, BigInteger.class); int delete = aiBotPluginsMapper.deleteById(id); if (delete <= 0) { return Result.fail(); } return Result.success(); } } aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/service/impl/AiPluginServiceImpl.java
@@ -10,6 +10,7 @@ import javax.annotation.Resource; import java.util.Date; import java.util.List; /** * 服务层实现。 @@ -57,4 +58,12 @@ } return Result.success(); } @Override public Result getList(String botId) { QueryWrapper queryWrapper = QueryWrapper.create().select("*") .from("tb_ai_plugin"); List<AiPlugin> aiPlugins = aiPluginMapper.selectListByQueryAs(queryWrapper, AiPlugin.class); return Result.success(aiPlugins); } } aiflowy-modules/aiflowy-module-ai/src/main/java/tech/aiflowy/ai/service/impl/AiPluginToolServiceImpl.java
@@ -10,6 +10,7 @@ import org.springframework.stereotype.Service; import tech.aiflowy.ai.entity.AiPlugin; import tech.aiflowy.ai.entity.AiPluginTool; import tech.aiflowy.ai.mapper.AiBotPluginsMapper; import tech.aiflowy.ai.mapper.AiPluginMapper; import tech.aiflowy.ai.mapper.AiPluginToolMapper; import tech.aiflowy.ai.service.AiPluginToolService; @@ -37,6 +38,9 @@ @Resource private AiPluginMapper aiPluginMapper; @Resource private AiBotPluginsMapper aiBotPluginsMapper; @Override public Result savePluginTool(AiPluginTool aiPluginTool) { @@ -103,6 +107,20 @@ return Result.success(aiPluginTools); } @Override public Result getPluginToolList(BigInteger botId) { QueryWrapper queryAiPluginToolWrapper = QueryWrapper.create() .select("plugin_tool_id") .from("tb_ai_bot_plugins") .where("bot_id = ? ", botId); List<BigInteger> pluginToolIds = aiBotPluginsMapper.selectListByQueryAs(queryAiPluginToolWrapper, BigInteger.class); if (pluginToolIds.size() <= 0){ return Result.success(); } List<AiPluginTool> aiPluginTools = aiPluginToolMapper.selectListByIds(pluginToolIds); return Result.success(aiPluginTools); } public static String switchParams(String paramString){ ObjectMapper mapper = new ObjectMapper(); // 1. 将JSON解析为Map<String, Parameter> aiflowy-ui-react/src/pages/ai/botDesign/BotDesign.tsx
@@ -5,7 +5,16 @@ import {App, Avatar, Button, Col, Collapse, Modal, Select, Tooltip} from 'antd'; import Title from 'antd/es/typography/Title'; import {DeleteOutlined, PlusOutlined} from "@ant-design/icons"; import {useDetail, useGet, useList, usePostManual, useRemove, useSave, useUpdate} from "../../../hooks/useApis.ts"; import { useDetail, useGet, useList, usePost, usePostManual, useRemove, useSave, useUpdate } from "../../../hooks/useApis.ts"; import {useParams} from "react-router-dom"; import {WorkflowsModal} from "./Workflows.tsx"; import {DebouncedTextArea} from "../../../components/DebouncedTextArea"; @@ -15,8 +24,7 @@ import TextArea from "antd/es/input/TextArea"; import {getSessionId} from "../../../libs/getSessionId.ts"; import {AiProChat, ChatMessage} from "../../../components/AiProChat/AiProChat"; import {PluginModal} from "./Plugins.tsx"; import {PluginsModal} from "./PluginsModal.tsx"; const colStyle: React.CSSProperties = { background: '#fafafa', padding: '8px', @@ -168,9 +176,9 @@ const {doRemove: doRemoveAiBotWorkflow} = useRemove("aiBotWorkflow"); const [workflowOpen, setWorkflowOpen] = useState(false) const {result: pluginResult, doGet: doGetPlugin} = useList("aiBotPlugins", {"botId": params.id}); const {doSave: doSavePlugin} = useSave("aiBotPlugins"); const {doRemove: doRemovePlugin} = useRemove("aiBotPlugins"); const {doPost: doPostPluginTool, result: pluginResult} = usePost('/api/v1/aiPluginTool/tool/list') const {doPost: doRemovePluginTool} = usePostManual('/api/v1/aiBotPlugins/doRemove') const [pluginOpen, setPluginOpen] = useState(false) @@ -189,12 +197,25 @@ botId: params.id, sessionId: getSessionId() }); console.log('pluginResult') console.log(pluginResult) const [pluginToolData, setPluginToolData] = useState([]) useEffect(() => { setChats(messageResult?.data) }, [messageResult]); useEffect(() => { doPostPluginTool({data: {botId: params.id}}).then(r => { console.log('ssssdfsdfadsf') console.log(r) setPluginToolData(r?.data?.data) console.log('pluginToolData') console.log(pluginToolData) }) }, []); const {doPost: doPostGetPluginsList, result: resultPlugins} = usePostManual(('/api/v1/aiPlugin/getList')) const handleToolExecute = async (pluginId: string, toolId: string, params: Record<string, any>) => { console.log('执行工具:', { pluginId, toolId, params }); // 这里调用实际API }; return ( <> <WorkflowsModal open={workflowOpen} onClose={() => setWorkflowOpen(false)} @@ -211,18 +232,12 @@ }} /> <PluginModal open={pluginOpen} onClose={() => setPluginOpen(false)} onCancel={() => setPluginOpen(false)} goToPage={"/ai/plugins"} onSelectedItem={item => { setPluginOpen(false) doSavePlugin({ data: { botId: params.id, pluginId: item.id, } }).then(doGetPlugin) }} <PluginsModal open={pluginOpen} onCancel={() => setPluginOpen(false)} params={params} plugins={resultPlugins?.data} onToolExecute={handleToolExecute} /> @@ -357,21 +372,26 @@ key: 'plugins', label: <CollapseLabel text="插件" onClick={() => { setPluginOpen(true) doPostGetPluginsList({data: { botId: params.id }}) }}/>, children: <div> {pluginResult?.data?.map((item: any) => { return <ListItem key={item.id} title={item.aiPlugin.name} description={item.aiPlugin.description} icon={item.aiPlugin.icon} return <ListItem key={item.id} title={item?.name} description={item.description} icon={item?.icon} onButtonClick={() => { Modal.confirm({ title: '确定要删除该插件吗?', content: '删除后,该插件将不再关联该机器人,但插件本身不会被删除。', onOk: () => { doRemovePlugin({ data: {id: item.id} }).then(doGetPlugin) doRemovePluginTool({ data: {pluginId: item.id, botId: params.id} }).then(() =>{ doPostPluginTool({data: {botId: params.id}}) }) } }) }}