This commit is contained in:
jack ning
2025-09-02 16:40:02 +08:00
parent 1a057da74e
commit 8b93a90e16
18 changed files with 51 additions and 169 deletions

View File

@@ -1,6 +1,6 @@
{
"/admin/umi.css": "/admin/umi.c10bed78.css",
"/admin/umi.js": "/admin/umi.0de25954.js",
"/admin/umi.js": "/admin/umi.3d8c620b.js",
"/admin/6848.6f03ea0d.async.js": "/admin/6848.6f03ea0d.async.js",
"/admin/7866.0cdcfa42.async.js": "/admin/7866.0cdcfa42.async.js",
"/admin/8593.9844b3fa.async.js": "/admin/8593.9844b3fa.async.js",
@@ -33,7 +33,7 @@
"/admin/p__Dashboard__Ai__LlmModel__index.js": "/admin/p__Dashboard__Ai__LlmModel__index.be4eaef1.async.js",
"/admin/p__Dashboard__Ai__Mcp__index.js": "/admin/p__Dashboard__Ai__Mcp__index.ab982c51.async.js",
"/admin/p__Dashboard__Ai__Prompt__index.css": "/admin/p__Dashboard__Ai__Prompt__index.f9c908ef.chunk.css",
"/admin/p__Dashboard__Ai__Prompt__index.js": "/admin/p__Dashboard__Ai__Prompt__index.31dcbf39.async.js",
"/admin/p__Dashboard__Ai__Prompt__index.js": "/admin/p__Dashboard__Ai__Prompt__index.d5daf660.async.js",
"/admin/p__Dashboard__Ai__Message__index.js": "/admin/p__Dashboard__Ai__Message__index.549bece4.async.js",
"/admin/p__Dashboard__Ai__Statistic__index.js": "/admin/p__Dashboard__Ai__Statistic__index.1be740b4.async.js",
"/admin/p__Dashboard__Kbase__index.js": "/admin/p__Dashboard__Kbase__index.64303c5e.async.js",

View File

@@ -7,10 +7,10 @@
<link rel="shortcut icon" href="/admin/favicon.ico">
<title>微语</title>
<link rel="stylesheet" href="/admin/umi.c10bed78.css">
<script src="/admin/preload_helper.a09969ae.js"></script>
<script src="/admin/preload_helper.7fc5cf75.js"></script>
</head>
<body>
<div id="root"></div>
<script src="/admin/umi.0de25954.js"></script>
<script src="/admin/umi.3d8c620b.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2024-03-22 16:44:41
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-08-20 13:20:46
* @LastEditTime: 2025-09-02 16:19:31
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -637,7 +637,12 @@ public class RobotRestService extends BaseRestServiceWithExport<RobotEntity, Rob
robot.setType(RobotTypeEnum.LLM.name());
// robot.setDefaultReply(I18Consts.I18N_ROBOT_DEFAULT_REPLY);
//
RobotLlm llm = RobotLlm.builder().prompt(request.getLlm().getPrompt()).build();
RobotLlm llm = RobotLlm.builder()
.prompt(request.getLlm().getPrompt())
.textProvider(request.getLlm().getTextProvider())
.textProviderUid(request.getLlm().getTextProviderUid())
.textModel(request.getLlm().getTextModel())
.build();
robot.setLlm(llm);
//
RobotEntity savedRobot = save(robot);
@@ -666,6 +671,7 @@ public class RobotRestService extends BaseRestServiceWithExport<RobotEntity, Rob
RobotLlm llm = robot.getLlm();
llm.setPrompt(request.getLlm().getPrompt());
llm.setTextProvider(request.getLlm().getTextProvider());
llm.setTextProviderUid(request.getLlm().getTextProviderUid());
llm.setTextModel(request.getLlm().getTextModel());
robot.setLlm(llm);
//

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2025-05-21 14:23:55
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-05-23 12:19:08
* @LastEditTime: 2025-09-02 16:03:28
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -44,6 +44,7 @@ import lombok.extern.slf4j.Slf4j;
public class RobotAgentService {
private final RobotRestService robotRestService;
private final SpringAIServiceRegistry springAIServiceRegistry;
/**
@@ -61,6 +62,7 @@ public class RobotAgentService {
// 使用新添加的接口方法直接调用大模型并获取结果
RobotProtobuf robot = RobotProtobuf.convertFromRobotEntity(robotOptional.get());
//
return service.processDirectLlmRequest(query, robot);
} catch (IllegalArgumentException e) {

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2025-02-28 11:44:03
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-08-21 15:20:02
* @LastEditTime: 2025-09-02 16:34:02
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -186,13 +186,13 @@ public class SpringAIBaiduService extends BaseSpringAIService {
// 从robot中获取llm配置
RobotLlm llm = robot.getLlm();
if (llm == null) {
return "Baidu service is not available";
return I18Consts.I18N_SERVICE_TEMPORARILY_UNAVAILABLE;
}
// 获取适当的模型实例
OpenAiChatModel baiduChatModel = createBaiduChatModel(llm);
if (baiduChatModel == null) {
return "Baidu service is not available";
return I18Consts.I18N_SERVICE_TEMPORARILY_UNAVAILABLE;
}
try {
@@ -245,7 +245,7 @@ public class SpringAIBaiduService extends BaseSpringAIService {
RobotLlm llm = robot.getLlm();
if (llm == null) {
handleSseError(new RuntimeException("Baidu service not available"), messageProtobufQuery,
handleSseError(new RuntimeException(I18Consts.I18N_SERVICE_TEMPORARILY_UNAVAILABLE), messageProtobufQuery,
messageProtobufReply, emitter);
return;
}
@@ -253,7 +253,7 @@ public class SpringAIBaiduService extends BaseSpringAIService {
// 获取适当的模型实例
OpenAiChatModel baiduChatModel = createBaiduChatModel(llm);
if (baiduChatModel == null) {
handleSseError(new RuntimeException("Baidu service not available"), messageProtobufQuery,
handleSseError(new RuntimeException(I18Consts.I18N_SERVICE_TEMPORARILY_UNAVAILABLE), messageProtobufQuery,
messageProtobufReply, emitter);
return;
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2025-02-28 11:44:03
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-09-02 14:57:56
* @LastEditTime: 2025-09-02 16:35:39
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -164,7 +164,7 @@ public class SpringAIVolcengineService extends BaseSpringAIService {
// 创建动态chatModel
OpenAiChatModel chatModel = createVolcengineChatModel(robot.getLlm());
if (chatModel == null) {
return "Volcengine service is not available";
return I18Consts.I18N_SERVICE_TEMPORARILY_UNAVAILABLE;
}
try {
@@ -216,7 +216,7 @@ public class SpringAIVolcengineService extends BaseSpringAIService {
// 创建动态chatModel
OpenAiChatModel chatModel = createVolcengineChatModel(llm);
if (chatModel == null) {
handleSseError(new RuntimeException("Volcengine service not available"), messageProtobufQuery, messageProtobufReply, emitter);
handleSseError(new RuntimeException(I18Consts.I18N_SERVICE_TEMPORARILY_UNAVAILABLE), messageProtobufQuery, messageProtobufReply, emitter);
return;
}

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2025-02-19 09:39:15
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-08-21 12:38:11
* @LastEditTime: 2025-09-02 16:32:18
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -148,25 +148,7 @@ public class ZhipuaiController {
return ResponseEntity.ok(JsonResult.error("Error: " + e.getMessage()));
}
}
/**
* 健康检查
*/
@GetMapping("/health")
public ResponseEntity<JsonResult<?>> health() {
if (!bytedeskProperties.getDebug()) {
return ResponseEntity.ok(JsonResult.error("Zhipuai service is not available"));
}
try {
boolean healthy = zhipuaiService.isHealthy();
return ResponseEntity.ok(JsonResult.success(healthy ? "ok" : "fail"));
} catch (Exception e) {
log.error("Error in health check", e);
return ResponseEntity.ok(JsonResult.error("Error: " + e.getMessage()));
}
}
/**
* Function Calling 同步调用
* POST http://127.0.0.1:9003/zhipuai/function-call

View File

@@ -2,7 +2,7 @@
* @Author: jackning 270580156@qq.com
* @Date: 2025-02-19 09:39:15
* @LastEditors: jackning 270580156@qq.com
* @LastEditTime: 2025-08-24 17:38:54
* @LastEditTime: 2025-09-02 16:35:19
* @Description: bytedesk.com https://github.com/Bytedesk/bytedesk
* Please be aware of the BSL license restrictions before installing Bytedesk IM
* selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license.
@@ -198,6 +198,11 @@ public class ZhipuaiService extends BaseSpringAIService {
// 获取适当的client实例
ClientV4 chatClient = createDynamicClient(llm);
if (chatClient == null) {
log.error("Failed to create Zhipuai client, cannot process websocket request");
sendMessageWebsocket(MessageTypeEnum.ERROR, I18Consts.I18N_SERVICE_TEMPORARILY_UNAVAILABLE, messageProtobufReply);
return;
}
try {
ChatCompletionRequest chatCompletionRequest = createDynamicRequestFromPrompt(llm, prompt, true);
@@ -333,6 +338,10 @@ public class ZhipuaiService extends BaseSpringAIService {
// 获取适当的client实例
ClientV4 chatClient = createDynamicClient(llm);
if (chatClient == null) {
log.error("Failed to create Zhipuai client, cannot process sync request");
return I18Consts.I18N_SERVICE_TEMPORARILY_UNAVAILABLE;
}
try {
ChatCompletionRequest chatCompletionRequest = createDynamicRequest(llm, message, false);
@@ -396,6 +405,12 @@ public class ZhipuaiService extends BaseSpringAIService {
// 获取适当的client实例
ClientV4 chatClient = createDynamicClient(llm);
if (chatClient == null) {
log.error("Failed to create Zhipuai client, cannot process SSE request");
handleSseError(new Exception("Failed to create Zhipuai client"),
messageProtobufQuery, messageProtobufReply, emitter);
return;
}
try {
ChatCompletionRequest chatCompletionRequest = createDynamicRequestFromPrompt(llm, prompt, true);
@@ -979,127 +994,4 @@ public class ZhipuaiService extends BaseSpringAIService {
}
}
/**
* 简单流式测试 - 完全按照官方示例代码实现
* 用于调试流式响应问题
*/
// public void testSimpleStream() {
// // 使用默认client进行简单测试
// ClientV4 chatClient = client;
// try {
// log.info("Zhipuai API testing simple stream response...");
// // 完全按照官方示例代码实现
// List<ChatMessage> messages = new ArrayList<>();
// ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(), "What is the relationship between ZhipuAI and ChatGLM?");
// messages.add(chatMessage);
// String requestId = String.format("your-request-id-%d", System.currentTimeMillis());
// ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
// .model(Constants.ModelChatGLM4)
// .stream(Boolean.TRUE)
// .messages(messages)
// .requestId(requestId)
// .build();
// log.info("Zhipuai API making simple stream test call with requestId: {}", requestId);
// ModelApiResponse sseModelApiResp = chatClient.invokeModelApi(chatCompletionRequest);
// if (sseModelApiResp.isSuccess()) {
// log.info("Zhipuai API simple stream test response success");
// // java.util.concurrent.atomic.AtomicBoolean isFirst = new java.util.concurrent.atomic.AtomicBoolean(true);
// final int[] messageCount = {0};
// mapStreamToAccumulator(sseModelApiResp.getFlowable())
// .doOnNext(accumulator -> {
// messageCount[0]++;
// log.info("Zhipuai API simple stream test message #{}: accumulator: {}", messageCount[0], accumulator);
// Object delta = accumulator.getDelta();
// log.info("Zhipuai API simple stream test message #{}: delta: {}", messageCount[0], delta);
// if (delta instanceof com.zhipu.oapi.service.v4.model.ChatMessage) {
// Object content = ((com.zhipu.oapi.service.v4.model.ChatMessage) delta).getContent();
// log.info("Zhipuai API simple stream test message #{}: content: {}", messageCount[0], content);
// }
// })
// .doOnComplete(() -> {
// log.info("Zhipuai API simple stream test completed, total messages: {}", messageCount[0]);
// })
// .doOnError(error -> {
// log.error("Zhipuai API simple stream test error: ", error);
// })
// .subscribe();
// } else {
// log.error("Zhipuai API simple stream test failed: {}", sseModelApiResp.getError());
// }
// } catch (Exception e) {
// log.error("Zhipuai API test simple stream error", e);
// }
// }
/**
* 测试content提取功能
*/
public void testContentExtraction() {
log.info("Zhipuai API testing content extraction...");
// 测试用例1标准的JSON格式
String test1 = "{\"role\":\"assistant\",\"content\":\"\",\"tool_calls\":[]}";
String result1 = extractContentFromDeltaString(test1);
log.info("Test 1 - Input: {}, Result: {}", test1, result1);
// 测试用例2content为空的情况
String test2 = "{\"role\":\"assistant\",\"content\":\"\",\"tool_calls\":[]}";
String result2 = extractContentFromDeltaString(test2);
log.info("Test 2 - Input: {}, Result: {}", test2, result2);
// 测试用例3content为null的情况
String test3 = "{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[]}";
String result3 = extractContentFromDeltaString(test3);
log.info("Test 3 - Input: {}, Result: {}", test3, result3);
// 测试用例4包含特殊字符的content
String test4 = "{\"role\":\"assistant\",\"content\":\"Hello, world! 你好世界!\",\"tool_calls\":[]}";
String result4 = extractContentFromDeltaString(test4);
log.info("Test 4 - Input: {}, Result: {}", test4, result4);
// 测试用例5不是JSON格式的字符串
String test5 = "Hello, world!";
String result5 = extractContentFromDeltaString(test5);
log.info("Test 5 - Input: {}, Result: {}", test5, result5);
// 测试用例6null输入
String result6 = extractContentFromDeltaString(null);
log.info("Test 6 - Input: null, Result: {}", result6);
// 测试用例7空字符串
String result7 = extractContentFromDeltaString("");
log.info("Test 7 - Input: empty string, Result: {}", result7);
}
/**
* 检查服务健康状态
*/
public boolean isHealthy() {
log.info("Zhipuai API health check started");
try {
// 发送一个简单的测试请求
String response = processPromptSync("Hello", null, "");
boolean isHealthy = response != null && !response.startsWith("Error");
log.info("Zhipuai API health check result: {}", isHealthy);
return isHealthy;
} catch (Exception e) {
log.error("Zhipuai API health check failed", e);
return false;
}
}
}

View File

@@ -1,6 +1,6 @@
{
"/admin/umi.css": "/admin/umi.c10bed78.css",
"/admin/umi.js": "/admin/umi.0de25954.js",
"/admin/umi.js": "/admin/umi.3d8c620b.js",
"/admin/6848.6f03ea0d.async.js": "/admin/6848.6f03ea0d.async.js",
"/admin/7866.0cdcfa42.async.js": "/admin/7866.0cdcfa42.async.js",
"/admin/8593.9844b3fa.async.js": "/admin/8593.9844b3fa.async.js",
@@ -33,7 +33,7 @@
"/admin/p__Dashboard__Ai__LlmModel__index.js": "/admin/p__Dashboard__Ai__LlmModel__index.be4eaef1.async.js",
"/admin/p__Dashboard__Ai__Mcp__index.js": "/admin/p__Dashboard__Ai__Mcp__index.ab982c51.async.js",
"/admin/p__Dashboard__Ai__Prompt__index.css": "/admin/p__Dashboard__Ai__Prompt__index.f9c908ef.chunk.css",
"/admin/p__Dashboard__Ai__Prompt__index.js": "/admin/p__Dashboard__Ai__Prompt__index.31dcbf39.async.js",
"/admin/p__Dashboard__Ai__Prompt__index.js": "/admin/p__Dashboard__Ai__Prompt__index.d5daf660.async.js",
"/admin/p__Dashboard__Ai__Message__index.js": "/admin/p__Dashboard__Ai__Message__index.549bece4.async.js",
"/admin/p__Dashboard__Ai__Statistic__index.js": "/admin/p__Dashboard__Ai__Statistic__index.1be740b4.async.js",
"/admin/p__Dashboard__Kbase__index.js": "/admin/p__Dashboard__Kbase__index.64303c5e.async.js",

View File

@@ -7,10 +7,10 @@
<link rel="shortcut icon" href="/admin/favicon.ico">
<title>微语</title>
<link rel="stylesheet" href="/admin/umi.c10bed78.css">
<script src="/admin/preload_helper.a09969ae.js"></script>
<script src="/admin/preload_helper.7fc5cf75.js"></script>
</head>
<body>
<div id="root"></div>
<script src="/admin/umi.0de25954.js"></script>
<script src="/admin/umi.3d8c620b.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long