Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
Signed-off-by: yuluo-yx <yuluo08290126@gmail.com>
  • Loading branch information
yuluo-yx committed Dec 7, 2024
1 parent 6509865 commit 80cbe5e
Show file tree
Hide file tree
Showing 25 changed files with 422 additions and 500 deletions.
1 change: 0 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
<module>spring-ai-alibaba-core</module>
<module>spring-ai-alibaba-starter</module>
<module>spring-ai-alibaba-autoconfigure</module>
<module>spring-ai-alibaba-examples</module>
<module>community/plugins/spring-ai-alibaba-starter-plugin-time</module>
<module>community/plugins/spring-ai-alibaba-starter-plugin-baidusearch</module>
<module>community/plugins/spring-ai-alibaba-starter-plugin-bingsearch</module>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
import com.fasterxml.jackson.annotation.JsonProperty;

/**
* Lets you specify the format of the returned content.
* Valid values: {"type": "text"} or {"type": "json_object"}.
* When set to {"type": "json_object"}, a JSON string in standard format is output.
* Params reference: <a href="https://help.aliyun.com/zh/dashscope/developer-reference/qwen-api">...</a>
* Lets you specify the format of the returned content. Valid values: {"type": "text"} or
* {"type": "json_object"}. When set to {"type": "json_object"}, a JSON string in standard
* format is output. Params reference:
* <a href="https://help.aliyun.com/zh/dashscope/developer-reference/qwen-api">...</a>
*
* @author yuluo
* @author <a href="mailto:yuluo08290126@gmail.com">yuluo</a>
Expand Down Expand Up @@ -80,6 +80,7 @@ public DashScopeResponseFormat build() {

return new DashScopeResponseFormat(this.type);
}

}

@Override
Expand All @@ -90,8 +91,10 @@ public String toString() {

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
DashScopeResponseFormat that = (DashScopeResponseFormat) o;
return Objects.equals(type, that.type);
}
Expand All @@ -102,7 +105,8 @@ public int hashCode() {
}

/**
* DashScopeResponseFormat type. Valid values: {"type": "text"} or {"type": "json_object"}.
* DashScopeResponseFormat type. Valid values: {"type": "text"} or
* {"type": "json_object"}.
*/
public enum Type {

Expand All @@ -113,7 +117,8 @@ public enum Type {
TEXT,

/**
* Enables JSON mode, which guarantees the message the model generates is valid JSON string.
* Enables JSON mode, which guarantees the message the model generates is valid
* JSON string.
*/
@JsonProperty("json_object")
JSON_OBJECT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class STTController {
private static final String DEFAULT_MODEL_1 = "sensevoice-v1";

private static final String DEFAULT_MODEL_2 = "paraformer-realtime-v2";

private static final String DEFAULT_MODEL_3 = "paraformer-v2";

private static final String FILE_PATH = "spring-ai-alibaba-examples/audio-example/src/main/resources/stt/count.pcm";
Expand All @@ -64,14 +65,9 @@ public class STTController {
@GetMapping
public DashScopeAudioTranscriptionApi.Response.Output stt() throws MalformedURLException {

AudioTranscriptionResponse response = transcriptionModel.call(
new AudioTranscriptionPrompt(
new UrlResource(AUDIO_RESOURCES_URL),
DashScopeAudioTranscriptionOptions.builder()
.withModel(DEFAULT_MODEL_1)
.build()
)
);
AudioTranscriptionResponse response = transcriptionModel
.call(new AudioTranscriptionPrompt(new UrlResource(AUDIO_RESOURCES_URL),
DashScopeAudioTranscriptionOptions.builder().withModel(DEFAULT_MODEL_1).build()));

return response.getMetadata().get("output");
}
Expand All @@ -83,23 +79,16 @@ public String streamSTT() {
StringBuilder stringBuilder = new StringBuilder();

Flux<AudioTranscriptionResponse> response = transcriptionModel
.stream(
new AudioTranscriptionPrompt(
new FileSystemResource(FILE_PATH),
DashScopeAudioTranscriptionOptions.builder()
.withModel(DEFAULT_MODEL_2)
.withSampleRate(16000)
.withFormat(DashScopeAudioTranscriptionOptions.AudioFormat.PCM)
.withDisfluencyRemovalEnabled(false)
.build()
)
);

response.doFinally(
signal -> latch.countDown()
).subscribe(
resp -> stringBuilder.append(resp.getResult().getOutput())
);
.stream(new AudioTranscriptionPrompt(new FileSystemResource(FILE_PATH),
DashScopeAudioTranscriptionOptions.builder()
.withModel(DEFAULT_MODEL_2)
.withSampleRate(16000)
.withFormat(DashScopeAudioTranscriptionOptions.AudioFormat.PCM)
.withDisfluencyRemovalEnabled(false)
.build()));

response.doFinally(signal -> latch.countDown())
.subscribe(resp -> stringBuilder.append(resp.getResult().getOutput()));

try {
latch.await();
Expand All @@ -117,21 +106,15 @@ public String asyncSTT() {
CountDownLatch latch = new CountDownLatch(1);

try {
AudioTranscriptionResponse submitResponse = transcriptionModel.asyncCall(
new AudioTranscriptionPrompt(
new UrlResource(AUDIO_RESOURCES_URL),
DashScopeAudioTranscriptionOptions.builder()
.withModel(DEFAULT_MODEL_3)
.build()
)
);

DashScopeAudioTranscriptionApi.Response.Output submitOutput = Objects.requireNonNull(submitResponse.getMetadata()
.get("output"));
AudioTranscriptionResponse submitResponse = transcriptionModel
.asyncCall(new AudioTranscriptionPrompt(new UrlResource(AUDIO_RESOURCES_URL),
DashScopeAudioTranscriptionOptions.builder().withModel(DEFAULT_MODEL_3).build()));

DashScopeAudioTranscriptionApi.Response.Output submitOutput = Objects
.requireNonNull(submitResponse.getMetadata().get("output"));
String taskId = submitOutput.taskId();

scheduler.scheduleAtFixedRate(
() -> checkTaskStatus(taskId, stringBuilder, latch), 0, 1, TimeUnit.SECONDS);
scheduler.scheduleAtFixedRate(() -> checkTaskStatus(taskId, stringBuilder, latch), 0, 1, TimeUnit.SECONDS);
latch.await();

}
Expand All @@ -153,8 +136,8 @@ private void checkTaskStatus(String taskId, StringBuilder stringBuilder, CountDo

try {
AudioTranscriptionResponse fetchResponse = transcriptionModel.fetch(taskId);
DashScopeAudioTranscriptionApi.Response.Output fetchOutput =
Objects.requireNonNull(fetchResponse.getMetadata().get("output"));
DashScopeAudioTranscriptionApi.Response.Output fetchOutput = Objects
.requireNonNull(fetchResponse.getMetadata().get("output"));
DashScopeAudioTranscriptionApi.TaskStatus taskStatus = fetchOutput.taskStatus();

if (taskStatus.equals(DashScopeAudioTranscriptionApi.TaskStatus.SUCCEEDED)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ public class TTSController implements ApplicationRunner {
@GetMapping
public void tts() throws IOException {

SpeechSynthesisResponse response = speechSynthesisModel.call(
new SpeechSynthesisPrompt(TEXT)
);
SpeechSynthesisResponse response = speechSynthesisModel.call(new SpeechSynthesisPrompt(TEXT));

File file = new File(FILE_PATH + "output.mp3");
try (FileOutputStream fos = new FileOutputStream(file)) {
Expand All @@ -72,17 +70,13 @@ public void tts() throws IOException {
@GetMapping("/stream")
public void streamTTS() {

Flux<SpeechSynthesisResponse> response = speechSynthesisModel.stream(
new SpeechSynthesisPrompt(TEXT)
);
Flux<SpeechSynthesisResponse> response = speechSynthesisModel.stream(new SpeechSynthesisPrompt(TEXT));

CountDownLatch latch = new CountDownLatch(1);
File file = new File(FILE_PATH + "output-stream.mp3");
try (FileOutputStream fos = new FileOutputStream(file)) {

response.doFinally(
signal -> latch.countDown()
).subscribe(synthesisResponse -> {
response.doFinally(signal -> latch.countDown()).subscribe(synthesisResponse -> {
ByteBuffer byteBuffer = synthesisResponse.getResult().getOutput().getAudio();
byte[] bytes = new byte[byteBuffer.remaining()];
byteBuffer.get(bytes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,33 +51,37 @@ public String stream(String input) {
StringBuilder res = new StringBuilder();
Flux<ChatResponse> stream = chatModel.stream(new Prompt(input));
stream.toStream().toList().forEach(resp -> {
res.append(resp.getResult().getOutput().getContent());
res.append(resp.getResult().getOutput().getContent());
});

return res.toString();
}

/**
* Tips: When specifying response types as json, you must include json when entering input, otherwise you will receive an error:
* 400 - {"code":"InvalidParameter","message":"<400> InternalError.Algo.InvalidParameter: 'messages' must contain the word 'json' in some form, to use 'response_format' of type 'json_object'."
*
* For example: In this interface, when mode is true, your input should be "Hello, returned in json format", and the prompt must contain the word json
* request url: <a href="http://localhost:8080/ai/response_types/true/"你好,以 json 形式返回信息">...</a>
* Tips: When specifying response types as json, you must include json when entering
* input, otherwise you will receive an error: 400 -
* {"code":"InvalidParameter","message":"<400> InternalError.Algo.InvalidParameter:
* 'messages' must contain the word 'json' in some form, to use 'response_format' of
* type 'json_object'."
*
* For example: In this interface, when mode is true, your input should be "Hello,
* returned in json format", and the prompt must contain the word json request url: <a
* href="http://localhost:8080/ai/response_types/true/"你好,以 json 形式返回信息">...</a>
* @return json string
*/
@GetMapping("/response_types/{mode}/{input}")
public String responseTypes(
@PathVariable(value = "input") String input,
@PathVariable(value = "mode") Boolean mode
) {
public String responseTypes(@PathVariable(value = "input") String input,
@PathVariable(value = "mode") Boolean mode) {

DashScopeChatOptions.DashscopeChatOptionsBuilder builder = DashScopeChatOptions.builder();

if (!mode) {
builder.withResponseFormat(DashScopeResponseFormat.builder().type(DashScopeResponseFormat.Type.TEXT).build());
} else {
builder.withResponseFormat(DashScopeResponseFormat.builder().type(DashScopeResponseFormat.Type.JSON_OBJECT).build());
builder
.withResponseFormat(DashScopeResponseFormat.builder().type(DashScopeResponseFormat.Type.TEXT).build());
}
else {
builder.withResponseFormat(
DashScopeResponseFormat.builder().type(DashScopeResponseFormat.Type.JSON_OBJECT).build());
}

return chatModel.call(new Prompt(input, builder.build())).getResult().getOutput().getContent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ public class ImageModelController {
@GetMapping("/image/{input}")
public void image(@PathVariable("input") String input, HttpServletResponse response) {

// The options parameter set in this way takes precedence over the parameters in the yaml configuration file.
// The options parameter set in this way takes precedence over the parameters in
// the yaml configuration file.
// The default image model is wanx-v1
// ImageOptions options = ImageOptionsBuilder.builder()
// .withModel("wax-2")
// .build();
// .withModel("wax-2")
// .build();
// ImagePrompt imagePrompt = new ImagePrompt(input, options);

ImagePrompt imagePrompt = new ImagePrompt(input);
Expand All @@ -62,7 +63,8 @@ public void image(@PathVariable("input") String input, HttpServletResponse respo
response.setHeader("Content-Type", MediaType.IMAGE_PNG_VALUE);
response.getOutputStream().write(in.readAllBytes());
response.getOutputStream().flush();
} catch (IOException e) {
}
catch (IOException e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,20 @@
@RequestMapping("/ai/func")
public class FunctionCallingController {

private final ChatClient chatClient;
private final ChatClient chatClient;

public FunctionCallingController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
public FunctionCallingController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}

@GetMapping("/weather-service")
public String weatherService(String subject) {
return chatClient.prompt()
.function("getWeather", "根据城市查询天气", new MockWeatherService())
.user(subject)
.call()
.content();
}
@GetMapping("/weather-service")
public String weatherService(String subject) {
return chatClient.prompt()
.function("getWeather", "根据城市查询天气", new MockWeatherService())
.user(subject)
.call()
.content();
}

@GetMapping("/order-detail")
public String orderDetail() {
Expand All @@ -53,58 +53,41 @@ public String orderDetail() {

@GetMapping("/baidu-search")
public String baiduSearch(@RequestParam String query) {
return chatClient.prompt()
.functions("baiduSearchService")
.user(query)
.call()
.content();
return chatClient.prompt().functions("baiduSearchService").user(query).call().content();
}

@GetMapping("/bing-search")
public String bingSearch(@RequestParam String query) {
return chatClient.prompt()
.functions("bingSearchService")
.user(query)
.call()
.content();
return chatClient.prompt().functions("bingSearchService").user(query).call().content();
}

@GetMapping("/getTime")
public String getTime(String text) {
return chatClient.prompt()
.functions("getCityTimeFunction")
.user(text)
.call()
.content();
}
@GetMapping("/getTime")
public String getTime(String text) {
return chatClient.prompt().functions("getCityTimeFunction").user(text).call().content();
}

@GetMapping("/dingTalk-custom-robot-send")
public String dingTalkCustomRobotSend(String input) {
return chatClient.prompt()
.functions("dingTalkGroupSendMessageByCustomRobotFunction")
.user(String.format("帮我用自定义机器人发送'%s'", input))
.call()
.content();
}
@GetMapping("/dingTalk-custom-robot-send")
public String dingTalkCustomRobotSend(String input) {
return chatClient.prompt()
.functions("dingTalkGroupSendMessageByCustomRobotFunction")
.user(String.format("帮我用自定义机器人发送'%s'", input))
.call()
.content();
}

@GetMapping("/gaode-get-address-weather")
public String gaoDeGetAddressWeatherFunction(String input) {
return chatClient.prompt()
.functions("gaoDeGetAddressWeatherFunction")
.system("如果用户输入的内容中想询问天气情况,而且还给定了地址,则使用工具获取天气情况,不然提示用户缺少信息")
.user(input)
.call()
.content();
.functions("gaoDeGetAddressWeatherFunction")
.system("如果用户输入的内容中想询问天气情况,而且还给定了地址,则使用工具获取天气情况,不然提示用户缺少信息")
.user(input)
.call()
.content();
}


@GetMapping("/getWeather")
public String getWeather(@RequestParam String text) {
return chatClient.prompt()
.functions("getWeatherService")
.user(text)
.call()
.content();
return chatClient.prompt().functions("getWeatherService").user(text).call().content();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ public static void main(String[] args) {

@Bean
@Description("根据用户编号和订单编号查询订单信息")
public Function<MockOrderService.Request, Response> getOrderFunction(
MockOrderService mockOrderService) {
public Function<MockOrderService.Request, Response> getOrderFunction(MockOrderService mockOrderService) {

return mockOrderService::getOrder;
}
Expand Down
Loading

0 comments on commit 80cbe5e

Please # to comment.