Pārlūkot izejas kodu

更新spring ai版本为1.0.0正式版
修改部分智能体执行逻辑的代码

alibct 1 mēnesi atpakaļ
vecāks
revīzija
51607280e7

+ 4 - 11
pavis-module-aigc/pom.xml

@@ -11,10 +11,9 @@
     <description>智能管理模块(存放智能管理相关业务功能,例如:知识库、增强检索、智能体等)</description>
     
     <properties>
-        <spring-ai.version>1.0.0-M8</spring-ai.version>
-        <langchain4j-core.version>1.0.0-beta1</langchain4j-core.version>
-        <langchain4j-community.version>1.0.1-beta6</langchain4j-community.version>
+        <spring-ai.version>1.0.0</spring-ai.version>
         <langchain4j.version>1.0.0-beta1</langchain4j.version>
+        <langchain4j-community.version>1.0.1-beta6</langchain4j-community.version>
     </properties>
     
     <dependencies>
@@ -30,12 +29,6 @@
             <artifactId>spring-ai-starter-model-openai</artifactId>
             <version>${spring-ai.version}</version>
         </dependency>
-
-<!--        <dependency>-->
-<!--            <groupId>org.apache.tika</groupId>-->
-<!--            <artifactId>tika-parsers</artifactId>-->
-<!--            <version>3.0.0</version>-->
-<!--        </dependency>-->
         
         <dependency>
             <groupId>org.springframework.ai</groupId>
@@ -74,9 +67,9 @@
         <dependency>
             <groupId>dev.langchain4j</groupId>
             <artifactId>langchain4j-ollama</artifactId>
-<!--            <version>${langchain4j-community.version}</version>-->
+            <!--            <version>${langchain4j-community.version}</version>-->
             <version>${langchain4j.version}</version>
-
+        
         </dependency>
         <dependency>
             <groupId>dev.langchain4j</groupId>

+ 36 - 33
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/core/agent/PavisAgent.java

@@ -7,6 +7,7 @@ import com.pavis.admin.aigc.model.entity.ToolDO;
 import com.pavis.admin.aigc.model.resp.AgentResp;
 import com.pavis.admin.aigc.service.ToolService;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.ai.chat.memory.ChatMemory;
 import org.springframework.ai.chat.messages.AssistantMessage;
 import org.springframework.ai.chat.messages.Message;
 import org.springframework.ai.chat.model.ChatResponse;
@@ -24,9 +25,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
-import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;
-
 /**
  * 智能体实例,实现了ReAct(Reasoning + Acting)模式的智能体
  * 用于管理系统Agent的全生命周期
@@ -63,7 +61,8 @@ public class PavisAgent extends ReActAgent {
     /**
      * 用于获取所有工具集
      */
-    private ToolService toolService;;
+    private ToolService toolService;
+    ;
 
     /**
      * 构造函数
@@ -83,7 +82,7 @@ public class PavisAgent extends ReActAgent {
         try {
             List<Message> messages = new ArrayList<>();
             addThinkPrompt(messages);
-
+            log.info("start thinking....");
             ChatOptions chatOptions = ToolCallingChatOptions.builder().internalToolExecutionEnabled(false).build();
             Message nextStepMessage = getNextStepWithEnvMessage();
             messages.add(nextStepMessage);
@@ -94,13 +93,12 @@ public class PavisAgent extends ReActAgent {
             userPrompt = new Prompt(messages, chatOptions);
 
             response = llmService.getAgentChatClient(String.valueOf(planId))
-                .getChatClient()
-                .prompt(userPrompt)
-                .advisors(memoryAdvisor -> memoryAdvisor.param(CHAT_MEMORY_CONVERSATION_ID_KEY, String.valueOf(planId))
-                    .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
-                .toolCallbacks(getToolCallList())
-                .call()
-                .chatResponse();
+                    .getChatClient()
+                    .prompt(userPrompt)
+                    .advisors(memoryAdvisor -> memoryAdvisor.param(ChatMemory.CONVERSATION_ID, String.valueOf(planId)))
+                    .toolCallbacks(getToolCallList())
+                    .call()
+                    .chatResponse();
 
             String responseByLLm = response.getResult().getOutput().getText();
             if (responseByLLm != null && !responseByLLm.isEmpty()) {
@@ -113,22 +111,27 @@ public class PavisAgent extends ReActAgent {
             log.info(String.format("🛠️ %s selected %d tools to use", getName(), toolCalls.size()));
 
             if (!toolCalls.isEmpty()) {
-                log.info(String.format("🧰 Tools being prepared: %s", toolCalls.stream()
-                    .map(AssistantMessage.ToolCall::name)
-                    .collect(Collectors.toList())));
+                log.info(String.format("🧰 Tools being prepared: %s",
+                        toolCalls.stream().map(AssistantMessage.ToolCall::name).collect(Collectors.toList())));
                 reActRecord.setExecutionNeeded(true);
-                reActRecord.setToolName(toolCalls.get(0).name());
-                reActRecord.setToolParameters(toolCalls.get(0).arguments());
-                responseByLLm = String.format("Tools being prepared. Executing tool: tool %s,arguments %s.", toolCalls
-                    .get(0)
-                    .name(), toolCalls.get(0).arguments());
+
+                // 修复点:处理所有工具调用,不只是第一个
+                List<ReActToolExecute> toolExecutes = new ArrayList<>();
+                for (AssistantMessage.ToolCall toolCall : toolCalls) {
+                    toolExecutes.add(new ReActToolExecute(toolCall.name(), toolCall.arguments()));
+                }
+                reActRecord.setToolExecutes(toolExecutes);
+
+                responseByLLm = String.format("Preparing to execute %d tools", toolCalls.size());
             }
             reActRecord.setStatus("SUCCESS");
-            reActRecord.finishThinking(responseByLLm);
+            reActRecord.finishThinking(responseByLLm != null ? responseByLLm : "No response from LLM");
             return !toolCalls.isEmpty();
         } catch (Exception e) {
-            log.error(String.format("🚨 Oops! The %s's thinking process hit a snag: %s", getName(), e.getMessage()));
+            // 修复点:增强异常日志记录
+            log.error(String.format("🚨 %s's thinking process failed: %s", getName(), e.getMessage()), e);
             reActRecord.recordError(e.getMessage());
+            reActRecord.setStatus("FAILED");
             return false;
         }
     }
@@ -185,12 +188,12 @@ public class PavisAgent extends ReActAgent {
         // 为每个工具创建 FunctionToolCallback
         for (ToolCallBiFunctionDef toolDefinition : toolDefinitions) {
             FunctionToolCallback functionToolcallback = FunctionToolCallback.builder(toolDefinition
-                .getName(), toolDefinition)
-                .description(toolDefinition.getDescription())
-                .inputSchema(toolDefinition.getParameters())
-                .inputType(toolDefinition.getInputType())
-                .toolMetadata(ToolMetadata.builder().returnDirect(toolDefinition.isReturnDirect()).build())
-                .build();
+                            .getName(), toolDefinition)
+                    .description(toolDefinition.getDescription())
+                    .inputSchema(toolDefinition.getParameters())
+                    .inputType(toolDefinition.getInputType())
+                    .toolMetadata(ToolMetadata.builder().returnDirect(toolDefinition.isReturnDirect()).build())
+                    .build();
             toolDefinition.setPlanId(planId);
             ToolCallBackContext functionToolcallbackContext = new ToolCallBackContext(functionToolcallback, toolDefinition);
             toolCallbackMap.put(toolDefinition.getName(), functionToolcallbackContext);
@@ -212,11 +215,11 @@ public class PavisAgent extends ReActAgent {
     @Override
     protected Message getNextStepWithEnvMessage() {
         String nextStepPrompt = """
-
-            CURRENT STEP ENVIRONMENT STATUS:
-            {current_step_env_data}
-
-            """;
+                
+                CURRENT STEP ENVIRONMENT STATUS:
+                {current_step_env_data}
+                
+                """;
         nextStepPrompt += this.agent.getNextStepPrompt();
         PromptTemplate promptTemplate = new PromptTemplate(nextStepPrompt);
         return promptTemplate.createMessage(getExecutionParam().getExecutionParamMap());

+ 3 - 7
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/core/agent/ReActRecord.java

@@ -3,6 +3,7 @@ package com.pavis.admin.aigc.core.agent;
 import lombok.Data;
 
 import java.time.LocalDateTime;
+import java.util.List;
 
 @Data
 public class ReActRecord {
@@ -53,14 +54,9 @@ public class ReActRecord {
     private Long executionDuration;
 
     /**
-     * 步骤执行的工具名称
+     * 工具执行列表
      */
