Skip to content

Commit c5a6976

Browse files
feat(ai): 添加 HunYuan模型支持
- 新增 HunYuanAutoConfiguration 类实现自动配置 - 添加 HunYuanChatProperties 和 HunYuanCommonProperties 类管理配置属性 - 更新 HunYuanApi 和 HunYuanChatModel 类以支持新功能 -增加相关测试用例验证功能
1 parent becf742 commit c5a6976

24 files changed

+390
-76
lines changed

models/spring-ai-hunyuan/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
</parent>
2727
<artifactId>spring-ai-hunyuan</artifactId>
2828
<packaging>jar</packaging>
29-
<name>Spring AI Model - Hunyuan</name>
30-
<description>Hunyuan support</description>
29+
<name>Spring AI Model - HunYuan</name>
30+
<description>HunYuan support</description>
3131
<url>https://github.com/spring-projects/spring-ai</url>
3232

3333
<scm>

models/spring-ai-hunyuan/src/main/java/org/springframework/ai/hunyuan/HunYuanChatModel.java

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,9 @@
6666
import org.springframework.util.CollectionUtils;
6767

6868
/**
69-
* HunyuanChatModel is a {@link ChatModel} implementation that uses the Hunyuan
69+
* HunYuanChatModel is a {@link ChatModel} implementation that uses the HunYuan
7070
*
71-
* @author Geng Rong
72-
* @author Alexandros Pappas
71+
* @author Guo Junyu
7372
*/
7473
public class HunYuanChatModel extends AbstractToolCallSupport implements ChatModel, StreamingChatModel {
7574

@@ -83,7 +82,7 @@ public class HunYuanChatModel extends AbstractToolCallSupport implements ChatMod
8382
private final HunYuanChatOptions defaultOptions;
8483

8584
/**
86-
* Low-level access to the Hunyuan API.
85+
* Low-level access to the HunYuan API.
8786
*/
8887
private final HunYuanApi hunYuanApi;
8988

@@ -100,29 +99,29 @@ public class HunYuanChatModel extends AbstractToolCallSupport implements ChatMod
10099
private ChatModelObservationConvention observationConvention = DEFAULT_OBSERVATION_CONVENTION;
101100

102101
/**
103-
* Initializes a new instance of the HunyuanChatModel.
104-
* @param hunYuanApi The Hunyuan instance to be used for interacting with the
105-
* Hunyuan Chat API.
102+
* Initializes a new instance of the HunYuanChatModel.
103+
* @param hunYuanApi The HunYuan instance to be used for interacting with the
104+
* HunYuan Chat API.
106105
*/
107106
public HunYuanChatModel(HunYuanApi hunYuanApi) {
108107
this(hunYuanApi, HunYuanChatOptions.builder().model(HunYuanApi.DEFAULT_CHAT_MODEL).build());
109108
}
110109

111110
/**
112-
* Initializes a new instance of the HunyuanChatModel.
113-
* @param hunYuanApi The Hunyuan instance to be used for interacting with the
114-
* Hunyuan Chat API.
115-
* @param options The HunyuanChatOptions to configure the chat client.
111+
* Initializes a new instance of the HunYuanChatModel.
112+
* @param hunYuanApi The HunYuan instance to be used for interacting with the
113+
* HunYuan Chat API.
114+
* @param options The HunYuanChatOptions to configure the chat client.
116115
*/
117116
public HunYuanChatModel(HunYuanApi hunYuanApi, HunYuanChatOptions options) {
118117
this(hunYuanApi, options, null, RetryUtils.DEFAULT_RETRY_TEMPLATE);
119118
}
120119

121120
/**
122-
* Initializes a new instance of the HunyuanChatModel.
123-
* @param hunYuanApi The Hunyuan instance to be used for interacting with the
124-
* Hunyuan Chat API.
125-
* @param options The HunyuanChatOptions to configure the chat client.
121+
* Initializes a new instance of the HunYuanChatModel.
122+
* @param hunYuanApi The HunYuan instance to be used for interacting with the
123+
* HunYuan Chat API.
124+
* @param options The HunYuanChatOptions to configure the chat client.
126125
* @param functionCallbackResolver The function callback resolver to resolve the
127126
* function by its name.
128127
* @param retryTemplate The retry template.
@@ -133,10 +132,10 @@ public HunYuanChatModel(HunYuanApi hunYuanApi, HunYuanChatOptions options,
133132
}
134133

135134
/**
136-
* Initializes a new instance of the HunyuanChatModel.
137-
* @param hunYuanApi The Hunyuan instance to be used for interacting with the
138-
* Hunyuan Chat API.
139-
* @param options The HunyuanChatOptions to configure the chat client.
135+
* Initializes a new instance of the HunYuanChatModel.
136+
* @param hunYuanApi The HunYuan instance to be used for interacting with the
137+
* HunYuan Chat API.
138+
* @param options The HunYuanChatOptions to configure the chat client.
140139
* @param functionCallbackResolver resolves the function by its name.
141140
* @param toolFunctionCallbacks The tool function callbacks.
142141
* @param retryTemplate The retry template.
@@ -146,7 +145,7 @@ public HunYuanChatModel(HunYuanApi hunYuanApi, HunYuanChatOptions options,
146145
FunctionCallbackResolver functionCallbackResolver, List<FunctionCallback> toolFunctionCallbacks,
147146
RetryTemplate retryTemplate, ObservationRegistry observationRegistry) {
148147
super(functionCallbackResolver, options, toolFunctionCallbacks);
149-
Assert.notNull(hunYuanApi, "HunyuanApi must not be null");
148+
Assert.notNull(hunYuanApi, "HunYuanApi must not be null");
150149
Assert.notNull(options, "Options must not be null");
151150
Assert.notNull(retryTemplate, "RetryTemplate must not be null");
152151
Assert.isTrue(CollectionUtils.isEmpty(options.getFunctionCallbacks()),
@@ -311,7 +310,7 @@ public Flux<ChatResponse> stream(Prompt prompt) {
311310
}
312311

313312
private ChatResponseMetadata from(ChatCompletionRequest request, ChatCompletion result) {
314-
Assert.notNull(result, "Hunyuan ChatCompletionResult must not be null");
313+
Assert.notNull(result, "HunYuan ChatCompletionResult must not be null");
315314
return ChatResponseMetadata.builder()
316315
.id(result.id() != null ? result.id() : "")
317316
.usage(result.usage() != null ? HunYuanUsage.from(result.usage()) : new EmptyUsage())

models/spring-ai-hunyuan/src/main/java/org/springframework/ai/hunyuan/HunYuanChatOptions.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,9 @@
2929
import org.springframework.util.Assert;
3030

3131
/**
32-
* Options for Hunyuan chat completions.
32+
* Options for HunYuan chat completions.
3333
*
34-
* @author Geng Rong
35-
* @author Thomas Vitale
36-
* @author Alexandros Pappas
34+
* @author Guo Junyu
3735
*/
3836
@JsonInclude(JsonInclude.Include.NON_NULL)
3937
public class HunYuanChatOptions implements FunctionCallingOptions {
@@ -71,7 +69,7 @@ public class HunYuanChatOptions implements FunctionCallingOptions {
7169

7270

7371
/**
74-
* Hunyuan Tool Function Callbacks to register with the ChatModel. For Prompt Options
72+
* HunYuan Tool Function Callbacks to register with the ChatModel. For Prompt Options
7573
* the functionCallbacks are automatically enabled for the duration of the prompt
7674
* execution. For Default Options the functionCallbacks are registered but disabled by
7775
* default. Use the enableFunctions to set the functions from the registry to be used

models/spring-ai-hunyuan/src/main/java/org/springframework/ai/hunyuan/api/HunYuanApi.java

Lines changed: 62 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,13 @@
2020
import java.util.concurrent.atomic.AtomicBoolean;
2121
import java.util.function.Consumer;
2222
import java.util.function.Predicate;
23-
import java.util.stream.Collectors;
2423

2524
import com.fasterxml.jackson.annotation.JsonInclude;
2625
import com.fasterxml.jackson.annotation.JsonInclude.Include;
2726
import com.fasterxml.jackson.annotation.JsonProperty;
28-
import com.fasterxml.jackson.core.JsonProcessingException;
29-
import com.fasterxml.jackson.databind.DeserializationFeature;
30-
import com.fasterxml.jackson.databind.ObjectMapper;
3127
import org.slf4j.Logger;
3228
import org.slf4j.LoggerFactory;
3329
import org.springframework.ai.hunyuan.api.auth.HunYuanAuthApi;
34-
import org.springframework.util.CollectionUtils;
3530
import org.springframework.util.MultiValueMap;
3631
import reactor.core.publisher.Flux;
3732
import reactor.core.publisher.Mono;
@@ -311,6 +306,11 @@ public record Usage(
311306
* like 0.8 will make the output more random, while lower values like 0.2 will make it
312307
* more focused and deterministic. We generally recommend altering this or top_p but
313308
* not both.
309+
* @param enableEnhancement Enables or disables feature enhancements such as search. This parameter does not affect the security review capability.
310+
* For hunyuan-lite, this parameter is ineffective.
311+
* If not specified, the switch is turned on by default.
312+
* Turning off this switch can reduce response latency, especially for the first character in stream mode, but may slightly degrade the response quality in some scenarios.
313+
* Example: true
314314
* @param topP An alternative to sampling with temperature, called nucleus sampling,
315315
* where the model considers the results of the tokens with top_p probability mass. So
316316
* 0.1 means only the tokens comprising the top 10% probability mass are considered.
@@ -319,12 +319,46 @@ public record Usage(
319319
* @param stream If set, partial message deltas will be sent.Tokens will be sent as
320320
* data-only server-sent events as they become available, with the stream terminated
321321
* by a data: [DONE] message.
322+
* @param streamModeration Controls whether the output is reviewed in real-time during streaming.
323+
* This field is effective only when Stream is set to true.
324+
* If true, the output is reviewed in real-time, and segments that fail the review will have their FinishReason set to sensitive.
325+
* If false, the entire output is reviewed before being returned.
326+
* If real-time text display is required in your application, you should handle the case where FinishReason is sensitive by撤回已显示的内容 and providing a custom message.
327+
* Example: false
322328
* @param tools A list of tools the model may call. Currently, only functions are
323329
* supported as a tool.
324-
* @param toolChoice Controls which (if any) function is called by the model.
325-
* @param customTool A custom tool to be used by the model.
326-
* @param searchInfo Whether to include search information in the response.
327-
* @param citation Whether to include citation information in the response.
330+
* @param toolChoice Controls which (if any) function is called by the model. Possible values are none, auto, and custom.
331+
* If not specified, the default is auto.
332+
* Example: auto
333+
* @param customTool Forces the model to call a specific tool. This parameter is required when ToolChoice is set to custom.
334+
* @param searchInfo If true, the interface will return SearchInfo when a search hit occurs. Example: false
335+
* @param citation Enables or disables citation markers in the response.
336+
* This parameter works in conjunction with EnableEnhancement and SearchInfo.
337+
* If true, search results in the response will be marked with a citation marker corresponding to links in the SearchInfo list.
338+
* If not specified, the default is false.
339+
* Example: false
340+
* @param enableSpeedSearch Enables or disables the fast version of search.
341+
* If true and a search hit occurs, the fast version of search will be used, which can reduce the latency of the first character in the stream.
342+
* Example: false
343+
* @param enableMultimedia Enables or disables multimedia capabilities.
344+
* This parameter is effective only for whitelisted users and when EnableEnhancement is true and EnableSpeedSearch is false.
345+
* For hunyuan-lite, this parameter is ineffective.
346+
* If not specified, the default is false.
347+
* When enabled and a multimedia hit occurs, the corresponding multimedia address will be output.
348+
* Example: false
349+
* @param enableDeepSearch Enables or disables deep research on the question.
350+
* If true and a deep research hit occurs, information about the deep research will be returned.
351+
* Example: false
352+
* @param seed Ensures the model's output is reproducible.
353+
* The value should be a non-zero positive integer, with a maximum value of 10000.
354+
* It is not recommended to use this parameter unless necessary, as improper values can affect the output quality.
355+
* Example: 1
356+
* @param forceSearchEnhancement Forces the use of AI search.
357+
* If true, AI search will be used, and if the AI search result is empty, the large model will provide a fallback response.
358+
* Example: false
359+
* @param enableRecommendedQuestions Enables or disables the recommendation of additional questions.
360+
* If true, the response will include a RecommendedQuestions field with up to 3 recommended questions in the last package.
361+
* Example: false
328362
*/
329363
@JsonInclude(Include.NON_NULL)
330364
public record ChatCompletionRequest(
@@ -346,7 +380,7 @@ public record ChatCompletionRequest(
346380
@JsonProperty("EnableMultimedia") Boolean enableMultimedia,
347381
@JsonProperty("EnableDeepSearch") Boolean enableDeepSearch,
348382
@JsonProperty("Seed") Integer seed,
349-
@JsonProperty("ForceSearchEnhancement") Boolean ForceSearchEnhancement,
383+
@JsonProperty("ForceSearchEnhancement") Boolean forceSearchEnhancement,
350384
@JsonProperty("EnableRecommendedQuestions") Boolean enableRecommendedQuestions
351385
) {
352386
// @formatter:on
@@ -403,6 +437,19 @@ public ChatCompletionRequest(List<ChatCompletionMessage> messages, String model,
403437
String toolChoice) {
404438
this(model,messages, null, null, null, null, null, null, tools, toolChoice, null, null, null, null, null, null, null, null, null);
405439
}
440+
441+
/**
442+
* Shortcut constructor for a chat completion request with the given messages,
443+
* model, stream, streamModeration, enableEnhancement, searchInfo, citation, enableSpeedSearch.
444+
* @param messages A list of messages comprising the conversation so far.
445+
* @param model ID of the model to use.
446+
* @param stream Whether to stream back partial progress.
447+
* @param streamModeration Whether to stream back partial progress.
448+
* @param enableEnhancement Enables or disables the enhancement feature.
449+
* @param searchInfo Enables or disables the search information feature.
450+
* @param citation Enables or disables the citation feature.
451+
* @param enableSpeedSearch Enables or disables the speed search feature.
452+
*/
406453
public ChatCompletionRequest(List<ChatCompletionMessage> messages, String model,
407454
Boolean stream,
408455
Boolean streamModeration,
@@ -454,7 +501,7 @@ public static Object function(String functionName) {
454501
* @param rawContent The raw contents of the message.
455502
* @param role The role of the message's author. Could be one of the {@link Role}
456503
* types.
457-
* @param chatContent The name of the message's author.
504+
* @param chatContents The name of the message's author.
458505
* @param toolCallId The ID of the tool call associated with the message.
459506
* @param toolCalls The list of tool calls associated with the message.
460507
*/
@@ -583,14 +630,7 @@ public record ChatCompletionFunction(@JsonProperty("Name") String name,
583630
/**
584631
* Represents a chat completion response returned by model, based on the provided
585632
* input.
586-
*
587-
* @param id A unique identifier for the chat completion.
588-
* @param object The object type, which is always chat.completion.
589-
* @param created The Unix timestamp (in seconds) of when the chat completion was
590-
* created.
591-
* @param model The model used for the chat completion.
592-
* @param choices A list of chat completion choices.
593-
* @param usage Usage statistics for the completion request.
633+
* @param response The response object containing the generated chat completion.
594634
*/
595635
@JsonInclude(Include.NON_NULL)
596636
public record ChatCompletionResponse(
@@ -754,12 +794,13 @@ public record ErrorMsg(
754794
* on the provided input.
755795
*
756796
* @param id A unique identifier for the chat completion. Each chunk has the same ID.
757-
* @param object The object type, which is always 'chat.completion.chunk'.
797+
* @param errorMsg The error message, if any.
758798
* @param created The Unix timestamp (in seconds) of when the chat completion was
759799
* created. Each chunk has the same timestamp.
760-
* @param model The model used for the chat completion.
800+
* @param note A note about the generated content. Each chunk has the same note.
761801
* @param choices A list of chat completion choices. Can be more than one if n is
762802
* greater than 1.
803+
* @param usage The usage statistics for the chat completion.
763804
*/
764805
@JsonInclude(Include.NON_NULL)
765806
public record ChatCompletionChunk(

models/spring-ai-hunyuan/src/main/java/org/springframework/ai/hunyuan/api/HunYuanConstants.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
import org.springframework.ai.observation.conventions.AiProvider;
2020

2121
/**
22-
* Constants for Moonshot API.
22+
* Constants for HunYuan API.
2323
*
24-
* @author Geng Rong
24+
* @author Guo Junyu
2525
*/
2626
public final class HunYuanConstants {
2727

models/spring-ai-hunyuan/src/main/java/org/springframework/ai/hunyuan/api/HunYuanStreamFunctionCallingHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
* Helper class to support Streaming function calling. It can merge the streamed
2929
* ChatCompletionChunk in case of function calling message.
3030
*
31-
* @author Geng Rong
31+
* @author Guo Junyu
3232
*/
3333
public class HunYuanStreamFunctionCallingHelper {
3434

models/spring-ai-hunyuan/src/main/java/org/springframework/ai/hunyuan/metadata/HunYuanUsage.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
import org.springframework.util.Assert;
2222

2323
/**
24-
* Represents the usage of a Hunyuan model.
24+
* Represents the usage of a HunYuan model.
2525
*
26-
* @author Geng Rong
26+
* @author Guo Junyu
2727
*/
2828
public class HunYuanUsage implements Usage {
2929

models/spring-ai-hunyuan/src/test/java/org/springframework/ai/hunyuan/HunYuanChatCompletionRequestTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
import static org.assertj.core.api.Assertions.assertThat;
2727

2828
/**
29-
* @author Geng Rong
30-
* @author Alexandros Pappas
29+
* @author Guo Junyu
3130
*/
3231
@SpringBootTest
3332
@EnabledIfEnvironmentVariable(named = "HUNYUAN_SECRET_ID", matches = ".+")

models/spring-ai-hunyuan/src/test/java/org/springframework/ai/hunyuan/HunYuanRetryTests.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@
4848
import static org.mockito.BDDMockito.given;
4949

5050
/**
51-
* @author Geng Rong
52-
* @author Alexandros Pappas
51+
* @author Guo Junyu
5352
*/
5453
@SuppressWarnings("unchecked")
5554
@ExtendWith(MockitoExtension.class)
@@ -99,7 +98,7 @@ public void hunyuanChatTransientError() {
9998
}
10099

101100
@Test
102-
public void moonshotChatNonTransientError() {
101+
public void hunYuanChatNonTransientError() {
103102
given(this.hunYuanApi.chatCompletionEntity(isA(ChatCompletionRequest.class)))
104103
.willThrow(new RuntimeException("Non Transient Error"));
105104
assertThrows(RuntimeException.class, () -> this.chatModel.call(new Prompt("text")));

models/spring-ai-hunyuan/src/test/java/org/springframework/ai/hunyuan/HunYuanTestConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import org.springframework.util.StringUtils;
2323

2424
/**
25-
* @author Geng Rong
25+
* @author Guo Junyu
2626
*/
2727
@SpringBootConfiguration
2828
public class HunYuanTestConfiguration {

0 commit comments

Comments
 (0)