扣子智能体调用
This commit is contained in:
parent
e12583c41c
commit
b72d166adb
@ -2,7 +2,6 @@ package com.company.agentfoundation.integration.coze.client;
|
|||||||
|
|
||||||
import com.company.agentfoundation.config.FoundationProperties;
|
import com.company.agentfoundation.config.FoundationProperties;
|
||||||
import com.company.agentfoundation.integration.coze.dto.CozeWorkflowRequest;
|
import com.company.agentfoundation.integration.coze.dto.CozeWorkflowRequest;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -23,13 +22,13 @@ public class CozeWorkflowClient {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonNode chat(CozeWorkflowRequest request) {
|
public String chat(CozeWorkflowRequest request) {
|
||||||
return webClient.post()
|
return webClient.post()
|
||||||
.uri(properties.getCoze().getChatPath())
|
.uri(properties.getCoze().getChatPath())
|
||||||
.header(HttpHeaders.AUTHORIZATION, "Bearer " + properties.getCoze().getApiKey())
|
.header(HttpHeaders.AUTHORIZATION, "Bearer " + properties.getCoze().getApiKey())
|
||||||
.bodyValue(request)
|
.bodyValue(request)
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(JsonNode.class)
|
.bodyToMono(String.class)
|
||||||
.retryWhen(Retry.backoff(properties.getCoze().getMaxRetries(), Duration.ofMillis(300)))
|
.retryWhen(Retry.backoff(properties.getCoze().getMaxRetries(), Duration.ofMillis(300)))
|
||||||
.block(Duration.ofMillis(properties.getCoze().getReadTimeoutMs()));
|
.block(Duration.ofMillis(properties.getCoze().getReadTimeoutMs()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,7 +55,7 @@ public class CozeWorkflowService {
|
|||||||
List.of(new CozeMessage("text", "user", "question", userText == null ? "" : userText))
|
List.of(new CozeMessage("text", "user", "question", userText == null ? "" : userText))
|
||||||
);
|
);
|
||||||
|
|
||||||
JsonNode response = client.chat(request);
|
String response = client.chat(request);
|
||||||
String reply = extractReply(response).orElse("");
|
String reply = extractReply(response).orElse("");
|
||||||
log.info("coze workflow chat success workflowKey={} replyPreview={}", workflowKey, preview(reply));
|
log.info("coze workflow chat success workflowKey={} replyPreview={}", workflowKey, preview(reply));
|
||||||
return reply;
|
return reply;
|
||||||
@ -117,6 +117,76 @@ public class CozeWorkflowService {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Optional<String> extractReply(String response) {
|
||||||
|
if (isBlank(response)) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
String trimmed = response.trim();
|
||||||
|
if (isJson(trimmed)) {
|
||||||
|
try {
|
||||||
|
return extractReply(objectMapper.readTree(trimmed));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("coze workflow json response parse failed err={}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Optional<String> eventReply = extractFromEventStream(trimmed);
|
||||||
|
if (eventReply.isPresent()) {
|
||||||
|
return eventReply;
|
||||||
|
}
|
||||||
|
if (looksLikeEventStream(trimmed)) {
|
||||||
|
log.warn("coze workflow event stream response did not include completed content");
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return Optional.of(trimmed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<String> extractFromEventStream(String response) {
|
||||||
|
String currentEvent = "";
|
||||||
|
StringBuilder data = new StringBuilder();
|
||||||
|
String[] lines = response.replace("\r\n", "\n").replace('\r', '\n').split("\n", -1);
|
||||||
|
for (String line : lines) {
|
||||||
|
if (line.isBlank()) {
|
||||||
|
Optional<String> content = extractCompletedEventContent(currentEvent, data.toString());
|
||||||
|
if (content.isPresent()) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
currentEvent = "";
|
||||||
|
data.setLength(0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.startsWith("event:")) {
|
||||||
|
currentEvent = line.substring("event:".length()).trim();
|
||||||
|
} else if (line.startsWith("data:")) {
|
||||||
|
if (data.length() > 0) {
|
||||||
|
data.append('\n');
|
||||||
|
}
|
||||||
|
data.append(line.substring("data:".length()).trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return extractCompletedEventContent(currentEvent, data.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<String> extractCompletedEventContent(String event, String data) {
|
||||||
|
if (!"conversation.message.completed".equals(event) || isBlank(data) || !isJson(data.trim())) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
JsonNode message = objectMapper.readTree(data);
|
||||||
|
String role = message.path("role").asText("");
|
||||||
|
String type = message.path("type").asText("");
|
||||||
|
if (("assistant".equalsIgnoreCase(role) || role.isBlank()) && ("answer".equalsIgnoreCase(type) || type.isBlank())) {
|
||||||
|
return firstText(message, "content", "text", "answer", "output");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("coze workflow completed event parse failed err={}", e.getMessage());
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean looksLikeEventStream(String response) {
|
||||||
|
return response.startsWith("event:") || response.contains("\nevent:") || response.startsWith("data:") || response.contains("\ndata:");
|
||||||
|
}
|
||||||
|
|
||||||
private Optional<String> extractFromMessages(JsonNode messages) {
|
private Optional<String> extractFromMessages(JsonNode messages) {
|
||||||
if (messages == null || !messages.isArray()) {
|
if (messages == null || !messages.isArray()) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
public class WecomCallbackController {
|
public class WecomCallbackController {
|
||||||
private static final Logger log = LoggerFactory.getLogger(WecomCallbackController.class);
|
private static final Logger log = LoggerFactory.getLogger(WecomCallbackController.class);
|
||||||
private static final long MESSAGE_DEDUP_TTL_SECONDS = 600;
|
private static final long MESSAGE_DEDUP_TTL_SECONDS = 600;
|
||||||
private static final String FIXED_REPLY = "\u4f60\u597d";
|
private static final String ERROR_REPLY = "\u6263\u5b50\u667a\u80fd\u4f53\u8c03\u7528\u5931\u8d25\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5";
|
||||||
private final CozeWorkflowService cozeWorkflowService;
|
private final CozeWorkflowService cozeWorkflowService;
|
||||||
private final WecomClient wecomClient;
|
private final WecomClient wecomClient;
|
||||||
private final WecomCryptoService wecomCryptoService;
|
private final WecomCryptoService wecomCryptoService;
|
||||||
@ -97,11 +97,11 @@ public class WecomCallbackController {
|
|||||||
reply = cozeWorkflowService.chatDefault(userText);
|
reply = cozeWorkflowService.chatDefault(userText);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("wecom callback coze workflow failed fromUser={} err={}", msg.getFromUserName(), e.getMessage(), e);
|
log.error("wecom callback coze workflow failed fromUser={} err={}", msg.getFromUserName(), e.getMessage(), e);
|
||||||
reply = FIXED_REPLY;
|
reply = ERROR_REPLY;
|
||||||
}
|
}
|
||||||
if (reply == null || reply.isBlank()) {
|
if (reply == null || reply.isBlank()) {
|
||||||
log.warn("wecom callback coze reply blank, fallback to fixed reply");
|
log.warn("wecom callback coze reply blank, fallback to error reply");
|
||||||
reply = FIXED_REPLY;
|
reply = ERROR_REPLY;
|
||||||
}
|
}
|
||||||
log.info("wecom callback sending coze reply toUser={} replyPreview={}", msg.getFromUserName(), preview(reply));
|
log.info("wecom callback sending coze reply toUser={} replyPreview={}", msg.getFromUserName(), preview(reply));
|
||||||
wecomClient.sendText(msg.getFromUserName(), reply);
|
wecomClient.sendText(msg.getFromUserName(), reply);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user