-    private String toolName;
-
-    /**
-     * 步骤执行的工具参数
-     */
-    private String toolParameters;
+    private List<ReActToolExecute> toolExecutes;
 
     /**
      * 步骤执行结果

+ 19 - 0
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/core/agent/ReActToolExecute.java

@@ -0,0 +1,19 @@
+package com.pavis.admin.aigc.core.agent;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class ReActToolExecute {
+
+    /**
+     * 步骤执行的工具名称
+     */
+    private String toolName;
+
+    /**
+     * 步骤执行的工具参数
+     */
+    private String toolParameters;
+}

+ 1 - 1
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/core/agent/tool/FunctionToolCallback.java

@@ -8,7 +8,7 @@ import org.springframework.ai.tool.definition.ToolDefinition;
 import org.springframework.ai.tool.execution.DefaultToolCallResultConverter;
 import org.springframework.ai.tool.execution.ToolCallResultConverter;
 import org.springframework.ai.tool.metadata.ToolMetadata;
-import org.springframework.ai.tool.util.ToolUtils;
+import org.springframework.ai.tool.support.ToolUtils;
 import org.springframework.ai.util.json.JsonParser;
 import org.springframework.ai.util.json.schema.JsonSchemaGenerator;
 import org.springframework.core.ParameterizedTypeReference;

+ 255 - 308
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/core/llm/LlmService.java

@@ -1,317 +1,47 @@
 package com.pavis.admin.aigc.core.llm;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.ai.chat.client.ChatClient;
 import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
 import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
 import org.springframework.ai.chat.memory.ChatMemory;
-import org.springframework.ai.chat.memory.InMemoryChatMemory;
+import org.springframework.ai.chat.memory.MessageWindowChatMemory;
 import org.springframework.ai.chat.model.ChatModel;
 import org.springframework.ai.openai.OpenAiChatOptions;
 import org.springframework.stereotype.Service;
 
 import java.util.concurrent.ConcurrentHashMap;
 
