Michael Yang
2025-05-07 5afa5041ea166f462a90a996d5264c64837f4341
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package tech.aiflowy.common.ai;
 
import tech.aiflowy.common.ai.annotation.FunctionModuleDef;
import tech.aiflowy.common.util.SpringContextUtil;
import tech.aiflowy.common.util.StringUtil;
import com.agentsflex.core.llm.ChatContext;
import com.agentsflex.core.llm.Llm;
import com.agentsflex.core.llm.StreamResponseListener;
import com.agentsflex.core.llm.functions.Function;
import com.agentsflex.core.llm.functions.JavaNativeFunctions;
import com.agentsflex.core.llm.response.AiMessageResponse;
import com.agentsflex.core.memory.ChatMemory;
import com.agentsflex.core.prompt.FunctionPrompt;
import com.mybatisflex.core.util.ClassUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
 
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
@Component
public class FunctionsManager {
    private static final Logger logger = LoggerFactory.getLogger(FunctionsManager.class);
    private ExecutorService sseExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
 
    private Map<String, FunctionModule> functionModules = new HashMap<>();
 
 
    @EventListener(ApplicationReadyEvent.class)
    public void initFunctionModules() {
        Map<String, Object> functionModuleBeanMap = SpringContextUtil.getBeansWithAnnotation(FunctionModuleDef.class);
        for (Object functionModuleBean : functionModuleBeanMap.values()) {
            Class<?> usefulClass = ClassUtil.getUsefulClass(functionModuleBean.getClass());
            FunctionModuleDef annotation = usefulClass.getAnnotation(FunctionModuleDef.class);
 
            FunctionModule functionModule = new FunctionModule();
            functionModule.setName(annotation.name());
            functionModule.setTitle(annotation.title());
            functionModule.setDescription(annotation.description());
            functionModule.setFunctionsObject(functionModuleBean);
 
            functionModules.put(functionModule.getName(), functionModule);
        }
    }
 
 
    public List<Function> getFunctions(String userPrompt, String... names) {
        StringBuilder prompt = new StringBuilder("我的系统包含了如下的模块:\n");
        functionModules.forEach((s, functionModule) ->
                prompt.append("- **").append(functionModule.getTitle()).append("**: ").append(functionModule.getDescription()).append("\n")
        );
        prompt.append("\n请根据如下的用户内容,帮我分析出该用户想了解关于哪个模块的信息,并直接告诉我模块的名称,不用做任何的解释,也不需要除了模块名称以外其他的文字内容或信息。如果没有匹配任何模块,请直接告知我:无模块匹配。");
        prompt.append("\n\n用户的提问内容是:\n").append(userPrompt);
 
 
        String result = ChatManager.getInstance().chat(prompt.toString());
 
        if (!StringUtil.hasText(result)) {
            return null;
        }
 
        FunctionModule functionModule = null;
        for (FunctionModule module : functionModules.values()) {
            if (StringUtil.hasText(module.getTitle()) && result.contains(module.getTitle())) {
                functionModule = module;
                break;
            }
        }
 
        if (functionModule == null) {
            return null;
        }
 
        return JavaNativeFunctions.from(functionModule.getFunctionsObject());
    }
 
    public SseEmitter call(String prompt, List<Function> functions) {
        return call(prompt, functions, null);
    }
 
    public SseEmitter call(String prompt, List<Function> functions, ChatMemory memory) {
        MySseEmitter emitter = new MySseEmitter(20000L);
        sseExecutor.execute(() -> {
            Llm llm = ChatManager.getInstance().getChatLlm();
            if (llm == null) {
                emitter.sendAndComplete("AI 大模型未配置正确");
                return;
            }
            FunctionPrompt functionPrompt = new FunctionPrompt(prompt, functions);
            AiMessageResponse response = llm.chat(functionPrompt);
 
 
            if (response.getMessage() == null) {
                llm.chatStream(prompt, new StreamResponseListener() {
                    @Override
                    public void onMessage(ChatContext chatContext, AiMessageResponse aiMessageResponse) {
                        String content = aiMessageResponse.getMessage().getContent();
                        System.out.println(">>>>response: " + content);
                        emitter.send(content);
                    }
 
                    @Override
                    public void onStop(ChatContext context) {
                        emitter.complete();
                    }
                });
            } else {
                Object result = response.callFunctions();
                memory.addMessage(response.getMessage());
                emitter.sendAndComplete(result + " \n");
            }
        });
        return emitter;
    }
 
 
    public static FunctionsManager getInstance() {
        return SpringContextUtil.getBean(FunctionsManager.class);
    }
 
}