mirror of
https://gitee.com/270580156/weiyu.git
synced 2025-12-30 10:52:26 +00:00
update
This commit is contained in:
@@ -284,14 +284,14 @@ services:
|
||||
# https://bailian.console.aliyun.com/?spm=a2c4g.11186623.0.0.11c67980m5X2VR#/model-market
|
||||
SPRING_AI_DASHSCOPE_BASE_URL: https://dashscope.aliyuncs.com/compatible-mode
|
||||
SPRING_AI_DASHSCOPE_API_KEY: 'sk-xxx'
|
||||
SPRING_AI_DASHSCOPE_CHAT_ENABLED: false
|
||||
SPRING_AI_DASHSCOPE_CHAT_ENABLED: "false"
|
||||
SPRING_AI_DASHSCOPE_CHAT_OPTIONS_MODEL: deepseek-r1
|
||||
SPRING_AI_DASHSCOPE_CHAT_OPTIONS_TEMPERATURE: 0.7
|
||||
SPRING_AI_DASHSCOPE_AUDIO_TRANSCRIPTION_ENABLED: false
|
||||
SPRING_AI_DASHSCOPE_IMAGE_ENABLED: false
|
||||
SPRING_AI_DASHSCOPE_EMBEDDING_ENABLED: false
|
||||
SPRING_AI_DASHSCOPE_AUDIO_SYNTHESIS_ENABLED: false
|
||||
SPRING_AI_NACOS_PROMPT_TEMPLATE_ENABLED: false
|
||||
SPRING_AI_DASHSCOPE_AUDIO_TRANSCRIPTION_ENABLED: "false"
|
||||
SPRING_AI_DASHSCOPE_IMAGE_ENABLED: "false"
|
||||
SPRING_AI_DASHSCOPE_EMBEDDING_ENABLED: "false"
|
||||
SPRING_AI_DASHSCOPE_AUDIO_SYNTHESIS_ENABLED: "false"
|
||||
SPRING_AI_NACOS_PROMPT_TEMPLATE_ENABLED: "false"
|
||||
# logging config
|
||||
LOGGING_LEVEL_COM_BYTEDESK_AI: DEBUG
|
||||
LOGGING_LEVEL_COM_BYTEDESK_CORE: DEBUG
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 412 KiB After Width: | Height: | Size: 478 KiB |
@@ -125,11 +125,11 @@
|
||||
|
||||
<!-- https://github.com/alibaba/spring-ai-alibaba -->
|
||||
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud.ai/spring-ai-alibaba-starter-dashscope -->
|
||||
<dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>com.alibaba.cloud.ai</groupId>
|
||||
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
|
||||
<version>${spring-ai-alibaba.version}</version>
|
||||
</dependency>
|
||||
</dependency> -->
|
||||
|
||||
<!-- ///////////////////////////////////////////////////////////////////////////// -->
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2025-02-17 11:17:28
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-07-11 09:08:46
|
||||
* @LastEditTime: 2025-07-11 10:03:16
|
||||
* @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.
|
||||
@@ -13,61 +13,61 @@
|
||||
*/
|
||||
package com.bytedesk.ai.springai.providers.dashscope;
|
||||
|
||||
// import org.springframework.ai.chat.client.ChatClient;
|
||||
// import org.springframework.ai.openai.OpenAiChatModel;
|
||||
// import org.springframework.ai.openai.OpenAiChatOptions;
|
||||
// import org.springframework.ai.openai.api.OpenAiApi;
|
||||
// import org.springframework.beans.factory.annotation.Value;
|
||||
// import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
// import org.springframework.context.annotation.Bean;
|
||||
// import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ai.chat.client.ChatClient;
|
||||
import org.springframework.ai.openai.OpenAiChatModel;
|
||||
import org.springframework.ai.openai.OpenAiChatOptions;
|
||||
import org.springframework.ai.openai.api.OpenAiApi;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
|
||||
// @Configuration
|
||||
// @ConditionalOnProperty(name = "spring.ai.dashscope.chat.enabled", havingValue = "true", matchIfMissing = false)
|
||||
// public class SpringAIDashscopeConfig {
|
||||
@Configuration
|
||||
@ConditionalOnProperty(name = "spring.ai.dashscope.chat.enabled", havingValue = "true", matchIfMissing = false)
|
||||
public class SpringAIDashscopeConfig {
|
||||
|
||||
// @Value("${spring.ai.dashscope.base-url:https://dashscope.aliyuncs.com/compatible-mode}")
|
||||
// private String baseUrl;
|
||||
@Value("${spring.ai.dashscope.base-url:https://dashscope.aliyuncs.com/compatible-mode}")
|
||||
private String baseUrl;
|
||||
|
||||
// @Value("${spring.ai.dashscope.api-key:sk-xxx}")
|
||||
// private String apiKey;
|
||||
@Value("${spring.ai.dashscope.api-key:sk-xxx}")
|
||||
private String apiKey;
|
||||
|
||||
// @Value("${spring.ai.dashscope.chat.options.model:deepseek-r1}")
|
||||
// private String model;
|
||||
@Value("${spring.ai.dashscope.chat.options.model:deepseek-r1}")
|
||||
private String model;
|
||||
|
||||
// @Value("${spring.ai.dashscope.chat.options.temperature:0.7}")
|
||||
// private Double temperature;
|
||||
@Value("${spring.ai.dashscope.chat.options.temperature:0.7}")
|
||||
private Double temperature;
|
||||
|
||||
// @Bean("dashscopeApi")
|
||||
// OpenAiApi dashscopeApi() {
|
||||
// return OpenAiApi.builder()
|
||||
// .baseUrl(baseUrl)
|
||||
// .apiKey(apiKey)
|
||||
// .build();
|
||||
// }
|
||||
@Bean("dashscopeApi")
|
||||
OpenAiApi dashscopeApi() {
|
||||
return OpenAiApi.builder()
|
||||
.baseUrl(baseUrl)
|
||||
.apiKey(apiKey)
|
||||
.build();
|
||||
}
|
||||
|
||||
// @Bean("dashscopeChatOptions")
|
||||
// OpenAiChatOptions dashscopeChatOptions() {
|
||||
// return OpenAiChatOptions.builder()
|
||||
// .model(model)
|
||||
// .temperature(temperature)
|
||||
// .build();
|
||||
// }
|
||||
@Bean("dashscopeChatOptions")
|
||||
OpenAiChatOptions dashscopeChatOptions() {
|
||||
return OpenAiChatOptions.builder()
|
||||
.model(model)
|
||||
.temperature(temperature)
|
||||
.build();
|
||||
}
|
||||
|
||||
// @Bean("dashscopeChatModel")
|
||||
// OpenAiChatModel dashscopeChatModel() {
|
||||
// return OpenAiChatModel.builder()
|
||||
// .openAiApi(dashscopeApi())
|
||||
// .defaultOptions(dashscopeChatOptions())
|
||||
// .build();
|
||||
// }
|
||||
@Bean("dashscopeChatModel")
|
||||
OpenAiChatModel dashscopeChatModel() {
|
||||
return OpenAiChatModel.builder()
|
||||
.openAiApi(dashscopeApi())
|
||||
.defaultOptions(dashscopeChatOptions())
|
||||
.build();
|
||||
}
|
||||
|
||||
// @Bean("dashscopeChatClient")
|
||||
// ChatClient dashscopeChatClient() {
|
||||
// return ChatClient.builder(dashscopeChatModel())
|
||||
// .defaultOptions(dashscopeChatOptions())
|
||||
// .build();
|
||||
// }
|
||||
@Bean("dashscopeChatClient")
|
||||
ChatClient dashscopeChatClient() {
|
||||
return ChatClient.builder(dashscopeChatModel())
|
||||
.defaultOptions(dashscopeChatOptions())
|
||||
.build();
|
||||
}
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -13,136 +13,136 @@
|
||||
*/
|
||||
package com.bytedesk.ai.springai.providers.dashscope;
|
||||
|
||||
// import java.util.concurrent.ExecutorService;
|
||||
// import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
// import org.springframework.ai.chat.messages.UserMessage;
|
||||
// import org.springframework.ai.chat.model.ChatResponse;
|
||||
// import org.springframework.ai.chat.prompt.Prompt;
|
||||
// import org.springframework.ai.openai.OpenAiChatModel;
|
||||
// import org.springframework.ai.openai.OpenAiChatOptions;
|
||||
// import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
// import org.springframework.http.MediaType;
|
||||
// import org.springframework.http.ResponseEntity;
|
||||
// import org.springframework.web.bind.annotation.GetMapping;
|
||||
// import org.springframework.web.bind.annotation.RequestMapping;
|
||||
// import org.springframework.web.bind.annotation.RequestParam;
|
||||
// import org.springframework.web.bind.annotation.RestController;
|
||||
// import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
import org.springframework.ai.chat.messages.UserMessage;
|
||||
import org.springframework.ai.chat.model.ChatResponse;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
import org.springframework.ai.openai.OpenAiChatModel;
|
||||
import org.springframework.ai.openai.OpenAiChatOptions;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
// import com.bytedesk.core.utils.JsonResult;
|
||||
import com.bytedesk.core.utils.JsonResult;
|
||||
|
||||
// import lombok.RequiredArgsConstructor;
|
||||
// import lombok.extern.slf4j.Slf4j;
|
||||
// import reactor.core.publisher.Flux;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
// /**
|
||||
// * DeepSeek接口
|
||||
// */
|
||||
// @Slf4j
|
||||
// @RestController
|
||||
// @RequestMapping("/springai/dashscope")
|
||||
// @RequiredArgsConstructor
|
||||
// @ConditionalOnProperty(name = "spring.ai.dashscope.chat.enabled", havingValue = "true", matchIfMissing = false)
|
||||
// public class SpringAIDashscopeController {
|
||||
/**
|
||||
* DeepSeek接口
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/springai/dashscope")
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(name = "spring.ai.dashscope.chat.enabled", havingValue = "true", matchIfMissing = false)
|
||||
public class SpringAIDashscopeController {
|
||||
|
||||
// private final SpringAIDashscopeService springAIDashscopeService;
|
||||
// private final ExecutorService executorService = Executors.newCachedThreadPool();
|
||||
private final SpringAIDashscopeService springAIDashscopeService;
|
||||
private final ExecutorService executorService = Executors.newCachedThreadPool();
|
||||
|
||||
// /**
|
||||
// * 方式1:同步调用
|
||||
// * http://127.0.0.1:9003/springai/dashscope/chat/sync?message=hello
|
||||
// */
|
||||
// @GetMapping("/chat/sync")
|
||||
// public ResponseEntity<JsonResult<?>> chatSync(
|
||||
// @RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
|
||||
// String response = springAIDashscopeService.processPromptSync(message, null);
|
||||
// return ResponseEntity.ok(JsonResult.success(response));
|
||||
// }
|
||||
/**
|
||||
* 方式1:同步调用
|
||||
* http://127.0.0.1:9003/springai/dashscope/chat/sync?message=hello
|
||||
*/
|
||||
@GetMapping("/chat/sync")
|
||||
public ResponseEntity<JsonResult<?>> chatSync(
|
||||
@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
|
||||
String response = springAIDashscopeService.processPromptSync(message, null);
|
||||
return ResponseEntity.ok(JsonResult.success(response));
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 方式2:异步流式调用
|
||||
// * http://127.0.0.1:9003/springai/dashscope/chat/stream?message=hello
|
||||
// */
|
||||
// @GetMapping("/chat/stream")
|
||||
// public Flux<ChatResponse> chatStream(
|
||||
// @RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
|
||||
// Prompt prompt = new Prompt(new UserMessage(message));
|
||||
// OpenAiChatModel model = springAIDashscopeService.getChatModel();
|
||||
// if (model != null) {
|
||||
// return model.stream(prompt);
|
||||
// } else {
|
||||
// return Flux.empty();
|
||||
// }
|
||||
// }
|
||||
/**
|
||||
* 方式2:异步流式调用
|
||||
* http://127.0.0.1:9003/springai/dashscope/chat/stream?message=hello
|
||||
*/
|
||||
@GetMapping("/chat/stream")
|
||||
public Flux<ChatResponse> chatStream(
|
||||
@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
|
||||
Prompt prompt = new Prompt(new UserMessage(message));
|
||||
OpenAiChatModel model = springAIDashscopeService.getChatModel();
|
||||
if (model != null) {
|
||||
return model.stream(prompt);
|
||||
} else {
|
||||
return Flux.empty();
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 方式3:SSE调用
|
||||
// * http://127.0.0.1:9003/springai/dashscope/chat/sse?message=hello
|
||||
// */
|
||||
// @GetMapping(value = "/chat/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||
// public SseEmitter chatSSE(
|
||||
// @RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
|
||||
/**
|
||||
* 方式3:SSE调用
|
||||
* http://127.0.0.1:9003/springai/dashscope/chat/sse?message=hello
|
||||
*/
|
||||
@GetMapping(value = "/chat/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||
public SseEmitter chatSSE(
|
||||
@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
|
||||
|
||||
// SseEmitter emitter = new SseEmitter(180_000L); // 3分钟超时
|
||||
SseEmitter emitter = new SseEmitter(180_000L); // 3分钟超时
|
||||
|
||||
// executorService.execute(() -> {
|
||||
// try {
|
||||
// // springAIDashscopeService.processPromptSSE(message, emitter);
|
||||
// } catch (Exception e) {
|
||||
// log.error("Error processing SSE request", e);
|
||||
// emitter.completeWithError(e);
|
||||
// }
|
||||
// });
|
||||
executorService.execute(() -> {
|
||||
try {
|
||||
// springAIDashscopeService.processPromptSSE(message, emitter);
|
||||
} catch (Exception e) {
|
||||
log.error("Error processing SSE request", e);
|
||||
emitter.completeWithError(e);
|
||||
}
|
||||
});
|
||||
|
||||
// // 添加超时和完成时的回调
|
||||
// emitter.onTimeout(() -> {
|
||||
// log.warn("SSE connection timed out");
|
||||
// emitter.complete();
|
||||
// });
|
||||
// 添加超时和完成时的回调
|
||||
emitter.onTimeout(() -> {
|
||||
log.warn("SSE connection timed out");
|
||||
emitter.complete();
|
||||
});
|
||||
|
||||
// emitter.onCompletion(() -> {
|
||||
// log.info("SSE connection completed");
|
||||
// });
|
||||
emitter.onCompletion(() -> {
|
||||
log.info("SSE connection completed");
|
||||
});
|
||||
|
||||
// return emitter;
|
||||
// }
|
||||
return emitter;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 自定义模型参数的调用示例
|
||||
// * http://127.0.0.1:9003/springai/dashscope/chat/custom?message=hello
|
||||
// */
|
||||
// @GetMapping("/chat/custom")
|
||||
// public ResponseEntity<?> chatCustom(
|
||||
// @RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
|
||||
/**
|
||||
* 自定义模型参数的调用示例
|
||||
* http://127.0.0.1:9003/springai/dashscope/chat/custom?message=hello
|
||||
*/
|
||||
@GetMapping("/chat/custom")
|
||||
public ResponseEntity<?> chatCustom(
|
||||
@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
|
||||
|
||||
// OpenAiChatModel model = springAIDashscopeService.getChatModel();
|
||||
// if (model == null) {
|
||||
// return ResponseEntity.ok(JsonResult.error("DeepSeek service is not available"));
|
||||
// }
|
||||
OpenAiChatModel model = springAIDashscopeService.getChatModel();
|
||||
if (model == null) {
|
||||
return ResponseEntity.ok(JsonResult.error("DeepSeek service is not available"));
|
||||
}
|
||||
|
||||
// try {
|
||||
// ChatResponse response = model.call(
|
||||
// new Prompt(
|
||||
// message,
|
||||
// OpenAiChatOptions.builder()
|
||||
// .model("dashscope-chat")
|
||||
// .temperature(0.7)
|
||||
// .topP(0.9)
|
||||
// .build()
|
||||
// ));
|
||||
try {
|
||||
ChatResponse response = model.call(
|
||||
new Prompt(
|
||||
message,
|
||||
OpenAiChatOptions.builder()
|
||||
.model("dashscope-chat")
|
||||
.temperature(0.7)
|
||||
.topP(0.9)
|
||||
.build()
|
||||
));
|
||||
|
||||
// String result = response.getResult().getOutput().getText();
|
||||
// return ResponseEntity.ok(JsonResult.success(result));
|
||||
// } catch (Exception e) {
|
||||
// return ResponseEntity.ok(JsonResult.error(e.getMessage()));
|
||||
// }
|
||||
// }
|
||||
String result = response.getResult().getOutput().getText();
|
||||
return ResponseEntity.ok(JsonResult.success(result));
|
||||
} catch (Exception e) {
|
||||
return ResponseEntity.ok(JsonResult.error(e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
// // 在 Bean 销毁时关闭线程池
|
||||
// public void destroy() {
|
||||
// if (executorService != null && !executorService.isShutdown()) {
|
||||
// executorService.shutdown();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// 在 Bean 销毁时关闭线程池
|
||||
public void destroy() {
|
||||
if (executorService != null && !executorService.isShutdown()) {
|
||||
executorService.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2025-02-28 11:44:03
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-07-11 09:08:55
|
||||
* @LastEditTime: 2025-07-11 10:03:26
|
||||
* @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.
|
||||
@@ -13,190 +13,190 @@
|
||||
*/
|
||||
package com.bytedesk.ai.springai.providers.dashscope;
|
||||
|
||||
// import java.util.List;
|
||||
import java.util.List;
|
||||
|
||||
// import org.springframework.ai.chat.messages.AssistantMessage;
|
||||
// import org.springframework.ai.chat.model.Generation;
|
||||
// import org.springframework.ai.chat.prompt.Prompt;
|
||||
// import org.springframework.ai.openai.OpenAiChatModel;
|
||||
// import org.springframework.ai.openai.OpenAiChatOptions;
|
||||
// import org.springframework.beans.factory.annotation.Autowired;
|
||||
// import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
// import org.springframework.stereotype.Service;
|
||||
// import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
import org.springframework.ai.chat.messages.AssistantMessage;
|
||||
import org.springframework.ai.chat.model.Generation;
|
||||
import org.springframework.ai.chat.prompt.Prompt;
|
||||
import org.springframework.ai.openai.OpenAiChatModel;
|
||||
import org.springframework.ai.openai.OpenAiChatOptions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
// import com.bytedesk.ai.robot.RobotLlm;
|
||||
// import com.bytedesk.ai.robot.RobotProtobuf;
|
||||
// import com.bytedesk.ai.springai.service.BaseSpringAIService;
|
||||
// import com.bytedesk.core.message.MessageProtobuf;
|
||||
// import com.bytedesk.core.message.MessageTypeEnum;
|
||||
import com.bytedesk.ai.robot.RobotLlm;
|
||||
import com.bytedesk.ai.robot.RobotProtobuf;
|
||||
import com.bytedesk.ai.springai.service.BaseSpringAIService;
|
||||
import com.bytedesk.core.message.MessageProtobuf;
|
||||
import com.bytedesk.core.message.MessageTypeEnum;
|
||||
|
||||
// import lombok.extern.slf4j.Slf4j;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
// @Slf4j
|
||||
// @Service
|
||||
// @ConditionalOnProperty(name = "spring.ai.dashscope.chat.enabled", havingValue = "true", matchIfMissing = false)
|
||||
// public class SpringAIDashscopeService extends BaseSpringAIService {
|
||||
@Slf4j
|
||||
@Service
|
||||
@ConditionalOnProperty(name = "spring.ai.dashscope.chat.enabled", havingValue = "true", matchIfMissing = false)
|
||||
public class SpringAIDashscopeService extends BaseSpringAIService {
|
||||
|
||||
// @Autowired(required = false)
|
||||
// private OpenAiChatModel dashscopeChatModel;
|
||||
@Autowired(required = false)
|
||||
private OpenAiChatModel dashscopeChatModel;
|
||||
|
||||
// public SpringAIDashscopeService() {
|
||||
// super(); // 调用基类的无参构造函数
|
||||
// }
|
||||
public SpringAIDashscopeService() {
|
||||
super(); // 调用基类的无参构造函数
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 根据机器人配置创建动态的OpenAiChatOptions
|
||||
// *
|
||||
// * @param llm 机器人LLM配置
|
||||
// * @return 根据机器人配置创建的选项
|
||||
// */
|
||||
// private OpenAiChatOptions createDynamicOptions(RobotLlm llm) {
|
||||
// return super.createDynamicOptions(llm, robotLlm ->
|
||||
// OpenAiChatOptions.builder()
|
||||
// .model(robotLlm.getModel())
|
||||
// .temperature(robotLlm.getTemperature())
|
||||
// .topP(robotLlm.getTopP())
|
||||
// .build()
|
||||
// );
|
||||
// }
|
||||
/**
|
||||
* 根据机器人配置创建动态的OpenAiChatOptions
|
||||
*
|
||||
* @param llm 机器人LLM配置
|
||||
* @return 根据机器人配置创建的选项
|
||||
*/
|
||||
private OpenAiChatOptions createDynamicOptions(RobotLlm llm) {
|
||||
return super.createDynamicOptions(llm, robotLlm ->
|
||||
OpenAiChatOptions.builder()
|
||||
.model(robotLlm.getModel())
|
||||
.temperature(robotLlm.getTemperature())
|
||||
.topP(robotLlm.getTopP())
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected void processPromptWebsocket(Prompt prompt, RobotProtobuf robot, MessageProtobuf messageProtobufQuery, MessageProtobuf messageProtobufReply) {
|
||||
// // 从robot中获取llm配置
|
||||
// RobotLlm llm = robot.getLlm();
|
||||
@Override
|
||||
protected void processPromptWebsocket(Prompt prompt, RobotProtobuf robot, MessageProtobuf messageProtobufQuery, MessageProtobuf messageProtobufReply) {
|
||||
// 从robot中获取llm配置
|
||||
RobotLlm llm = robot.getLlm();
|
||||
|
||||
// if (dashscopeChatModel == null) {
|
||||
// sendMessageWebsocket(MessageTypeEnum.ERROR, "Dashscope服务不可用", messageProtobufReply);
|
||||
// return;
|
||||
// }
|
||||
if (dashscopeChatModel == null) {
|
||||
sendMessageWebsocket(MessageTypeEnum.ERROR, "Dashscope服务不可用", messageProtobufReply);
|
||||
return;
|
||||
}
|
||||
|
||||
// // 如果有自定义选项,创建新的Prompt
|
||||
// Prompt requestPrompt = prompt;
|
||||
// OpenAiChatOptions customOptions = createDynamicOptions(llm);
|
||||
// if (customOptions != null) {
|
||||
// requestPrompt = new Prompt(prompt.getInstructions(), customOptions);
|
||||
// }
|
||||
// 如果有自定义选项,创建新的Prompt
|
||||
Prompt requestPrompt = prompt;
|
||||
OpenAiChatOptions customOptions = createDynamicOptions(llm);
|
||||
if (customOptions != null) {
|
||||
requestPrompt = new Prompt(prompt.getInstructions(), customOptions);
|
||||
}
|
||||
|
||||
// // 使用同一个ChatModel实例,但传入不同的选项
|
||||
// dashscopeChatModel.stream(requestPrompt).subscribe(
|
||||
// response -> {
|
||||
// if (response != null) {
|
||||
// log.info("Dashscope API response metadata: {}", response.getMetadata());
|
||||
// List<Generation> generations = response.getResults();
|
||||
// for (Generation generation : generations) {
|
||||
// AssistantMessage assistantMessage = generation.getOutput();
|
||||
// String textContent = assistantMessage.getText();
|
||||
// 使用同一个ChatModel实例,但传入不同的选项
|
||||
dashscopeChatModel.stream(requestPrompt).subscribe(
|
||||
response -> {
|
||||
if (response != null) {
|
||||
log.info("Dashscope API response metadata: {}", response.getMetadata());
|
||||
List<Generation> generations = response.getResults();
|
||||
for (Generation generation : generations) {
|
||||
AssistantMessage assistantMessage = generation.getOutput();
|
||||
String textContent = assistantMessage.getText();
|
||||
|
||||
// sendMessageWebsocket(MessageTypeEnum.STREAM, textContent, messageProtobufReply);
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// error -> {
|
||||
// log.error("Dashscope API error: ", error);
|
||||
// sendMessageWebsocket(MessageTypeEnum.ERROR, "服务暂时不可用,请稍后重试", messageProtobufReply);
|
||||
// },
|
||||
// () -> {
|
||||
// log.info("Chat stream completed");
|
||||
// });
|
||||
// }
|
||||
sendMessageWebsocket(MessageTypeEnum.STREAM, textContent, messageProtobufReply);
|
||||
}
|
||||
}
|
||||
},
|
||||
error -> {
|
||||
log.error("Dashscope API error: ", error);
|
||||
sendMessageWebsocket(MessageTypeEnum.ERROR, "服务暂时不可用,请稍后重试", messageProtobufReply);
|
||||
},
|
||||
() -> {
|
||||
log.info("Chat stream completed");
|
||||
});
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected String processPromptSync(String message, RobotProtobuf robot) {
|
||||
// try {
|
||||
// if (dashscopeChatModel == null) {
|
||||
// return "Dashscope service is not available";
|
||||
// }
|
||||
@Override
|
||||
protected String processPromptSync(String message, RobotProtobuf robot) {
|
||||
try {
|
||||
if (dashscopeChatModel == null) {
|
||||
return "Dashscope service is not available";
|
||||
}
|
||||
|
||||
// try {
|
||||
// // 如果有robot参数,尝试创建自定义选项
|
||||
// if (robot != null && robot.getLlm() != null) {
|
||||
// // 创建自定义选项
|
||||
// OpenAiChatOptions customOptions = createDynamicOptions(robot.getLlm());
|
||||
// if (customOptions != null) {
|
||||
// // 使用自定义选项创建Prompt
|
||||
// Prompt prompt = new Prompt(message, customOptions);
|
||||
// var response = dashscopeChatModel.call(prompt);
|
||||
// return extractTextFromResponse(response);
|
||||
// }
|
||||
// }
|
||||
try {
|
||||
// 如果有robot参数,尝试创建自定义选项
|
||||
if (robot != null && robot.getLlm() != null) {
|
||||
// 创建自定义选项
|
||||
OpenAiChatOptions customOptions = createDynamicOptions(robot.getLlm());
|
||||
if (customOptions != null) {
|
||||
// 使用自定义选项创建Prompt
|
||||
Prompt prompt = new Prompt(message, customOptions);
|
||||
var response = dashscopeChatModel.call(prompt);
|
||||
return extractTextFromResponse(response);
|
||||
}
|
||||
}
|
||||
|
||||
// var response = dashscopeChatModel.call(message);
|
||||
// return extractTextFromResponse(response);
|
||||
// } catch (Exception e) {
|
||||
// log.error("Dashscope API call error: ", e);
|
||||
// return "服务暂时不可用,请稍后重试";
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// log.error("Dashscope API sync error: ", e);
|
||||
// return "服务暂时不可用,请稍后重试";
|
||||
// }
|
||||
// }
|
||||
var response = dashscopeChatModel.call(message);
|
||||
return extractTextFromResponse(response);
|
||||
} catch (Exception e) {
|
||||
log.error("Dashscope API call error: ", e);
|
||||
return "服务暂时不可用,请稍后重试";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Dashscope API sync error: ", e);
|
||||
return "服务暂时不可用,请稍后重试";
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected void processPromptSse(Prompt prompt, RobotProtobuf robot, MessageProtobuf messageProtobufQuery, MessageProtobuf messageProtobufReply, SseEmitter emitter) {
|
||||
// // 从robot中获取llm配置
|
||||
// RobotLlm llm = robot.getLlm();
|
||||
@Override
|
||||
protected void processPromptSse(Prompt prompt, RobotProtobuf robot, MessageProtobuf messageProtobufQuery, MessageProtobuf messageProtobufReply, SseEmitter emitter) {
|
||||
// 从robot中获取llm配置
|
||||
RobotLlm llm = robot.getLlm();
|
||||
|
||||
// if (dashscopeChatModel == null) {
|
||||
// handleSseError(new RuntimeException("Dashscope service not available"), messageProtobufQuery, messageProtobufReply, emitter);
|
||||
// return;
|
||||
// }
|
||||
if (dashscopeChatModel == null) {
|
||||
handleSseError(new RuntimeException("Dashscope service not available"), messageProtobufQuery, messageProtobufReply, emitter);
|
||||
return;
|
||||
}
|
||||
|
||||
// // 发送起始消息
|
||||
// sendStreamStartMessage(messageProtobufReply, emitter, "正在思考中...");
|
||||
// 发送起始消息
|
||||
sendStreamStartMessage(messageProtobufReply, emitter, "正在思考中...");
|
||||
|
||||
// // 如果有自定义选项,创建新的Prompt
|
||||
// Prompt requestPrompt = prompt;
|
||||
// OpenAiChatOptions customOptions = createDynamicOptions(llm);
|
||||
// if (customOptions != null) {
|
||||
// requestPrompt = new Prompt(prompt.getInstructions(), customOptions);
|
||||
// }
|
||||
// 如果有自定义选项,创建新的Prompt
|
||||
Prompt requestPrompt = prompt;
|
||||
OpenAiChatOptions customOptions = createDynamicOptions(llm);
|
||||
if (customOptions != null) {
|
||||
requestPrompt = new Prompt(prompt.getInstructions(), customOptions);
|
||||
}
|
||||
|
||||
// dashscopeChatModel.stream(requestPrompt).subscribe(
|
||||
// response -> {
|
||||
// try {
|
||||
// if (response != null) {
|
||||
// List<Generation> generations = response.getResults();
|
||||
// for (Generation generation : generations) {
|
||||
// AssistantMessage assistantMessage = generation.getOutput();
|
||||
// String textContent = assistantMessage.getText();
|
||||
// log.info("Dashscope API response metadata: {}, text {}",
|
||||
// response.getMetadata(), textContent);
|
||||
dashscopeChatModel.stream(requestPrompt).subscribe(
|
||||
response -> {
|
||||
try {
|
||||
if (response != null) {
|
||||
List<Generation> generations = response.getResults();
|
||||
for (Generation generation : generations) {
|
||||
AssistantMessage assistantMessage = generation.getOutput();
|
||||
String textContent = assistantMessage.getText();
|
||||
log.info("Dashscope API response metadata: {}, text {}",
|
||||
response.getMetadata(), textContent);
|
||||
|
||||
// sendStreamMessage(messageProtobufQuery, messageProtobufReply, emitter, textContent);
|
||||
// }
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// log.error("Error sending SSE event", e);
|
||||
// handleSseError(e, messageProtobufQuery, messageProtobufReply, emitter);
|
||||
// }
|
||||
// },
|
||||
// error -> {
|
||||
// log.error("Dashscope API SSE error: ", error);
|
||||
// handleSseError(error, messageProtobufQuery, messageProtobufReply, emitter);
|
||||
// },
|
||||
// () -> {
|
||||
// log.info("Dashscope API SSE complete");
|
||||
// sendStreamEndMessage(messageProtobufQuery, messageProtobufReply, emitter);
|
||||
// });
|
||||
// }
|
||||
sendStreamMessage(messageProtobufQuery, messageProtobufReply, emitter, textContent);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Error sending SSE event", e);
|
||||
handleSseError(e, messageProtobufQuery, messageProtobufReply, emitter);
|
||||
}
|
||||
},
|
||||
error -> {
|
||||
log.error("Dashscope API SSE error: ", error);
|
||||
handleSseError(error, messageProtobufQuery, messageProtobufReply, emitter);
|
||||
},
|
||||
() -> {
|
||||
log.info("Dashscope API SSE complete");
|
||||
sendStreamEndMessage(messageProtobufQuery, messageProtobufReply, emitter);
|
||||
});
|
||||
}
|
||||
|
||||
// public OpenAiChatModel getChatModel() {
|
||||
// return dashscopeChatModel;
|
||||
// }
|
||||
public OpenAiChatModel getChatModel() {
|
||||
return dashscopeChatModel;
|
||||
}
|
||||
|
||||
// public Boolean isServiceHealthy() {
|
||||
// if (dashscopeChatModel == null) {
|
||||
// return false;
|
||||
// }
|
||||
public Boolean isServiceHealthy() {
|
||||
if (dashscopeChatModel == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// try {
|
||||
// String response = processPromptSync("test", null);
|
||||
// return !response.contains("不可用") && !response.equals("Dashscope service is not available");
|
||||
// } catch (Exception e) {
|
||||
// log.error("Error checking Dashscope service health", e);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
try {
|
||||
String response = processPromptSync("test", null);
|
||||
return !response.contains("不可用") && !response.equals("Dashscope service is not available");
|
||||
} catch (Exception e) {
|
||||
log.error("Error checking Dashscope service health", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
@Data
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "spring.ai.ollama.chat", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
public class SpringAIOllamaConfig {
|
||||
|
||||
@Value("${spring.ai.ollama.base-url:http://host.docker.internal:11434}")
|
||||
@@ -61,6 +60,7 @@ public class SpringAIOllamaConfig {
|
||||
}
|
||||
|
||||
@Bean("bytedeskOllamaChatOptions")
|
||||
@ConditionalOnProperty(prefix = "spring.ai.ollama.chat", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
OllamaOptions bytedeskOllamaChatOptions() {
|
||||
return OllamaOptions.builder()
|
||||
.model(ollamaChatOptionsModel)
|
||||
@@ -72,6 +72,7 @@ public class SpringAIOllamaConfig {
|
||||
}
|
||||
|
||||
@Bean("bytedeskOllamaEmbeddingOptions")
|
||||
@ConditionalOnProperty(prefix = "spring.ai.ollama.embedding", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
OllamaOptions bytedeskOllamaEmbeddingOptions() {
|
||||
return OllamaOptions.builder()
|
||||
.model(ollamaEmbeddingOptionsModel)
|
||||
@@ -80,6 +81,7 @@ public class SpringAIOllamaConfig {
|
||||
|
||||
@Primary
|
||||
@Bean("bytedeskOllamaChatModel")
|
||||
@ConditionalOnProperty(prefix = "spring.ai.ollama.chat", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
OllamaChatModel bytedeskOllamaChatModel() {
|
||||
return OllamaChatModel.builder()
|
||||
.ollamaApi(bytedeskOllamaApi())
|
||||
@@ -99,6 +101,7 @@ public class SpringAIOllamaConfig {
|
||||
// https://docs.spring.io/spring-ai/reference/api/chatclient.html
|
||||
@Primary
|
||||
@Bean("bytedeskOllamaChatClient")
|
||||
@ConditionalOnProperty(prefix = "spring.ai.ollama.chat", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
ChatClient bytedeskOllamaChatClient() {
|
||||
return ChatClient.builder(bytedeskOllamaChatModel())
|
||||
// .defaultSystem("You are a friendly chat bot that answers question in the voice of a {voice}")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: jackning 270580156@qq.com
|
||||
* @Date: 2024-05-31 10:53:11
|
||||
* @LastEditors: jackning 270580156@qq.com
|
||||
* @LastEditTime: 2025-04-17 14:44:29
|
||||
* @LastEditTime: 2025-07-11 09:46:54
|
||||
* @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.
|
||||
@@ -26,6 +26,7 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
import lombok.Data;
|
||||
/**
|
||||
@@ -37,7 +38,6 @@ import lombok.Data;
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "spring.ai.zhipuai.chat", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
public class SpringAIZhipuaiConfig {
|
||||
|
||||
@Value("${spring.ai.zhipuai.api-key:}")
|
||||
@@ -58,6 +58,7 @@ public class SpringAIZhipuaiConfig {
|
||||
}
|
||||
|
||||
@Bean("bytedeskZhipuaiChatOptions")
|
||||
@ConditionalOnProperty(prefix = "spring.ai.zhipuai.chat", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
ZhiPuAiChatOptions bytedeskZhipuaiChatOptions() {
|
||||
return ZhiPuAiChatOptions.builder()
|
||||
.model(zhipuaiApiModel)
|
||||
@@ -68,6 +69,7 @@ public class SpringAIZhipuaiConfig {
|
||||
// https://docs.spring.io/spring-ai/reference/api/embeddings/zhipuai-embeddings.html
|
||||
// https://open.bigmodel.cn/overview
|
||||
@Bean("bytedeskZhipuaiEmbeddingOptions")
|
||||
@ConditionalOnProperty(prefix = "spring.ai.zhipuai.embedding", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
ZhiPuAiEmbeddingOptions bytedeskZhipuaiEmbeddingOptions() {
|
||||
return ZhiPuAiEmbeddingOptions.builder()
|
||||
.model(zhipuaiEmbeddingModel)
|
||||
@@ -76,28 +78,26 @@ public class SpringAIZhipuaiConfig {
|
||||
|
||||
// https://open.bigmodel.cn/dev/api/normal-model/glm-4
|
||||
@Bean("bytedeskZhipuaiChatModel")
|
||||
@ConditionalOnProperty(prefix = "spring.ai.zhipuai.chat", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
ZhiPuAiChatModel bytedeskZhipuaiChatModel() {
|
||||
return new ZhiPuAiChatModel(bytedeskZhipuaiApi(), bytedeskZhipuaiChatOptions());
|
||||
}
|
||||
|
||||
@Bean("bytedeskZhipuaiEmbeddingModel")
|
||||
@Primary
|
||||
@ConditionalOnProperty(prefix = "spring.ai.zhipuai.embedding", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
ZhiPuAiEmbeddingModel bytedeskZhipuaiEmbeddingModel(org.springframework.core.env.Environment env) {
|
||||
// Only mark as @Primary if this is the selected embedding provider
|
||||
boolean isPrimary = "zhipuai".equals(env.getProperty("spring.ai.model.embedding"));
|
||||
ZhiPuAiEmbeddingModel model = new ZhiPuAiEmbeddingModel(bytedeskZhipuaiApi(), MetadataMode.EMBED, bytedeskZhipuaiEmbeddingOptions());
|
||||
if (isPrimary) {
|
||||
// Use a proxy or custom annotation processor if needed, or document that only one embedding should be enabled
|
||||
}
|
||||
return model;
|
||||
ZhiPuAiEmbeddingModel bytedeskZhipuaiEmbeddingModel() {
|
||||
return new ZhiPuAiEmbeddingModel(bytedeskZhipuaiApi(), MetadataMode.EMBED, bytedeskZhipuaiEmbeddingOptions());
|
||||
}
|
||||
|
||||
@Bean("bytedeskZhipuaiChatClientBuilder")
|
||||
@ConditionalOnProperty(prefix = "spring.ai.zhipuai.chat", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
ChatClient.Builder bytedeskZhipuaiChatClientBuilder() {
|
||||
return ChatClient.builder(bytedeskZhipuaiChatModel());
|
||||
}
|
||||
|
||||
@Bean("bytedeskZhipuaiChatClient")
|
||||
@ConditionalOnProperty(prefix = "spring.ai.zhipuai.chat", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
ChatClient bytedeskZhipuaiChatClient() {
|
||||
return bytedeskZhipuaiChatClientBuilder()
|
||||
.defaultOptions(bytedeskZhipuaiChatOptions())
|
||||
@@ -105,11 +105,13 @@ public class SpringAIZhipuaiConfig {
|
||||
}
|
||||
|
||||
@Bean("bytedeskZhipuaiImageApi")
|
||||
@ConditionalOnProperty(prefix = "spring.ai.zhipuai.chat", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
ZhiPuAiImageApi bytedeskZhipuaiImageApi() {
|
||||
return new ZhiPuAiImageApi(zhipuaiApiKey);
|
||||
}
|
||||
|
||||
@Bean("bytedeskZhipuaiImageModel")
|
||||
@ConditionalOnProperty(prefix = "spring.ai.zhipuai.chat", name = "enabled", havingValue = "true", matchIfMissing = false)
|
||||
ZhiPuAiImageModel bytedeskZhipuaiImageModel() {
|
||||
return new ZhiPuAiImageModel(bytedeskZhipuaiImageApi());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user