agent-foundation/src/main/java/com/company/agentfoundation/agent/AgentOrchestratorService.java

137 lines
5.1 KiB
Java
Raw Normal View History

2026-06-11 11:37:38 +08:00
package com.company.agentfoundation.agent;
2026-06-08 09:37:35 +08:00
import com.company.agentfoundation.domain.ChatRequest;
import com.company.agentfoundation.domain.ChatResponse;
2026-06-12 09:56:34 +08:00
import com.company.agentfoundation.directory.EmployeeAccountMapping;
import com.company.agentfoundation.directory.EmployeeDirectoryResponse;
import com.company.agentfoundation.directory.EmployeeDirectoryService;
2026-06-08 09:37:35 +08:00
import com.company.agentfoundation.security.AgentContext;
import com.company.agentfoundation.service.ChatService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class AgentOrchestratorService {
private static final Logger log = LoggerFactory.getLogger(AgentOrchestratorService.class);
private final IntentRecognitionService intentRecognitionService;
private final OperationReportService operationReportService;
private final ChatService chatService;
2026-06-12 09:56:34 +08:00
private final EmployeeDirectoryService employeeDirectoryService;
2026-06-08 09:37:35 +08:00
public AgentOrchestratorService(
IntentRecognitionService intentRecognitionService,
OperationReportService operationReportService,
2026-06-12 09:56:34 +08:00
ChatService chatService,
EmployeeDirectoryService employeeDirectoryService
2026-06-08 09:37:35 +08:00
) {
this.intentRecognitionService = intentRecognitionService;
this.operationReportService = operationReportService;
this.chatService = chatService;
2026-06-12 09:56:34 +08:00
this.employeeDirectoryService = employeeDirectoryService;
2026-06-08 09:37:35 +08:00
}
public String handleMessage(String agentId, String fromUser, String userText) {
AgentIntent intent = intentRecognitionService.recognize(agentId, userText);
2026-06-11 11:31:49 +08:00
log.info("agent orchestrator route fromUser={} intent={} group={}", fromUser, intent.code(), intent.mcpGroup());
2026-06-08 09:37:35 +08:00
if (intent != AgentIntent.GENERAL_CHAT) {
2026-06-12 09:56:34 +08:00
return appendDirectoryInfo(
toWecomText(operationReportService.handle(intent, AgentRequestContext.of(agentId, fromUser, userText))),
fromUser
);
2026-06-08 09:37:35 +08:00
}
ChatRequest request = new ChatRequest(
null,
List.of(
new ChatRequest.Message("system", "You are an enterprise CRM assistant. Reply concisely in Chinese."),
new ChatRequest.Message("user", userText)
),
0.3
);
ChatResponse response = chatService.chat(new AgentContext(agentId), request);
2026-06-12 09:56:34 +08:00
return appendDirectoryInfo(response.content(), fromUser);
2026-06-08 09:37:35 +08:00
}
private String toWecomText(AgentCapabilityResponse response) {
return """
\u3010%s\u3011
%s
\u80fd\u529b\u5206\u7ec4\uff1a%s
\u80fd\u529b\u7f16\u7801\uff1a%s
\u6570\u636e\u6e90\uff1a%s
\u72b6\u6001\uff1a%s
""".formatted(
response.title(),
response.message(),
response.mcpGroup(),
response.intentCode(),
String.join("\u3001", response.dataSources()),
response.status()
).trim();
}
2026-06-12 09:56:34 +08:00
private String appendDirectoryInfo(String reply, String wecomUserId) {
String text = reply == null || reply.isBlank() ? "" : reply.trim();
return text + "\n\n" + buildDirectoryInfo(wecomUserId);
}
private String buildDirectoryInfo(String wecomUserId) {
if (wecomUserId == null || wecomUserId.isBlank()) {
return "【身份信息】\n企业微信账号:未获取\n学邦账号:未匹配\n部门:未匹配\n身份:未匹配";
}
try {
return employeeDirectoryService.findByWecomUserId(wecomUserId)
.map(this::formatDirectoryInfo)
.orElse("""
【身份信息】
企业微信账号:%s
学邦账号:未匹配
部门:未匹配
身份:未匹配
""".formatted(wecomUserId).trim());
} catch (Exception e) {
log.warn("employee directory lookup failed wecomUserId={} err={}", wecomUserId, e.getMessage());
return """
【身份信息】
企业微信账号:%s
学邦账号:查询失败
部门:查询失败
身份:查询失败
""".formatted(wecomUserId).trim();
}
}
private String formatDirectoryInfo(EmployeeDirectoryResponse response) {
EmployeeAccountMapping account = response.account();
String department = firstNotBlank(account.xuebangPrimaryOrg(), account.wecomDepartmentPath(), "未匹配");
String xuebangAccount = firstNotBlank(account.xuebangAccount(), "未匹配");
String roleName = firstNotBlank(account.primaryRoleName(), "未匹配");
String roleCode = firstNotBlank(account.primaryRoleCode(), "未匹配");
String scopeType = firstNotBlank(account.dataScopeType(), "未匹配");
String roleLevel = account.roleLevel() == null ? "未匹配" : account.roleLevel().toString();
return """
【身份信息】
企业微信账号:%s
学邦账号:%s
部门:%s
身份:%s(%s,级别%s,范围%s)
""".formatted(account.wecomUserId(), xuebangAccount, department, roleName, roleCode, roleLevel, scopeType).trim();
}
private String firstNotBlank(String... values) {
for (String value : values) {
if (value != null && !value.isBlank()) {
return value;
}
}
return "";
}
2026-06-08 09:37:35 +08:00
}