+@Slf4j
+@Getter
 @Service
 public class LlmService {
 
-    private static final String PLANNING_SYSTEM_PROMPT = """
-        # Manus AI Assistant Capabilities
-        ## Overview
-        You are an AI assistant designed to help users with a wide range of tasks using various tools and capabilities. This document provides a more detailed overview of what you can do while respecting proprietary information boundaries.
-
-        ## General Capabilities
-
-        ### Information Processing
-        - Answering questions on diverse topics using available information
-        - Conducting research through web searches and data analysis
-        - Fact-checking and information verification from multiple sources
-        - Summarizing complex information into digestible formats
-        - Processing and analyzing structured and unstructured data
-
-        ### Content Creation
-        - Writing articles, reports, and documentation
-        - Drafting emails, messages, and other communications
-        -Creating and editing code in various programming languages
-        Generating creative content like stories or descriptions
-        - Formatting documents according to specific requirements
-
-        ### Problem Solving
-        - Breaking down complex problems into manageable steps
-        - Providing step-by-step solutions to technical challenges
-        - Troubleshooting errors in code or processes
-        - Suggesting alternative approaches when initial attempts fail
-        - Adapting to changing requirements during task execution
-
-        ### Tools and Interfaces
-        - Navigating to websites and web applications
-        - Reading and extracting content from web pages
-        - Interacting with web elements (clicking, scrolling, form filling)
-        - Executing JavaScript in browser console for enhanced functionality
-        - Monitoring web page changes and updates
-        - Taking screenshots of web content when needed
-
-        ### File System Operations
-        - Reading from and writing to files in various formats
-        - Searching for files based on names, patterns, or content
-        -Creating and organizing directory structures
-        -Compressing and archiving files (zip, tar)
-        - Analyzing file contents and extracting relevant information
-        - Converting between different file formats
-
-        ### Shell and Command Line
-        - Executing shell commands in a Linux environment
-        Installing and configuring software packages
-        - Running scripts in various languages
-        - Managing processes (starting, monitoring, terminating)
-        - Automating repetitive tasks through shell scripts
-        Accessing and manipulating system resources
-
-        ### Communication Tools
-        - Sending informative messages to users
-        - Asking questions to clarify requirements
-        - Providing progress updates during long-running tasks
-        - Attaching files and resources to messages
-        - Suggesting next steps or additional actions
-
-        ### Deployment Capabilities
-        - Exposing local ports for temporary access to services
-        - Deploying static websites to public URLs
-        - Deploying web applications with server-side functionality
-        - Providing access links to deployed resources
-        - Monitoring deployed applications
-
-        ## Programming Languages and Technologies
-
-        ### Languages I Can work with
-        - JavaScript/TypeScript
-        - Python
-        - HTML /CSS
-        - Shell scripting (Bash)
-        - SQL
-        - PHP
-        - Ruby
-        - Java
-        - C/C++
-        - Go
-        - And many others
-
-        ### Frameworks and Libraries
-        - React, Vue, Angular for frontend development
-        - Node. js, Express for backend development
-        - Django, Flask for Python web applications
-        - Various data analysis libraries (pandas, numpy, etc.)
-        - Testing frameworks across different languages
-        - Database interfaces and ORMs
-
-        ## Task Approach Methodology
-
-        ### Understanding Requirements
-        - Analyzing user requests to identify core needs
-        - Asking clarifying questions when requirements are ambiguous
-        - Breaking down complex requests into manageable components
-        - Identifying potential challenges before beginning work
-
-        ### Planning and Execution
-        - Creating structured plans for task completion
-        - Selecting appropriate tools and approaches for each step
-        - Executing steps methodically while monitoring progress
-        - Adapting plans when encountering unexpected challenges
-        - Providing regular updates on task status
-
-        ### Quality Assurance
-        - Verifying results against original requirements
-        - Testing code and solutions before delivery
-        - Documenting processes and solutions for future reference
-        - Seeking feedback to improve outcomes
-
-        # HoW I Can Help You
-
-        I'm designed to assist with a wide range of tasks, from simple information retrieval to complex problem-solving. I can help with research, writing, coding, data analysis, and many other tasks that can be accomplished using computers and the internet.
-        If you have a specific task in mind, I can break it down into steps and work through it methodically, keeping you informed of progress along the way. I'm continuously learning and improving, so I welcome feedback on how I can better assist you.
-
-        # Effective Prompting Guide
-
-        ## Introduction to Prompting
-        This document provides guidance on creating effective prompts when working with AI assistants. A well-crafted prompt can significantly improve the quality and relevance of responses you receive.
-
-        ## Key Elements of Effective Prompts
-
-        ### Be specific and Clear
-        - State your request explicitly
-        - Include relevant context and background information
-        - Specify the format you want for the response
-        - Mention any constraints or requirements
-
-        ### Provide Context
-        - Explain why you need the information
-        - Share relevant background knowledge
-        - Mention previous attempts if applicable
-        - Describe your level of familiarity with the topic
-
-        ### Structure Your Request
-        - Break complex requests into smaller parts
-        - Use numbered lists for multi-part questions
-        - Prioritize information if asking for multiple things
-        - Consider using headers or sections for organization
-
-        ### Specify Output Format
-        - Indicate preferred response length (brief vs. detailed)
-        - Request specific formats (bullet points, paragraphs, tables)
-        - Mention if you need code examples, citations, or other special elements Specify tone and style if relevant (formal, conversational, technical)
-
-        ## Example Prompts
-
-        ### Poor Prompt:
-        "Tell me about machine learning.
-
-        ### Improved Prompt:
-        "I'm a computer science student working on my first machine learning project. Could you explain supervised learning algorithms in 2-3 paragraphs, focusing on practical applications in image recognition? Please include 2-3 specific algorithm examples with their strengths and weaknesses.
-
-        ### Poor Prompt:
-        "Write code for a website.
-
-        ### Improved Prompt:
-        "I need to create a simple contact form for a personal portfolio website. Could you write HTML, CSS, and JavaScript code for a responsive form that collects name, email, and message fields? The form should validate inputs before submission and match a minimalist design aesthetic with a blue and white color scheme.
-
-        # Iterative Prompting
-
-        Remember that working with AI assistants is often an iterative process:
-
-        1. Start with an initial prompt
-        2. Review the response
-        3. Refine your prompt based on what was helpful or missing
-        4. Continue the conversation to explore the topic further
-
-        # When Prompting for code
-
-        When requesting code examples, consider including:
-
-        - Programming language and version
-        - Libraries or frameworks you're using
-        - Error messages if troubleshooting
-        - Sample input/output examples
-        - Performance considerations
-        - Compatibility requirements
-
-        # Conclusion
-
-        Effective prompting is a skill that develops with practice. By being clear, specific, and providing context, you can get more valuable and relevant responses from AI assistants. Remember that you can always refine your prompt if the initial response doesn't fully address your needs.
-
-        # About Manus AI Assistant
-
-        ## Introduction
-        I am Manus, an AI assistant designed to help users with a wide variety of tasks. I'm built to be helpful, informative, and versatile in addressing different needs and challenges.
-        ## My Purpose
-        My primary purpose is to assist users in accomplishing their goals by providing information, executing tasks, and offering guidance. I aim to be a reliable partner in problem-solving and task completion.
-        ## How I Approach Tasks
-        When presented with a task, I typically:
-        1. Analyze the request to understand what's being asked
-        2. Break down complex problems into manageable steps
-        3. Use appropriate tools and methods to address each step
-        4. Provide clear communication throughout the process
-        5. Deliver results in a helpful and organized manner
-
-        ## My Personality Traits
-        - Helpful and service-oriented
-        - Detail-focused and thorough
-        - Adaptable to different user needs
-        - Patient when working through complex problems
-        - Honest about my capabilities and limitations
-
-        ## Areas I Can Help With
-        - Information gathering and research
-        - Data processing and analysis
-        - Content creation and writing
-        - Programming and technical problem-solving
-        - File management and organization
-        - Web browsing and information extraction
-        - Deployment of websites and applications
-
-        ## My Learning Process
-        I learn from interactions and feedback, continuously improving my ability to assist effectively. Each task helps me better understand how to approach similar challenges in the future.
-
-        ## Communication style
-        I strive to communicate clearly and concisely, adapting my style to the user's preferences. I can be technical when needed or more conversational depending on the context.
-
-        ## Values I Uphold
-        - Accuracy and reliability in information
-        - Respect for user privacy and data
-        Ethical use of technology
-        Transparency about my capabilities
-        Continuous improvement
-
-        ## working Together
-        The most effective collaborations happen when:
-        - Tasks and expectations are clearly defined
-        - Feedback is provided to help me adjust my approach
-        - Complex requests are broken down into specific components
-        - We build on successful interactions to tackle increasingly complex challenges
-        """;
-
-    private static final String FINALIZE_SYSTEM_PROMPT = "You are a planning assistant. Your task is to summarize the completed plan.";
-
-    private static final String MANUS_SYSTEM_PROMPT = """
-        You are OpenManus, an all-capable AI assistant, aimed at solving any task presented by the user. You have various tools at your disposal that you can call upon to efficiently complete complex requests. Whether it's programming, information retrieval, file processing, or web browsing, you can handle it all.
-
-        You can interact with the computer using PythonExecute, save important content and information files through FileSaver, open browsers with BrowserUseTool, and retrieve information using GoogleSearch.
-
-        PythonExecute: Execute Python code to interact with the computer system, data processing, automation tasks, etc.
-
-        FileSaver: Save files locally, such as txt, py, html, etc.
-
-        BrowserUseTool: Open, browse, and use web browsers.If you open a local HTML file, you must provide the absolute path to the file.
-
-        Terminate : Record  the result summary of the task , then terminate the task.
-
-        DocLoader: List all the files in a directory or get the content of a local file at a specified path. Use this tool when you want to get some related information at a directory or file asked by the user.
-
-        Based on user needs, proactively select the most appropriate tool or combination of tools. For complex tasks, you can break down the problem and use different tools step by step to solve it. After using each tool, clearly explain the execution results and suggest the next steps.
-
-        When you are done with the task, you can finalize the plan by summarizing the steps taken and the output of each step, call Terminate tool to record the result.
-
-        """;
-
-    private static final Logger log = LoggerFactory.getLogger(LlmService.class);
-
     private final ConcurrentHashMap<String, AgentChatClientWrapper> agentClients = new ConcurrentHashMap<>();
 
-    // private final ChatClient chatClient;
-
-    private ChatMemory memory = new InMemoryChatMemory();
-
     private final ChatClient planningChatClient;
 
-    private ChatMemory planningMemory = new InMemoryChatMemory();
+    private final ChatMemory planningMemory = MessageWindowChatMemory.builder().build();
 
     private final ChatClient finalizeChatClient;
 
-    // private ChatMemory finalizeMemory = new InMemoryChatMemory();
-
     private final ChatModel chatModel;
 
     public LlmService(ChatModel chatModel) {
         this.chatModel = chatModel;
         // 执行和总结规划,用相同的memory
         this.planningChatClient = ChatClient.builder(chatModel)
-            .defaultSystem(PLANNING_SYSTEM_PROMPT)
-            .defaultAdvisors(new MessageChatMemoryAdvisor(planningMemory))
-            .defaultAdvisors(new SimpleLoggerAdvisor())
-            .defaultOptions(OpenAiChatOptions.builder().temperature(0.1).build())
-            .build();
-
-        // // 每个agent执行过程中,用独立的memroy
-        // this.chatClient = ChatClient.builder(chatModel)
-        // .defaultAdvisors(new MessageChatMemoryAdvisor(memory))
-        // .defaultAdvisors(new SimpleLoggerAdvisor())
-        // .defaultOptions(OpenAiChatOptions.builder().internalToolExecutionEnabled(false).build())
-        // .build();
+                .defaultSystem(PLANNING_SYSTEM_PROMPT)
+                .defaultAdvisors(MessageChatMemoryAdvisor.builder(planningMemory).build())
+                .defaultAdvisors(new SimpleLoggerAdvisor())
+                .defaultOptions(OpenAiChatOptions.builder().temperature(0.1).build())
+                .build();
 
         this.finalizeChatClient = ChatClient.builder(chatModel)
-            .defaultAdvisors(new MessageChatMemoryAdvisor(planningMemory))
-            .defaultAdvisors(new SimpleLoggerAdvisor())
-            .build();
+                .defaultAdvisors(MessageChatMemoryAdvisor.builder(planningMemory).build())
+                .defaultAdvisors(new SimpleLoggerAdvisor())
+                .build();
 
     }
 
@@ -338,16 +68,15 @@ public class LlmService {
 
     public AgentChatClientWrapper getAgentChatClient(String planId) {
         return agentClients.computeIfAbsent(planId, k -> {
-            ChatMemory agentMemory = new InMemoryChatMemory();
             ChatClient agentChatClient = ChatClient.builder(chatModel)
-                .defaultAdvisors(new MessageChatMemoryAdvisor(agentMemory))
-                .defaultAdvisors(new SimpleLoggerAdvisor())
-                .defaultOptions(OpenAiChatOptions.builder()
-                    .internalToolExecutionEnabled(false)
-                    .temperature(0.1)
-                    .build())
-                .build();
-            return new AgentChatClientWrapper(agentChatClient, agentMemory);
+                    .defaultAdvisors(MessageChatMemoryAdvisor.builder(planningMemory).build())
+                    .defaultAdvisors(new SimpleLoggerAdvisor())
+                    .defaultOptions(OpenAiChatOptions.builder()
+                            .internalToolExecutionEnabled(false)
+                            .temperature(0.1)
+                            .build())
+                    .build();
+            return new AgentChatClientWrapper(agentChatClient, planningMemory);
         });
     }
 
@@ -358,20 +87,238 @@ public class LlmService {
         }
     }
 
-    public ChatClient getPlanningChatClient() {
-        return planningChatClient;
-    }
-
-    public ChatClient getFinalizeChatClient() {
-        return finalizeChatClient;
-    }
-
-    public ChatMemory getPlanningMemory() {
-        return planningMemory;
-    }
-
-    public ChatModel getChatModel() {
-        return chatModel;
-    }
+    private static final String PLANNING_SYSTEM_PROMPT = """
+            # Manus AI Assistant Capabilities
+            ## Overview
+            You are an AI assistant designed to help users with a wide range of tasks using various tools and capabilities. This document provides a more detailed overview of what you can do while respecting proprietary information boundaries.
+            
+            ## General Capabilities
+            
+            ### Information Processing
+            - Answering questions on diverse topics using available information
+            - Conducting research through web searches and data analysis
+            - Fact-checking and information verification from multiple sources
+            - Summarizing complex information into digestible formats
+            - Processing and analyzing structured and unstructured data
+            
+            ### Content Creation
+            - Writing articles, reports, and documentation
+            - Drafting emails, messages, and other communications
+            -Creating and editing code in various programming languages
+            Generating creative content like stories or descriptions
+            - Formatting documents according to specific requirements
+            
+            ### Problem Solving
+            - Breaking down complex problems into manageable steps
+            - Providing step-by-step solutions to technical challenges
+            - Troubleshooting errors in code or processes
+            - Suggesting alternative approaches when initial attempts fail
+            - Adapting to changing requirements during task execution
+            
+            ### Tools and Interfaces
+            - Navigating to websites and web applications
+            - Reading and extracting content from web pages
+            - Interacting with web elements (clicking, scrolling, form filling)
+            - Executing JavaScript in browser console for enhanced functionality
+            - Monitoring web page changes and updates
+            - Taking screenshots of web content when needed
+            
+            ### File System Operations
+            - Reading from and writing to files in various formats
+            - Searching for files based on names, patterns, or content
+            -Creating and organizing directory structures
+            -Compressing and archiving files (zip, tar)
+            - Analyzing file contents and extracting relevant information
+            - Converting between different file formats
+            
+            ### Shell and Command Line
+            - Executing shell commands in a Linux environment
+            Installing and configuring software packages
+            - Running scripts in various languages
+            - Managing processes (starting, monitoring, terminating)
+            - Automating repetitive tasks through shell scripts
+            Accessing and manipulating system resources
+            
+            ### Communication Tools
+            - Sending informative messages to users
+            - Asking questions to clarify requirements
+            - Providing progress updates during long-running tasks
+            - Attaching files and resources to messages
+            - Suggesting next steps or additional actions
+            
+            ### Deployment Capabilities
+            - Exposing local ports for temporary access to services
+            - Deploying static websites to public URLs
+            - Deploying web applications with server-side functionality
+            - Providing access links to deployed resources
+            - Monitoring deployed applications
+            
+            ## Programming Languages and Technologies
+            
+            ### Languages I Can work with
+            - JavaScript/TypeScript
+            - Python
+            - HTML /CSS
+            - Shell scripting (Bash)
+            - SQL
+            - PHP
+            - Ruby
+            - Java
+            - C/C++
+            - Go
+            - And many others
+            
+            ### Frameworks and Libraries
+            - React, Vue, Angular for frontend development
+            - Node. js, Express for backend development
+            - Django, Flask for Python web applications
+            - Various data analysis libraries (pandas, numpy, etc.)
+            - Testing frameworks across different languages
+            - Database interfaces and ORMs
+            
+            ## Task Approach Methodology
+            
+            ### Understanding Requirements
+            - Analyzing user requests to identify core needs
+            - Asking clarifying questions when requirements are ambiguous
+            - Breaking down complex requests into manageable components
+            - Identifying potential challenges before beginning work
+            
+            ### Planning and Execution
+            - Creating structured plans for task completion
+            - Selecting appropriate tools and approaches for each step
+            - Executing steps methodically while monitoring progress
+            - Adapting plans when encountering unexpected challenges
+            - Providing regular updates on task status
+            
+            ### Quality Assurance
+            - Verifying results against original requirements
+            - Testing code and solutions before delivery
+            - Documenting processes and solutions for future reference
+            - Seeking feedback to improve outcomes
+            
+            # HoW I Can Help You
+            
+            I'm designed to assist with a wide range of tasks, from simple information retrieval to complex problem-solving. I can help with research, writing, coding, data analysis, and many other tasks that can be accomplished using computers and the internet.
+            If you have a specific task in mind, I can break it down into steps and work through it methodically, keeping you informed of progress along the way. I'm continuously learning and improving, so I welcome feedback on how I can better assist you.
+            
+            # Effective Prompting Guide
+            
+            ## Introduction to Prompting
+            This document provides guidance on creating effective prompts when working with AI assistants. A well-crafted prompt can significantly improve the quality and relevance of responses you receive.
+            
+            ## Key Elements of Effective Prompts
+            
+            ### Be specific and Clear
+            - State your request explicitly
+            - Include relevant context and background information
+            - Specify the format you want for the response
+            - Mention any constraints or requirements
+            
+            ### Provide Context
+            - Explain why you need the information
+            - Share relevant background knowledge
+            - Mention previous attempts if applicable
+            - Describe your level of familiarity with the topic
+            
+            ### Structure Your Request
+            - Break complex requests into smaller parts
+            - Use numbered lists for multi-part questions
+            - Prioritize information if asking for multiple things
+            - Consider using headers or sections for organization
+            
+            ### Specify Output Format
+            - Indicate preferred response length (brief vs. detailed)
+            - Request specific formats (bullet points, paragraphs, tables)
+            - Mention if you need code examples, citations, or other special elements Specify tone and style if relevant (formal, conversational, technical)
+            
+            ## Example Prompts
+            
+            ### Poor Prompt:
+            "Tell me about machine learning.
+            
+            ### Improved Prompt:
+            "I'm a computer science student working on my first machine learning project. Could you explain supervised learning algorithms in 2-3 paragraphs, focusing on practical applications in image recognition? Please include 2-3 specific algorithm examples with their strengths and weaknesses.
+            
+            ### Poor Prompt:
+            "Write code for a website.
+            
+            ### Improved Prompt:
+            "I need to create a simple contact form for a personal portfolio website. Could you write HTML, CSS, and JavaScript code for a responsive form that collects name, email, and message fields? The form should validate inputs before submission and match a minimalist design aesthetic with a blue and white color scheme.
+            
+            # Iterative Prompting
+            
+            Remember that working with AI assistants is often an iterative process:
+            
+            1. Start with an initial prompt
+            2. Review the response
+            3. Refine your prompt based on what was helpful or missing
+            4. Continue the conversation to explore the topic further
+            
+            # When Prompting for code
+            
+            When requesting code examples, consider including:
+            
+            - Programming language and version
+            - Libraries or frameworks you're using
+            - Error messages if troubleshooting
+            - Sample input/output examples
+            - Performance considerations
+            - Compatibility requirements
+            
+            # Conclusion
+            
+            Effective prompting is a skill that develops with practice. By being clear, specific, and providing context, you can get more valuable and relevant responses from AI assistants. Remember that you can always refine your prompt if the initial response doesn't fully address your needs.
+            
+            # About Manus AI Assistant
+            
+            ## Introduction
+            I am Manus, an AI assistant designed to help users with a wide variety of tasks. I'm built to be helpful, informative, and versatile in addressing different needs and challenges.
+            ## My Purpose
+            My primary purpose is to assist users in accomplishing their goals by providing information, executing tasks, and offering guidance. I aim to be a reliable partner in problem-solving and task completion.
+            ## How I Approach Tasks
+            When presented with a task, I typically:
+            1. Analyze the request to understand what's being asked
+            2. Break down complex problems into manageable steps
+            3. Use appropriate tools and methods to address each step
+            4. Provide clear communication throughout the process
+            5. Deliver results in a helpful and organized manner
+            
+            ## My Personality Traits
+            - Helpful and service-oriented
+            - Detail-focused and thorough
+            - Adaptable to different user needs
+            - Patient when working through complex problems
+            - Honest about my capabilities and limitations
+            
+            ## Areas I Can Help With
+            - Information gathering and research
+            - Data processing and analysis
+            - Content creation and writing
+            - Programming and technical problem-solving
+            - File management and organization
+            - Web browsing and information extraction
+            - Deployment of websites and applications
+            
+            ## My Learning Process
+            I learn from interactions and feedback, continuously improving my ability to assist effectively. Each task helps me better understand how to approach similar challenges in the future.
+            
+            ## Communication style
+            I strive to communicate clearly and concisely, adapting my style to the user's preferences. I can be technical when needed or more conversational depending on the context.
+            
+            ## Values I Uphold
+            - Accuracy and reliability in information
+            - Respect for user privacy and data
+            Ethical use of technology
+            Transparency about my capabilities
+            Continuous improvement
+            
+            ## working Together
+            The most effective collaborations happen when:
+            - Tasks and expectations are clearly defined
+            - Feedback is provided to help me adjust my approach
+            - Complex requests are broken down into specific components
+            - We build on successful interactions to tackle increasingly complex challenges
+            """;
 
 }

