mirror of
https://gitee.com/agents-flex/agents-flex.git
synced 2024-11-29 18:38:17 +08:00
集成Coze api,实现和Bot对话
This commit is contained in:
parent
ce762b4743
commit
6174953033
38
agents-flex-llm/agents-flex-llm-coze/.gitignore
vendored
Normal file
38
agents-flex-llm/agents-flex-llm-coze/.gitignore
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
35
agents-flex-llm/agents-flex-llm-coze/pom.xml
Normal file
35
agents-flex-llm/agents-flex-llm-coze/pom.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.agentsflex</groupId>
|
||||
<artifactId>agents-flex-llm</artifactId>
|
||||
<version>1.0.0-beta.9</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>agents-flex-llm-coze</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.agentsflex</groupId>
|
||||
<artifactId>agents-flex-core</artifactId>
|
||||
<version>1.0.0-beta.9</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2025, Agents-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.agentsflex.llm.coze;
|
||||
|
||||
import com.agentsflex.core.llm.ChatContext;
|
||||
import com.agentsflex.core.llm.Llm;
|
||||
import com.agentsflex.core.llm.client.LlmClient;
|
||||
import com.agentsflex.core.message.AiMessage;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author yulsh
|
||||
*/
|
||||
public class CozeChatContext extends ChatContext {
|
||||
|
||||
private String id;
|
||||
private String conversationId;
|
||||
|
||||
private String botId;
|
||||
|
||||
private String status;
|
||||
|
||||
private long createdAt;
|
||||
|
||||
private Map lastError;
|
||||
|
||||
private Map usage;
|
||||
|
||||
private AiMessage message;
|
||||
|
||||
public CozeChatContext(Llm llm, LlmClient client) {
|
||||
super(llm, client);
|
||||
}
|
||||
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getConversationId() {
|
||||
return conversationId;
|
||||
}
|
||||
|
||||
public void setConversationId(String conversationId) {
|
||||
this.conversationId = conversationId;
|
||||
}
|
||||
|
||||
public String getBotId() {
|
||||
return botId;
|
||||
}
|
||||
|
||||
public void setBotId(String botId) {
|
||||
this.botId = botId;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public long getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(long createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public Map getLastError() {
|
||||
return lastError;
|
||||
}
|
||||
|
||||
public void setLastError(Map lastError) {
|
||||
this.lastError = lastError;
|
||||
}
|
||||
|
||||
public Map getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
public void setUsage(Map usage) {
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
public void setMessage(AiMessage message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public AiMessage getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2025, Agents-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.agentsflex.llm.coze;
|
||||
|
||||
import com.agentsflex.core.llm.ChatOptions;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author yulsh
|
||||
*/
|
||||
public class CozeChatOptions extends ChatOptions {
|
||||
|
||||
private String botId;
|
||||
|
||||
private String conversationId;
|
||||
|
||||
private String userId;
|
||||
|
||||
private boolean stream;
|
||||
|
||||
private Map<String, String> customVariables;
|
||||
|
||||
public String getBotId() {
|
||||
return botId;
|
||||
}
|
||||
|
||||
public void setBotId(String botId) {
|
||||
this.botId = botId;
|
||||
}
|
||||
|
||||
public String getConversationId() {
|
||||
return conversationId;
|
||||
}
|
||||
|
||||
public void setConversationId(String conversationId) {
|
||||
this.conversationId = conversationId;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public void setStream(boolean stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
public boolean isStream() {
|
||||
return stream;
|
||||
}
|
||||
|
||||
public void setCustomVariables(Map<String, String> customVariables) {
|
||||
this.customVariables = customVariables;
|
||||
}
|
||||
|
||||
public Map<String, String> getCustomVariables() {
|
||||
return customVariables;
|
||||
}
|
||||
}
|
@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2025, Agents-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.agentsflex.llm.coze;
|
||||
|
||||
import com.agentsflex.core.document.Document;
|
||||
import com.agentsflex.core.llm.BaseLlm;
|
||||
import com.agentsflex.core.llm.ChatContext;
|
||||
import com.agentsflex.core.llm.ChatOptions;
|
||||
import com.agentsflex.core.llm.MessageResponse;
|
||||
import com.agentsflex.core.llm.StreamResponseListener;
|
||||
import com.agentsflex.core.llm.client.BaseLlmClientListener;
|
||||
import com.agentsflex.core.llm.client.HttpClient;
|
||||
import com.agentsflex.core.llm.client.LlmClientListener;
|
||||
import com.agentsflex.core.llm.embedding.EmbeddingOptions;
|
||||
import com.agentsflex.core.llm.response.AbstractBaseMessageResponse;
|
||||
import com.agentsflex.core.llm.response.AiMessageResponse;
|
||||
import com.agentsflex.core.message.AiMessage;
|
||||
import com.agentsflex.core.message.Message;
|
||||
import com.agentsflex.core.parser.AiMessageParser;
|
||||
import com.agentsflex.core.parser.FunctionMessageParser;
|
||||
import com.agentsflex.core.prompt.Prompt;
|
||||
import com.agentsflex.core.store.VectorData;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @author yulsh
|
||||
*/
|
||||
public class CozeLlm extends BaseLlm<CozeLlmConfig> {
|
||||
|
||||
private final HttpClient httpClient = new HttpClient();
|
||||
private final AiMessageParser aiMessageParser = CozeLlmUtil.getAiMessageParser();
|
||||
|
||||
public CozeLlm(CozeLlmConfig config) {
|
||||
super(config);
|
||||
}
|
||||
|
||||
private Map<String, String> buildHeader() {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("Content-Type", "application/json");
|
||||
headers.put("Authorization", "Bearer " + config.getApiKey());
|
||||
return headers;
|
||||
}
|
||||
|
||||
private <R extends MessageResponse<?>> void botChat(Prompt<R> prompt, CozeRequestListener listener, ChatOptions chatOptions, boolean stream) {
|
||||
CozeChatOptions options = (CozeChatOptions) chatOptions;
|
||||
String payload = CozeLlmUtil.promptToPayload(prompt, config, options, stream);
|
||||
String url = config.getEndpoint() + config.getChatApi();
|
||||
if (options.getConversationId() != null) {
|
||||
url += "?conversation_id=" + options.getConversationId();
|
||||
}
|
||||
String response = httpClient.post(url, buildHeader(), payload);
|
||||
if (config.isDebug()) {
|
||||
System.out.println(">>>>request payload:" + payload);
|
||||
}
|
||||
CozeChatContext cozeChat;
|
||||
|
||||
// stream mode
|
||||
if (stream) {
|
||||
handleStreamResponse(response, listener);
|
||||
return;
|
||||
}
|
||||
|
||||
JSONObject jsonObject = JSON.parseObject(response);
|
||||
String code = jsonObject.getString("code");
|
||||
String error = jsonObject.getString("msg");
|
||||
cozeChat = jsonObject.getObject("data", (Type) CozeChatContext.class);
|
||||
|
||||
if (!error.isEmpty() && !Objects.equals(code, "0")) {
|
||||
listener.onFailure(cozeChat, new Throwable(error));
|
||||
listener.onStop(cozeChat);
|
||||
return;
|
||||
}
|
||||
|
||||
// try to check status
|
||||
int attemptCount = 0;
|
||||
boolean isCompleted = false;
|
||||
int maxAttempts = 20;
|
||||
while (attemptCount < maxAttempts && !isCompleted) {
|
||||
attemptCount ++;
|
||||
try {
|
||||
cozeChat = checkStatus(cozeChat);
|
||||
listener.onMessage(cozeChat);
|
||||
|
||||
isCompleted = Objects.equals(cozeChat.getStatus(), "completed");
|
||||
if (isCompleted || attemptCount == maxAttempts) {
|
||||
listener.onStop(cozeChat);
|
||||
break;
|
||||
}
|
||||
Thread.sleep(1000);
|
||||
} catch (Exception e) {
|
||||
listener.onFailure(cozeChat, e.getCause());
|
||||
listener.onStop(cozeChat);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleStreamResponse(String response, CozeRequestListener listener) {
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(response.getBytes(Charset.defaultCharset()));
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, Charset.defaultCharset()));
|
||||
String line;
|
||||
CozeChatContext context = new CozeChatContext(this, null);
|
||||
List<AiMessage> messageList = new ArrayList<>();
|
||||
try {
|
||||
while ( (line = br.readLine()) != null ) {
|
||||
if(!line.trim().equals("") && line.startsWith("data:")){
|
||||
if (line.contains("[DONE]")) {
|
||||
continue;
|
||||
}
|
||||
line = line.replace("data:", "");
|
||||
Map<String, String> data = JSON.parseObject(line, Map.class);
|
||||
String status = data.getOrDefault("status", "");
|
||||
String type = data.getOrDefault("type", "");
|
||||
if (status.equals("completed")) {
|
||||
context = JSON.parseObject(line, CozeChatContext.class);
|
||||
listener.onStop(context);
|
||||
continue;
|
||||
}
|
||||
// N 条answer,最后一条是完整的
|
||||
if (type.equals("answer")) {
|
||||
AiMessage message = new AiMessage();
|
||||
message.setContent(data.get("content"));
|
||||
messageList.add(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!messageList.isEmpty()) {
|
||||
// 删除最后一条完整的之后输出
|
||||
messageList.remove(messageList.size() -1);
|
||||
for(AiMessage m: messageList) {
|
||||
context.setMessage(m);
|
||||
listener.onMessage(context);
|
||||
Thread.sleep(10);
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
listener.onFailure(context, ex.getCause());
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private CozeChatContext checkStatus(CozeChatContext cozeChat) {
|
||||
String chatId = cozeChat.getId();
|
||||
String conversationId = cozeChat.getConversationId();
|
||||
String url = String.format("%s/v3/chat/retrieve?chat_id=%s&conversation_id=%s", config.getEndpoint(), chatId, conversationId);
|
||||
String response = httpClient.get(url, buildHeader());
|
||||
JSONObject resObj = JSON.parseObject(response);
|
||||
CozeChatContext data = resObj.getObject("data", (Type) CozeChatContext.class);
|
||||
return data;
|
||||
}
|
||||
|
||||
private JSONArray fetchMessageList(CozeChatContext cozeChat) {
|
||||
String chatId = cozeChat.getId();
|
||||
String conversationId = cozeChat.getConversationId();
|
||||
String endpoint = config.getEndpoint();
|
||||
String url = String.format("%s/v3/chat/message/list?chat_id=%s&conversation_id=%s", endpoint, chatId, conversationId);
|
||||
String response = httpClient.get(url, buildHeader());
|
||||
JSONObject jsonObject = JSON.parseObject(response);
|
||||
String code = jsonObject.getString("code");
|
||||
String error = jsonObject.getString("msg");
|
||||
JSONArray messageList = jsonObject.getJSONArray("data");
|
||||
if (!error.isEmpty() && !Objects.equals(code, "0")) {
|
||||
return null;
|
||||
}
|
||||
return messageList;
|
||||
}
|
||||
|
||||
public AiMessage getChatAnswer(CozeChatContext cozeChat) {
|
||||
JSONArray messageList = fetchMessageList(cozeChat);
|
||||
List<JSONObject> objects = messageList.stream()
|
||||
.map(JSONObject.class::cast)
|
||||
.filter(obj -> "answer".equals(obj.getString("type")))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
JSONObject answer = objects.size() > 0 ? objects.get(0) : null;
|
||||
if (answer != null) {
|
||||
answer.put("usage", cozeChat.getUsage());
|
||||
answer.put("content",answer.getString("content"));
|
||||
AiMessage message = aiMessageParser.parse(answer);
|
||||
return message;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VectorData embed(Document document, EmbeddingOptions options) {
|
||||
return super.embed(document);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends MessageResponse<?>> R chat(Prompt<R> prompt, ChatOptions options) {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
Message[] messages = new Message[1];
|
||||
Throwable[] failureThrowable = new Throwable[1];
|
||||
|
||||
this.botChat(prompt, new CozeRequestListener() {
|
||||
@Override
|
||||
public void onMessage(CozeChatContext context) {
|
||||
boolean isCompleted = Objects.equals(context.getStatus(), "completed");
|
||||
if (isCompleted) {
|
||||
AiMessage answer = getChatAnswer(context);
|
||||
messages[0] = answer;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(CozeChatContext context, Throwable throwable) {
|
||||
failureThrowable[0] = throwable;
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(CozeChatContext context) {
|
||||
latch.countDown();
|
||||
}
|
||||
}, options, false);
|
||||
|
||||
try {
|
||||
latch.await();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
AbstractBaseMessageResponse<?> response;
|
||||
response = new AiMessageResponse((AiMessage) messages[0]);
|
||||
|
||||
if (messages[0] == null || failureThrowable[0] != null) {
|
||||
response.setError(true);
|
||||
if (failureThrowable[0] != null) {
|
||||
response.setErrorMessage(failureThrowable[0].getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return (R) response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends MessageResponse<?>> void chatStream(Prompt<R> prompt, StreamResponseListener<R> listener, ChatOptions options) {
|
||||
this.botChat(prompt, new CozeRequestListener() {
|
||||
@Override
|
||||
public void onMessage(CozeChatContext context) {
|
||||
AiMessageResponse response = new AiMessageResponse(context.getMessage());
|
||||
listener.onMessage(context, (R) response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(CozeChatContext context, Throwable throwable) {
|
||||
listener.onFailure(context, throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(CozeChatContext context) {
|
||||
listener.onStop(context);
|
||||
}
|
||||
}, options, true);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2025, Agents-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.agentsflex.llm.coze;
|
||||
|
||||
import com.agentsflex.core.llm.LlmConfig;
|
||||
|
||||
/**
|
||||
* @author yulsh
|
||||
*/
|
||||
public class CozeLlmConfig extends LlmConfig {
|
||||
|
||||
private String DEFAULT_CHAT_API = "/v3/chat";
|
||||
private String DEFAULT_ENDPOINT = "https://api.coze.cn";
|
||||
private String chatApi;
|
||||
|
||||
public CozeLlmConfig() {
|
||||
this.setChatApi(DEFAULT_CHAT_API);
|
||||
this.setEndpoint(DEFAULT_ENDPOINT);
|
||||
}
|
||||
|
||||
public void setChatApi(String chatApi) {
|
||||
this.chatApi = chatApi;
|
||||
}
|
||||
|
||||
public String getChatApi() {
|
||||
return chatApi;
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2025, Agents-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.agentsflex.llm.coze;
|
||||
|
||||
import com.agentsflex.core.message.Message;
|
||||
import com.agentsflex.core.message.MessageStatus;
|
||||
import com.agentsflex.core.parser.AiMessageParser;
|
||||
import com.agentsflex.core.parser.FunctionMessageParser;
|
||||
import com.agentsflex.core.parser.impl.DefaultAiMessageParser;
|
||||
import com.agentsflex.core.parser.impl.DefaultFunctionMessageParser;
|
||||
import com.agentsflex.core.prompt.DefaultPromptFormat;
|
||||
import com.agentsflex.core.prompt.Prompt;
|
||||
import com.agentsflex.core.prompt.PromptFormat;
|
||||
import com.agentsflex.core.util.Maps;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author yulsh
|
||||
*/
|
||||
public class CozeLlmUtil {
|
||||
|
||||
private static final PromptFormat promptFormat = new DefaultPromptFormat() {
|
||||
@Override
|
||||
protected void buildMessageContent(Message message, Map<String, Object> map) {
|
||||
map.put("content_type", "text");
|
||||
super.buildMessageContent(message, map);
|
||||
}
|
||||
};
|
||||
|
||||
public static AiMessageParser getAiMessageParser() {
|
||||
DefaultAiMessageParser aiMessageParser = new DefaultAiMessageParser();
|
||||
aiMessageParser.setContentPath("$.content");
|
||||
aiMessageParser.setStatusPath("$.done");
|
||||
aiMessageParser.setStatusParser(content -> {
|
||||
if (content != null && (boolean) content) {
|
||||
return MessageStatus.END;
|
||||
}
|
||||
return MessageStatus.MIDDLE;
|
||||
});
|
||||
|
||||
aiMessageParser.setTotalTokensPath("$.usage.token_count");
|
||||
aiMessageParser.setCompletionTokensPath("$.usage.output_count");
|
||||
aiMessageParser.setPromptTokensPath("$.usage.input_count");
|
||||
return aiMessageParser;
|
||||
}
|
||||
|
||||
public static FunctionMessageParser getFunctionMessageParser() {
|
||||
DefaultFunctionMessageParser functionMessageParser = new DefaultFunctionMessageParser();
|
||||
// TODO: function params
|
||||
functionMessageParser.setFunctionArgsParser(JSON::parseObject);
|
||||
return functionMessageParser;
|
||||
}
|
||||
|
||||
public static String promptToPayload(Prompt<?> prompt, CozeLlmConfig config, CozeChatOptions options, boolean stream) {
|
||||
return Maps.of()
|
||||
.put("bot_id", options.getBotId())
|
||||
.put("user_id", options.getUserId())
|
||||
.put("auto_save_history", true)
|
||||
.put("additional_messages", promptFormat.toMessagesJsonObject(prompt))
|
||||
.put( "stream", stream)
|
||||
.putIf(options.getCustomVariables() != null, "custom_variables", options.getCustomVariables())
|
||||
.toJSON();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2023-2025, Agents-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.agentsflex.llm.coze;
|
||||
|
||||
import com.agentsflex.core.message.AiMessage;
|
||||
|
||||
/**
|
||||
* @author yulsh
|
||||
*/
|
||||
public interface CozeRequestListener{
|
||||
|
||||
void onMessage(CozeChatContext context);
|
||||
|
||||
void onFailure(CozeChatContext context, Throwable throwable);
|
||||
|
||||
void onStop(CozeChatContext context);
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package com.agentsflex.llm.coze;
|
||||
|
||||
import com.agentsflex.core.llm.ChatContext;
|
||||
import com.agentsflex.core.llm.StreamResponseListener;
|
||||
import com.agentsflex.core.llm.response.AiMessageResponse;
|
||||
import com.agentsflex.core.message.AiMessage;
|
||||
import com.agentsflex.core.prompt.TextPrompt;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CozeLlmTest {
|
||||
|
||||
String token = "changeit";
|
||||
String botId = "changeit";
|
||||
String userId = "changeit";
|
||||
String textPrompt = "你是谁?告诉我你能干什么事情?并列出5点你能做的事情";
|
||||
CozeLlmConfig config;
|
||||
CozeLlm llm;
|
||||
CozeChatOptions options;
|
||||
|
||||
public CozeLlmTest() {
|
||||
config = new CozeLlmConfig();
|
||||
config.setApiKey(token);
|
||||
config.setDebug(true);
|
||||
|
||||
llm = new CozeLlm(config);
|
||||
options = new CozeChatOptions();
|
||||
options.setBotId(botId);
|
||||
options.setUserId(userId);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testChat() {
|
||||
TextPrompt prompt = new TextPrompt(textPrompt);
|
||||
AiMessageResponse response = llm.chat(prompt, options);
|
||||
AiMessage message = response.getMessage();
|
||||
|
||||
String content = message.getContent();
|
||||
System.out.println(content);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChatStream() {
|
||||
TextPrompt prompt = new TextPrompt(textPrompt);
|
||||
llm.chatStream(prompt, new StreamResponseListener<AiMessageResponse>() {
|
||||
@Override
|
||||
public void onMessage(ChatContext context, AiMessageResponse response) {
|
||||
AiMessage message = response.getMessage();
|
||||
System.out.print(message.getContent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(ChatContext context) {
|
||||
StreamResponseListener.super.onStart(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(ChatContext context) {
|
||||
// stop 后才能拿到 token 用量等信息
|
||||
CozeChatContext ccc = (CozeChatContext) context;
|
||||
System.out.println(ccc.getUsage());
|
||||
StreamResponseListener.super.onStop(context);
|
||||
}
|
||||
}, options);
|
||||
}
|
||||
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
<module>agents-flex-llm-chatglm</module>
|
||||
<module>agents-flex-llm-ollama</module>
|
||||
<module>agents-flex-llm-moonshot</module>
|
||||
<module>agents-flex-llm-coze</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
Loading…
Reference in New Issue
Block a user