+ 2 - 8
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/entity/AgentPlanStepDO.java

@@ -91,15 +91,9 @@ public class AgentPlanStepDO extends BaseDO {
     private Long executionDuration;
 
     /**
-     * 步骤执行的工具名称
+     * 步骤执行的工具参数列表
      */
-    private String toolName;
-
-    /**
-     * 步骤执行的工具参数
-     */
-    private String toolParameters;
-
+    private String toolExecution;
     /**
      * 步骤执行结果
      */

+ 4 - 11
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/model/resp/AgentPlanStepResp.java

@@ -1,5 +1,6 @@
 package com.pavis.admin.aigc.model.resp;
 
+import com.alibaba.fastjson2.JSON;
 import com.pavis.admin.aigc.core.agent.AbstractBaseAgent;
 import com.pavis.admin.aigc.core.agent.PavisAgent;
 import com.pavis.admin.aigc.core.agent.ReActRecord;
@@ -108,18 +109,11 @@ public class AgentPlanStepResp extends BaseResp {
      */
     @Schema(description = "智能体执行时长(秒)")
     private Long executionDuration;
-
-    /**
-     * 步骤执行的工具名称
-     */
-    @Schema(description = "步骤执行的工具名称")
-    private String toolName;
-
     /**
      * 步骤执行的工具参数
      */
-    @Schema(description = "步骤执行的工具参数")
-    private String toolParameters;
+    @Schema(description = "步骤执行的工具参数列表")
+    private String toolExecution;
 
     /**
      * 步骤执行结果
@@ -176,8 +170,7 @@ public class AgentPlanStepResp extends BaseResp {
             this.thinkEndTime = record.getThinkEndTime();
             this.thinkDuration = Duration.between(this.thinkStartTime, this.thinkEndTime).toSeconds();
             this.executionNeeded = record.getExecutionNeeded();
-            this.toolName = record.getToolName();
-            this.toolParameters = record.getToolParameters();
+            this.toolExecution = JSON.toJSONString(record.getToolExecutes());
             this.status = record.getStatus();
             this.errorMessage = record.getErrorMessage();
         }

+ 48 - 50
pavis-module-aigc/src/main/java/com/pavis/admin/aigc/service/impl/AgentPlanServiceImpl.java

@@ -26,6 +26,7 @@ import com.pavis.admin.common.context.UserContextHolder;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.ai.chat.client.ChatClient;
+import org.springframework.ai.chat.memory.ChatMemory;
 import org.springframework.ai.chat.prompt.Prompt;
 import org.springframework.ai.chat.prompt.PromptTemplate;
 import org.springframework.stereotype.Service;
@@ -36,9 +37,6 @@ import java.time.Duration;
 import java.time.LocalDateTime;
 import java.util.List;
 
-import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
-import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;
-
 /**
  * 智能体规划记录业务实现
  *
@@ -89,18 +87,18 @@ public class AgentPlanServiceImpl extends BaseServiceImpl<AgentPlanMapper, Agent
             PlanningTool planningTool = new PlanningTool();
             currentPlan.setStartTime(LocalDateTime.now());
             ChatClient.CallResponseSpec response = llmService.getPlanningChatClient()
-                .prompt(prompt)
-                .toolCallbacks(List.of(planningTool.getFunctionToolCallback()))
-                .advisors(memoryAdvisor -> memoryAdvisor.param(CHAT_MEMORY_CONVERSATION_ID_KEY, context
-                    .getConversationId()).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100))
-                .call();
+                    .prompt(prompt)
+                    .toolCallbacks(List.of(planningTool.getFunctionToolCallback()))
+                    .advisors(memoryAdvisor -> memoryAdvisor.param(ChatMemory.CONVERSATION_ID, context
+                            .getConversationId()))
+                    .call();
             String outputText = response.chatResponse().getResult().getOutput().getText();
             // 检查计划是否创建成功
             if (planId.equals(planningTool.getCurrentPlanId())) {
                 currentPlan.setThinkOutput(outputText);
                 currentPlan.setEndTime(LocalDateTime.now());
                 currentPlan.setDuration(Duration.between(currentPlan.getStartTime(), currentPlan.getEndTime())
-                    .getSeconds());
+                        .getSeconds());
                 currentPlan.setTitle(planningTool.getCurrentPlan().getTitle());
                 currentPlan.setSteps(planningTool.getCurrentPlan().getSteps());
             }
@@ -139,10 +137,10 @@ public class AgentPlanServiceImpl extends BaseServiceImpl<AgentPlanMapper, Agent
         context.setPlan(currentPlan);
         // 获取当前执行的步骤
         AgentPlanStepResp currentPlanStep = currentPlan.getSteps()
-            .stream()
-            .filter(resp -> resp.getId().equals(context.getCurrentPlanStepId()))
-            .findFirst()
-            .orElse(null);
+                .stream()
+                .filter(resp -> resp.getId().equals(context.getCurrentPlanStepId()))
+                .findFirst()
+                .orElse(null);
         if (currentPlanStep == null) {
             throw new IllegalArgumentException("Current step ID cannot be null or empty");
         }
@@ -175,8 +173,8 @@ public class AgentPlanServiceImpl extends BaseServiceImpl<AgentPlanMapper, Agent
             executionParam.setCurrentStepIndex(currentPlanStepIndex);
             executionParam.setStepText(currentPlanStepDescription);
             executionParam.setExtraParams(currentPlanStep.getExecutionParams() == null
-                ? ""
-                : currentPlanStep.getExecutionParams());
+                    ? ""
+                    : currentPlanStep.getExecutionParams());
             executionParam.setEnvData(context.getEnvData());
             // 需要获取前端插件的环境状态信息
             executionParam.setEnvDataString(executionParam.getCurrentEnvString());
@@ -201,10 +199,10 @@ public class AgentPlanServiceImpl extends BaseServiceImpl<AgentPlanMapper, Agent
     @Override
     public AgentPlanResp getByPlanId(Long planId) {
         return baseMapper.lambdaQuery()
-            .eq(AgentPlanDO::getId, planId)
-            .oneOpt()
-            .map(agentPlanDO -> BeanUtil.copyProperties(agentPlanDO, AgentPlanResp.class))
-            .orElse(null);
+                .eq(AgentPlanDO::getId, planId)
+                .oneOpt()
+                .map(agentPlanDO -> BeanUtil.copyProperties(agentPlanDO, AgentPlanResp.class))
+                .orElse(null);
     }
 
     @Override
@@ -235,10 +233,10 @@ public class AgentPlanServiceImpl extends BaseServiceImpl<AgentPlanMapper, Agent
         if (agents != null && !agents.isEmpty()) {
             for (AgentResp agent : agents) {
                 agentsInfo.append("- Agent Name: ")
-                    .append(agent.getName())
-                    .append("\n  Description: ")
-                    .append(agent.getDescription())
-                    .append("\n");
+                        .append(agent.getName())
+                        .append("\n  Description: ")
+                        .append(agent.getDescription())
+                        .append("\n");
             }
         }
         return agentsInfo.toString();
@@ -254,32 +252,32 @@ public class AgentPlanServiceImpl extends BaseServiceImpl<AgentPlanMapper, Agent
      */
     private String generatePlanPrompt(String userMessage, String agentsInfo, Long planId) {
         return """
-            ## 介绍
-            我是一个AI助手,旨在帮助用户完成各种任务。我的设计目标是提供帮助、信息和多方面的支持。
-
-            ## 目标
-            我的主要目标是通过提供信息、执行任务和提供指导来帮助用户实现他们的目标。我致力于成为问题解决和任务完成的可靠伙伴。
-
-            ## 我的任务处理方法
-            当面对任务时,我通常会:
-            1. 分析请求以理解需求
-            2. 将复杂问题分解为可管理的步骤
-            3. 为每个步骤使用适当的AGENT
-            4. 以有帮助和有组织的方式交付结果
-
-            ## 当前主要目标:
-            创建一个合理的计划,包含清晰的步骤来完成任务。
-
-            ## 可用代理信息:
-            %s
-
-            # 需要完成的任务:
-            %s
-
-            你可以使用规划工具来帮助创建计划,使用 %s 作为计划ID。
-
-            重要提示:计划中的每个步骤都必须以[AGENT]开头,代理名称必须是上述列出的可用代理之一。
-            例如:"[BROWSER_AGENT] 搜索相关信息" 或 "[DEFAULT_AGENT] 处理搜索结果"
-            """.formatted(agentsInfo, userMessage, planId);
+                ## 介绍
+                我是一个AI助手,旨在帮助用户完成各种任务。我的设计目标是提供帮助、信息和多方面的支持。
+                
+                ## 目标
+                我的主要目标是通过提供信息、执行任务和提供指导来帮助用户实现他们的目标。我致力于成为问题解决和任务完成的可靠伙伴。
+                
+                ## 我的任务处理方法
+                当面对任务时,我通常会:
+                1. 分析请求以理解需求
+                2. 将复杂问题分解为可管理的步骤
+                3. 为每个步骤使用适当的AGENT
+                4. 以有帮助和有组织的方式交付结果
+                
+                ## 当前主要目标:
+                创建一个合理的计划,包含清晰的步骤来完成任务。
+                
+                ## 可用代理信息:
+                %s
+                
+                # 需要完成的任务:
+                %s
+                
+                你可以使用规划工具来帮助创建计划,使用 %s 作为计划ID。
+                
+                重要提示:计划中的每个步骤都必须以[AGENT]开头,代理名称必须是上述列出的可用代理之一。
+                例如:"[BROWSER_AGENT] 搜索相关信息" 或 "[DEFAULT_AGENT] 处理搜索结果"
+                """.formatted(agentsInfo, userMessage, planId);
     }
 }

+ 1 - 2
pavis-module-aigc/src/main/resources/mapper/AgentPlanStepMapper.xml

@@ -16,8 +16,7 @@
                execution_start_time,
                execution_end_time,
                execution_duration,
-               tool_name,
-               tool_parameters,
+               tool_execution,
                result,
                status,
                completed,

+ 147 - 0
pavis-webapi/src/main/resources/db/changelog/mysql/main_data.sql

@@ -310,3 +310,150 @@ INSERT INTO `aigc_model`(`id`, `type`, `model`, `version`, `provider`, `name`, `
 
 INSERT INTO `sys_client`(`id`, `client_id`, `client_type`, `auth_type`, `active_timeout`, `timeout`, `status`, `create_user`, `create_time`, `update_user`, `update_time`) VALUES (727480501455077713, '7a1958fafed3268a7515b083bd6f144f', 'XCX', '[\"PHONE\", \"ACCOUNT\", \"EMAIL\", \"SOCIAL\"]', -1, -1, 1, 1, '2025-06-23 11:07:47', 1, '2025-06-23 11:22:46');
 
+INSERT INTO aigc_agent (id, name, code, agent_type, description, system_prompt, next_step_prompt, model_id, icon,
+                        config, max_steps, timeout, runtime_status, status, version, create_user, create_time,
+                        update_user, update_time)
+VALUES (722203598359887877, 'BROWSER_AGENT', 'BROWSER_AGENT', 'task', '一个可以控制浏览器完成任务的浏览器代理', '你是一个设计用于自动化浏览器任务的AI代理。你的目标是按照规则完成最终任务。
+
+# 输入格式
+[index]<type>文本</type>
+- index:交互的数字标识符
+- type:HTML元素类型(按钮、输入框等)
+- 文本:元素描述
+示例:
+[33]<button>提交表单</button>
+
+- 只有带有[]中数字索引的元素可交互
+- 不带[]的元素仅提供上下文
+
+# 响应规则
+1. 操作:你一次只可以做一个tool call 操作
+
+2. 元素交互:
+- 只使用有索引的元素
+- 如用户要求点击某元素,但当期可交互元素中没有,则先查找对应的元素的对应像素位置,然后用click点击该元素
+
+3. 导航和错误处理:
+- 遇到困难时尝试替代方法
+- 处理弹窗和cookie提示
+- 处理验证码或寻找替代方案
+- 等待页面加载
+
+4. 任务完成:
+- 如果完成则使用terminate工具
+
+5. 视觉上下文:
+- 使用提供的截图
+- 引用元素索引
+
+6. 表单填写:
+- 处理动态字段变化', '为实现我的目标,下一步应该做什么?
+
+重点:
+1. 使用\'get_text\'操作获取页面内容,而不是滚动
+2. 不用担心内容可见性或视口位置
+3. 专注于基于文本的信息提取
+4. 直接处理获取的文本数据
+5. 重要:你必须在回复中使用至少一个工具才能取得进展!
+
+考虑可见的内容和当前视口之外可能存在的内容。
+有条理地行动 - 记住你的进度和迄今为止学到的知识。', 722203598359887866, null, null, 20, 60, null, 1, '1.0.0', 1,
+        '2025-06-09 11:10:23', null, null);
+
+
+
+INSERT INTO aigc_tool (id, `tool_key`, name, tool_group, description, parameters, is_return_direct, status, create_user,
+                       create_time, update_user, update_time)
+VALUES (722203598359887888, 'BROWSER_USE', 'BROWSER_USE', 'default-tool-group', '与网页浏览器交互,执行各种操作,如导航、元素交互、内容提取和标签页管理。搜索类优先考虑此工具。
+支持的操作包括:
+- \'navigate\':访问特定URL,默认使用https://baidu.com
+- \'click\':按索引点击元素
+- \'input_text\':在元素中输入文本,对于百度(Baidu),输入框的索引是
+- \'key_enter\':按回车键
+- \'screenshot\':捕获屏幕截图
+- \'get_html\':获取页面HTML内容
+- \'get_text\':获取页面文本内容
+- \'execute_js\':执行JavaScript代码
+- \'scroll\':滚动页面
+- \'switch_tab\':切换到特定标签页
+- \'new_tab\':打开新标签页
+- \'close_tab\':关闭当前标签页
+- \'refresh\':刷新当前页面', '{
+  "type": "object",
+  "required": [
+    "action"
+  ],
+  "properties": {
+    "url": {
+      "type": "string",
+      "description": "URL for \'navigate\' or \'new_tab\' actions"
+    },
+    "text": {
+      "type": "string",
+      "description": "Text for \'input_text\' action"
+    },
+    "index": {
+      "type": "integer",
+      "description": "Element index for \'click\' or \'input_text\' actions"
+    },
+    "action": {
+      "enum": [
+        "navigate",
+        "click",
+        "input_text",
+        "key_enter",
+        "screenshot",
+        "get_html",
+        "get_text",
+        "execute_js",
+        "scroll",
+        "switch_tab",
+        "new_tab",
+        "close_tab",
+        "refresh"
+      ],
+      "type": "string",
+      "description": "The browser action to perform"
+    },
+    "script": {
+      "type": "string",
+      "description": "JavaScript code for \'execute_js\' action"
+    },
+    "tab_id": {
+      "type": "integer",
+      "description": "Tab ID for \'switch_tab\' action"
+    },
+    "scroll_amount": {
+      "type": "integer",
+      "description": "Pixels to scroll (positive for down, negative for up) for \'scroll\' action"
+    }
+  },
+  "dependencies": {
+    "click": [
+      "index"
+    ],
+    "scroll": [
+      "scroll_amount"
+    ],
+    "new_tab": [
+      "url"
+    ],
+    "navigate": [
+      "url"
+    ],
+    "key_enter": [
+      "index"
+    ],
+    "execute_js": [
+      "script"
+    ],
+    "input_text": [
+      "index",
+      "text"
+    ],
+    "switch_tab": [
+      "tab_id"
+    ]
+  }
+}', 0, 1, 1, '2025-06-09 11:01:58', null, null);
+

+ 22 - 169
pavis-webapi/src/main/resources/db/changelog/mysql/main_table.sql

@@ -80,7 +80,7 @@ CREATE TABLE IF NOT EXISTS `sys_user`
 (
     `id`             bigint(20)          NOT NULL AUTO_INCREMENT COMMENT 'ID',
     `username`       varchar(64)         NOT NULL COMMENT '用户名',
-    `nickname`       varchar(100)         NOT NULL COMMENT '昵称',
+    `nickname`       varchar(100)        NOT NULL COMMENT '昵称',
     `password`       varchar(255)                 DEFAULT NULL COMMENT '密码',
     `gender`         tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '性别(0:未知;1:男;2:女)',
     `email`          varchar(255)                 DEFAULT NULL COMMENT '邮箱',
@@ -88,10 +88,10 @@ CREATE TABLE IF NOT EXISTS `sys_user`
     `avatar`         longtext                     DEFAULT NULL COMMENT '头像',
     `description`    varchar(200)                 DEFAULT NULL COMMENT '描述',
     `status`         tinyint(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '状态(1:启用;2:禁用)',
-    `is_fron`         tinyint(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '是否为前台用户(0:否;1:是)',
+    `is_fron`        tinyint(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '是否为前台用户(0:否;1:是)',
     `is_system`      bit(1)              NOT NULL DEFAULT b'0' COMMENT '是否为系统内置数据',
     `pwd_reset_time` datetime                     DEFAULT NULL COMMENT '最后一次修改密码时间',
-    `dept_id`        bigint(20)          COMMENT '部门ID',
+    `dept_id`        bigint(20) COMMENT '部门ID',
     `create_user`    bigint(20)                   DEFAULT NULL COMMENT '创建人',
     `create_time`    datetime            NOT NULL COMMENT '创建时间',
     `update_user`    bigint(20)                   DEFAULT NULL COMMENT '修改人',
@@ -452,7 +452,7 @@ CREATE TABLE IF NOT EXISTS `aigc_model_secret`
     `secret_key`  VARCHAR(255) DEFAULT NULL COMMENT '密钥',
     `base_url`    VARCHAR(255) DEFAULT NULL COMMENT '基础URL',
     `api_version` VARCHAR(50)  DEFAULT NULL COMMENT 'API版本',
-    `dimension`     INT                     COMMENT '向量维数',
+    `dimension`   INT COMMENT '向量维数',
     `create_user` BIGINT          NOT NULL COMMENT '创建人',
     `create_time` DATETIME        NOT NULL COMMENT '创建时间',
     `update_user` BIGINT       DEFAULT NULL COMMENT '修改人',
@@ -497,7 +497,7 @@ CREATE TABLE IF NOT EXISTS `aigc_knowledge`
     `status`         TINYINT(1)    DEFAULT 1 COMMENT '状态:0停用 1启用 2同步中',
     `hit_count`      BIGINT        DEFAULT 0 COMMENT '被检索次数',
     `avg_relevance`  DECIMAL(5, 2) DEFAULT 0.00 COMMENT '平均检索相关度',
-    `know_describe`              VARCHAR(500)    NOT NULL COMMENT '文档描述',
+    `know_describe`  VARCHAR(500)    NOT NULL COMMENT '文档描述',
     `create_user`    BIGINT          NOT NULL COMMENT '创建人',
     `create_time`    DATETIME        NOT NULL COMMENT '创建时间',
     `update_user`    BIGINT        DEFAULT NULL COMMENT '修改人',
@@ -520,7 +520,7 @@ CREATE TABLE IF NOT EXISTS `aigc_doc`
     `file_type`         VARCHAR(20)     NOT NULL COMMENT '文件类型',
     `mime_type`         VARCHAR(100) DEFAULT NULL COMMENT 'MIME类型',
     `file_encoding`     VARCHAR(50)  DEFAULT 'UTF-8' COMMENT '文件编码',
-    `file_hash`         CHAR(64)         COMMENT '文件哈希',
+    `file_hash`         CHAR(64) COMMENT '文件哈希',
     `file_size`         BIGINT       DEFAULT 0 COMMENT '文件大小',
     `storage_path`      VARCHAR(512)    NOT NULL COMMENT '存储路径',
     `storage_region`    VARCHAR(50)  DEFAULT 'default' COMMENT '存储区域',
@@ -545,7 +545,7 @@ CREATE TABLE IF NOT EXISTS `aigc_doc`
     `vector_status`     VARCHAR(20)  DEFAULT 'pending' COMMENT '向量化状态:pending/processing/completed/failed',
     `error_log`         TEXT         DEFAULT NULL COMMENT '错误日志',
     `retry_count`       INT          DEFAULT 0 COMMENT '重试次数',
-    `slice_num`       INT          DEFAULT 0 COMMENT '重试次数',
+    `slice_num`         INT          DEFAULT 0 COMMENT '重试次数',
     `is_sensitive`      TINYINT(1)   DEFAULT 0 COMMENT '敏感内容标记',
     `version`           INT          DEFAULT 1 COMMENT '文档版本',
     `create_user`       BIGINT          NOT NULL COMMENT '创建人',
@@ -564,12 +564,12 @@ CREATE TABLE IF NOT EXISTS `aigc_doc`
 CREATE TABLE IF NOT EXISTS `aigc_doc_chunk`
 (
     `id`              BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增主键',
-    `embed_store_id`  VARCHAR(100)   COMMENT '向量库的ID',
-    `name`  VARCHAR(255)   COMMENT '文档名称',
-    `doc_id`          BIGINT   COMMENT '文档ID',
-    `knowledge_id`    BIGINT   COMMENT '知识库ID',
-    `chunk_index`     INT              COMMENT '切片索引',
-    `content`         TEXT             COMMENT '切片内容',
+    `embed_store_id`  VARCHAR(100) COMMENT '向量库的ID',
+    `name`            VARCHAR(255) COMMENT '文档名称',
+    `doc_id`          BIGINT COMMENT '文档ID',
+    `knowledge_id`    BIGINT COMMENT '知识库ID',
+    `chunk_index`     INT COMMENT '切片索引',
+    `content`         TEXT COMMENT '切片内容',
     `word_num`        INT           DEFAULT NULL COMMENT '字符数',
     `metadata`        JSON          DEFAULT NULL COMMENT '元数据',
     `embedding`       JSON          DEFAULT NULL COMMENT '向量数据(可选存储)',
@@ -715,19 +715,19 @@ CREATE TABLE IF NOT EXISTS `aigc_app_api`
 CREATE TABLE IF NOT EXISTS `aigc_conversation`
 (
     `id`              BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增主键',
-    `user_id`         BIGINT   COMMENT '所属用户ID',
-    `app_id`          BIGINT   COMMENT '关联应用ID',
+    `user_id`         BIGINT COMMENT '所属用户ID',
+    `app_id`          BIGINT COMMENT '关联应用ID',
     `agent_id`        BIGINT UNSIGNED DEFAULT NULL COMMENT '关联智能体ID',
-    `model_id`        BIGINT   COMMENT '使用模型ID',
-    `title`           VARCHAR(200)     COMMENT '对话标题',
+    `model_id`        BIGINT COMMENT '使用模型ID',
+    `title`           VARCHAR(200) COMMENT '对话标题',
     `summary`         VARCHAR(500)    DEFAULT NULL COMMENT '对话摘要',
     `initial_prompt`  TEXT            DEFAULT NULL COMMENT '对话初始提示词快照',
     `message_count`   INT             DEFAULT 0 COMMENT '消息总数',
     `last_message_id` BIGINT          DEFAULT NULL COMMENT '最后消息ID',
-    `last_active`     DATETIME         COMMENT '最后活动时间',
+    `last_active`     DATETIME COMMENT '最后活动时间',
     `status`          TINYINT(1)      DEFAULT 1 COMMENT '状态:0关闭 1进行中 2置顶',
-    `create_user`     BIGINT           COMMENT '创建人',
-    `create_time`     DATETIME         COMMENT '创建时间',
+    `create_user`     BIGINT COMMENT '创建人',
+    `create_time`     DATETIME COMMENT '创建时间',
     `update_user`     BIGINT          DEFAULT NULL COMMENT '修改人',
     `update_time`     DATETIME        DEFAULT NULL COMMENT '修改时间',
     PRIMARY KEY (`id`),
@@ -755,7 +755,7 @@ CREATE TABLE IF NOT EXISTS `aigc_message`
     `content_metadata`  JSON         DEFAULT NULL COMMENT '元数据',
     `model_id`          BIGINT UNSIGNED                                      NOT NULL COMMENT '调用模型ID',
     `model_version`     VARCHAR(50)  DEFAULT NULL COMMENT '模型版本快照',
-    `usage_token`             json                                                 COMMENT 'token消耗 {"prompt_tokens":20,"completion_tokens":50,"total_tokens":70}',
+    `usage_token`       json COMMENT 'token消耗 {"prompt_tokens":20,"completion_tokens":50,"total_tokens":70}',
     `status`            TINYINT(1)   DEFAULT 1 COMMENT '状态:0删除 1正常 2标记',
     `error_info`        TEXT         DEFAULT NULL COMMENT '错误信息',
     `is_sensitive`      TINYINT(1)   DEFAULT 0 COMMENT '敏感内容标记',
@@ -824,56 +824,6 @@ CREATE TABLE IF NOT EXISTS `aigc_agent`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='智能体表';
 
-INSERT INTO aigc_agent (id, name, code, agent_type, description, system_prompt, next_step_prompt, model_id, icon,
-                        config, max_steps, timeout, runtime_status, status, version, create_user, create_time,
-                        update_user, update_time)
-VALUES (722203598359887877, 'BROWSER_AGENT', 'BROWSER_AGENT', 'task', '一个可以控制浏览器完成任务的浏览器代理', '你是一个设计用于自动化浏览器任务的AI代理。你的目标是按照规则完成最终任务。
-
-# 输入格式
-[index]<type>文本</type>
-- index:交互的数字标识符
-- type:HTML元素类型(按钮、输入框等)
-- 文本:元素描述
-示例:
-[33]<button>提交表单</button>
-
-- 只有带有[]中数字索引的元素可交互
-- 不带[]的元素仅提供上下文
-
-# 响应规则
-1. 操作:你一次只可以做一个tool call 操作
-
-2. 元素交互:
-- 只使用有索引的元素
-- 如用户要求点击某元素,但当期可交互元素中没有,则先查找对应的元素的对应像素位置,然后用click点击该元素
-
-3. 导航和错误处理:
-- 遇到困难时尝试替代方法
-- 处理弹窗和cookie提示
-- 处理验证码或寻找替代方案
-- 等待页面加载
-
-4. 任务完成:
-- 如果完成则使用terminate工具
-
-5. 视觉上下文:
-- 使用提供的截图
-- 引用元素索引
-
-6. 表单填写:
-- 处理动态字段变化', '为实现我的目标,下一步应该做什么?
-
-重点:
-1. 使用\'get_text\'操作获取页面内容,而不是滚动
-2. 不用担心内容可见性或视口位置
-3. 专注于基于文本的信息提取
-4. 直接处理获取的文本数据
-5. 重要:你必须在回复中使用至少一个工具才能取得进展!
-
-考虑可见的内容和当前视口之外可能存在的内容。
-有条理地行动 - 记住你的进度和迄今为止学到的知识。', 722203598359887866, null, null, 20, 60, null, 1, '1.0.0', 1,
-        '2025-06-09 11:10:23', null, null);
-
 
 -- ------------------------------
 -- Table structure for aigc_tool
@@ -897,102 +847,6 @@ CREATE TABLE IF NOT EXISTS `aigc_tool`
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8mb4 COMMENT ='工具表';
 
-INSERT INTO aigc_tool (id, `tool_key`, name, tool_group, description, parameters, is_return_direct, status, create_user,
-                       create_time, update_user, update_time)
-VALUES (722203598359887888, 'BROWSER_USE', 'BROWSER_USE', 'default-tool-group', '与网页浏览器交互,执行各种操作,如导航、元素交互、内容提取和标签页管理。搜索类优先考虑此工具。
-支持的操作包括:
-- \'navigate\':访问特定URL,默认使用https://baidu.com
-- \'click\':按索引点击元素
-- \'input_text\':在元素中输入文本,对于百度(Baidu),输入框的索引是
-- \'key_enter\':按回车键
-- \'screenshot\':捕获屏幕截图
-- \'get_html\':获取页面HTML内容
-- \'get_text\':获取页面文本内容
-- \'execute_js\':执行JavaScript代码
-- \'scroll\':滚动页面
-- \'switch_tab\':切换到特定标签页
-- \'new_tab\':打开新标签页
-- \'close_tab\':关闭当前标签页
-- \'refresh\':刷新当前页面', '{
-  "type": "object",
-  "required": [
-    "action"
-  ],
-  "properties": {
-    "url": {
-      "type": "string",
-      "description": "URL for \'navigate\' or \'new_tab\' actions"
-    },
-    "text": {
-      "type": "string",
-      "description": "Text for \'input_text\' action"
-    },
-    "index": {
-      "type": "integer",
-      "description": "Element index for \'click\' or \'input_text\' actions"
-    },
-    "action": {
-      "enum": [
-        "navigate",
-        "click",
-        "input_text",
-        "key_enter",
-        "screenshot",
-        "get_html",
-        "get_text",
-        "execute_js",
-        "scroll",
-        "switch_tab",
-        "new_tab",
-        "close_tab",
-        "refresh"
-      ],
-      "type": "string",
-      "description": "The browser action to perform"
-    },
-    "script": {
-      "type": "string",
-      "description": "JavaScript code for \'execute_js\' action"
-    },
-    "tab_id": {
-      "type": "integer",
-      "description": "Tab ID for \'switch_tab\' action"
-    },
-    "scroll_amount": {
-      "type": "integer",
-      "description": "Pixels to scroll (positive for down, negative for up) for \'scroll\' action"
-    }
-  },
-  "dependencies": {
-    "click": [
-      "index"
-    ],
-    "scroll": [
-      "scroll_amount"
-    ],
-    "new_tab": [
-      "url"
-    ],
-    "navigate": [
-      "url"
-    ],
-    "key_enter": [
-      "index"
-    ],
-    "execute_js": [
-      "script"
-    ],
-    "input_text": [
-      "index",
-      "text"
-    ],
-    "switch_tab": [
-      "tab_id"
-    ]
-  }
-}', 0, 1, 1, '2025-06-09 11:01:58', null, null);
-
-
 -- ------------------------------
 -- Table structure for aigc_tool
 -- ------------------------------
@@ -1080,8 +934,7 @@ CREATE TABLE IF NOT EXISTS `aigc_agent_plan_step`
     `execution_start_time` DATETIME     DEFAULT NULL COMMENT '插件执行此步骤开始的时间戳',
     `execution_end_time`   DATETIME     DEFAULT NULL COMMENT '插件执行此步骤完成的时间戳',
     `execution_duration`   LONG         DEFAULT NULL COMMENT '插件执行时长(秒)',
-    `tool_name`            VARCHAR(50)  DEFAULT NULL COMMENT '智能体选中的工具名称',
-    `tool_parameters`      JSON         DEFAULT NULL COMMENT '智能体选中的工具执行时需要的参数',
+    `tool_execution`       JSON         DEFAULT NULL COMMENT '智能体选中的工具执行时需要的参数了列表',
     `result`               TEXT         DEFAULT NULL COMMENT '步骤执行思考的结果',
     `status`               VARCHAR(20)  DEFAULT NULL COMMENT '智能体状态:IDLE/RUNNING/FINISHED',
     `completed`            TINYINT(1)   DEFAULT 0 COMMENT '是否完成:0未完成 1已完成',