Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ public class DashScopeParameters {
@JsonProperty("enable_search")
private Boolean enableSearch;

/**
* Whether to stitch the reasoning_content of the assistant message in the conversation history to the model input.
*/
@JsonProperty("preserve_thinking")
private Boolean preserveThinking;

/** Token budget for thinking. */
@JsonProperty("thinking_budget")
private Integer thinkingBudget;
Expand Down Expand Up @@ -165,6 +171,14 @@ public void setEnableThinking(Boolean enableThinking) {
this.enableThinking = enableThinking;
}

public Boolean getPreserveThinking() {
return preserveThinking;
}

public void setPreserveThinking(Boolean preserveThinking) {
this.preserveThinking = preserveThinking;
}

public Integer getThinkingBudget() {
return thinkingBudget;
}
Expand Down Expand Up @@ -284,6 +298,11 @@ public Builder enableThinking(Boolean enableThinking) {
return this;
}

public Builder preserveThinking(Boolean preserveThinking) {
params.setPreserveThinking(preserveThinking);
return this;
}

public Builder thinkingBudget(Integer thinkingBudget) {
params.setThinkingBudget(thinkingBudget);
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public class DashScopeChatModel extends ChatModelBase {
private final boolean stream;
private final Boolean enableThinking; // nullable
private final Boolean enableSearch; // nullable
private final Boolean preserveThinking; // nullable
private final EndpointType endpointType;
private final GenerateOptions defaultOptions;
private final Formatter<DashScopeMessage, DashScopeResponse, DashScopeRequest> formatter;
Expand All @@ -70,18 +71,20 @@ public class DashScopeChatModel extends ChatModelBase {
* <p>This constructor maintains backward compatibility. API type defaults to AUTO,
* which detects the endpoint based on model name.
*
* @param apiKey the API key for DashScope authentication
* @param modelName the model name (e.g., "qwen-max", "qwen-vl-plus")
* @param stream whether streaming should be enabled (ignored if enableThinking is true)
* @param apiKey the API key for DashScope authentication
* @param modelName the model name (e.g., "qwen-max", "qwen-vl-plus")
* @param stream whether streaming should be enabled (ignored if enableThinking is true)
* @param enableThinking whether thinking mode should be enabled (null for disabled)
* @param enableSearch whether search enhancement should be enabled (null for disabled)
* @param enableSearch whether search enhancement should be enabled (null for disabled)
* @param defaultOptions default generation options (null for defaults)
* @param baseUrl custom base URL for DashScope API (null for default)
* @param formatter the message formatter to use (null for default DashScope formatter)
* @param httpTransport custom HTTP transport (null for default from factory)
* @param publicKeyId the RSA public key ID for encryption (null to disable encryption)
* @param publicKey the RSA public key for encryption (Base64-encoded, null to disable encryption)
* @param baseUrl custom base URL for DashScope API (null for default)
* @param formatter the message formatter to use (null for default DashScope formatter)
* @param httpTransport custom HTTP transport (null for default from factory)
* @param publicKeyId the RSA public key ID for encryption (null to disable encryption)
* @param publicKey the RSA public key for encryption (Base64-encoded, null to disable encryption)
* @deprecated Use {@link #builder()} instead.
*/
@Deprecated(since = "1.0.12", forRemoval = true)
public DashScopeChatModel(
String apiKey,
String modelName,
Expand Down Expand Up @@ -112,19 +115,21 @@ public DashScopeChatModel(
/**
* Creates a new DashScope chat model instance with explicit API type.
*
* @param apiKey the API key for DashScope authentication
* @param modelName the model name (e.g., "qwen-max", "qwen-vl-plus")
* @param stream whether streaming should be enabled (ignored if enableThinking is true)
* @param apiKey the API key for DashScope authentication
* @param modelName the model name (e.g., "qwen-max", "qwen-vl-plus")
* @param stream whether streaming should be enabled (ignored if enableThinking is true)
* @param enableThinking whether thinking mode should be enabled (null for disabled)
* @param enableSearch whether search enhancement should be enabled (null for disabled)
* @param endpointType the endpoint type to use (null for AUTO detection)
* @param enableSearch whether search enhancement should be enabled (null for disabled)
* @param endpointType the endpoint type to use (null for AUTO detection)
* @param defaultOptions default generation options (null for defaults)
* @param baseUrl custom base URL for DashScope API (null for default)
* @param formatter the message formatter to use (null for default DashScope formatter)
* @param httpTransport custom HTTP transport (null for default from factory)
* @param publicKeyId the RSA public key ID for encryption (null to disable encryption)
* @param publicKey the RSA public key for encryption (Base64-encoded, null to disable encryption)
* @param baseUrl custom base URL for DashScope API (null for default)
* @param formatter the message formatter to use (null for default DashScope formatter)
* @param httpTransport custom HTTP transport (null for default from factory)
* @param publicKeyId the RSA public key ID for encryption (null to disable encryption)
* @param publicKey the RSA public key for encryption (Base64-encoded, null to disable encryption)
* @deprecated Use {@link #builder()} instead.
*/
@Deprecated(since = "1.0.12", forRemoval = true)
public DashScopeChatModel(
String apiKey,
String modelName,
Expand All @@ -138,6 +143,53 @@ public DashScopeChatModel(
HttpTransport httpTransport,
String publicKeyId,
String publicKey) {
this(
apiKey,
modelName,
stream,
enableThinking,
enableSearch,
null,
null,
defaultOptions,
baseUrl,
formatter,
httpTransport,
publicKeyId,
publicKey);
}

/**
* Creates a new DashScope chat model instance with explicit API type.
*
* @param apiKey the API key for DashScope authentication
* @param modelName the model name (e.g., "qwen-max", "qwen-vl-plus")
* @param stream whether streaming should be enabled (ignored if enableThinking is true)
* @param enableThinking whether thinking mode should be enabled (null for disabled)
* @param enableSearch whether search enhancement should be enabled (null for disabled)
* @param preserveThinking whether to append reasoning_content (null for disabled)
* @param endpointType the endpoint type to use (null for AUTO detection)
* @param defaultOptions default generation options (null for defaults)
* @param baseUrl custom base URL for DashScope API (null for default)
* @param formatter the message formatter to use (null for default DashScope formatter)
* @param httpTransport custom HTTP transport (null for default from factory)
* @param publicKeyId the RSA public key ID for encryption (null to disable encryption)
* @param publicKey the RSA public key for encryption (Base64-encoded, null to disable encryption)
*/
protected DashScopeChatModel(
String apiKey,
String modelName,
boolean stream,
Boolean enableThinking,
Boolean enableSearch,
Boolean preserveThinking,
EndpointType endpointType,
GenerateOptions defaultOptions,
String baseUrl,
Formatter<DashScopeMessage, DashScopeResponse, DashScopeRequest> formatter,
HttpTransport httpTransport,
String publicKeyId,
String publicKey) {
this.modelName = modelName;
// Thinking mode requires streaming; override stream setting if needed
if (enableThinking != null && enableThinking && !stream) {
Expand All @@ -148,6 +200,7 @@ public DashScopeChatModel(
this.stream = enableThinking != null && enableThinking ? true : stream;
this.enableThinking = enableThinking;
this.enableSearch = enableSearch;
this.preserveThinking = preserveThinking;
this.endpointType = endpointType != null ? endpointType : EndpointType.AUTO;
this.defaultOptions =
defaultOptions != null ? defaultOptions : GenerateOptions.builder().build();
Expand Down Expand Up @@ -187,8 +240,8 @@ public static Builder builder() {
* <p>Supports timeout and retry configuration through GenerateOptions.
*
* @param messages AgentScope messages to send to the model
* @param tools Optional list of tool schemas
* @param options Optional generation options (null to use defaults)
* @param tools Optional list of tool schemas
* @param options Optional generation options (null to use defaults)
* @return Flux stream of chat responses
*/
@Override
Expand Down Expand Up @@ -337,6 +390,10 @@ private void applyThinkingMode(DashScopeRequest request, GenerateOptions options
request.getParameters().setThinkingBudget(options.getThinkingBudget());
}

if (Boolean.TRUE.equals(enableThinking) && preserveThinking != null) {
request.getParameters().setPreserveThinking(preserveThinking);
}

// Model-specific settings for search mode
if (enableSearch != null) {
// Explicitly assign value for search mode
Expand All @@ -359,6 +416,7 @@ public static class Builder {
private String modelName;
private boolean stream = true;
private Boolean enableThinking;
private Boolean preserveThinking;
private Boolean enableSearch;
private EndpointType endpointType;
private GenerateOptions defaultOptions = null;
Expand Down Expand Up @@ -420,6 +478,19 @@ public Builder enableThinking(Boolean enableThinking) {
return this;
}

/**
* Sets whether to append the reasoning_content of the assistant message in the conversation history to the model input.
*
* <p>When enabled, this reasoning_content will be appended to the model input.
*
* @param preserveThinking true to append reasoning_content, false to disable, null for default (disabled)
* @return this builder instance
*/
public Builder preserveThinking(Boolean preserveThinking) {
this.preserveThinking = preserveThinking;
return this;
}

/**
* Sets whether search enhancement should be enabled.
*
Expand Down Expand Up @@ -533,7 +604,7 @@ public Builder httpTransport(HttpTransport httpTransport) {
* }</pre>
*
* @param enableEncrypt true to enable encryption (will fetch public key automatically),
* false to disable encryption
* false to disable encryption
* @return this builder instance
*/
public Builder enableEncrypt(boolean enableEncrypt) {
Expand All @@ -552,7 +623,7 @@ public Builder enableEncrypt(boolean enableEncrypt) {
*
* @return configured DashScopeChatModel instance
* @throws DashScopeHttpClient.DashScopeHttpException if encryption is enabled and
* public key fetching fails
* public key fetching fails
*/
public DashScopeChatModel build() {
GenerateOptions effectiveOptions =
Expand All @@ -576,6 +647,7 @@ public DashScopeChatModel build() {
stream,
enableThinking,
enableSearch,
preserveThinking,
endpointType,
effectiveOptions,
baseUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,8 @@ public static boolean isMultimodalModel(String modelName) {
return lowerModelName.startsWith("qvq")
|| lowerModelName.contains("-vl")
|| lowerModelName.contains("-asr")
|| lowerModelName.startsWith("qwen3.5");
|| lowerModelName.startsWith("qwen3.5")
|| lowerModelName.startsWith("qwen3.6");
}

/**
Expand Down Expand Up @@ -484,7 +485,7 @@ public static PublicKeyResult fetchPublicKey(
* @param publicKeyId the public key ID
* @param publicKey the Base64-encoded public key
*/
public static record PublicKeyResult(String publicKeyId, String publicKey) {}
public record PublicKeyResult(String publicKeyId, String publicKey) {}

private Map<String, String> buildHeaders(
boolean streaming, Map<String, String> additionalHeaders, EncryptionContext context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ void testDashScopeParametersBuilder() {
.topP(0.95)
.maxTokens(2048)
.enableThinking(true)
.preserveThinking(true)
.thinkingBudget(500)
.seed(42)
.frequencyPenalty(0.5)
Expand All @@ -354,6 +355,7 @@ void testDashScopeParametersBuilder() {
assertEquals(0.95, params.getTopP());
assertEquals(2048, params.getMaxTokens());
assertTrue(params.getEnableThinking());
assertTrue(params.getPreserveThinking());
assertEquals(500, params.getThinkingBudget());
assertEquals(42, params.getSeed());
assertEquals(0.5, params.getFrequencyPenalty());
Expand Down
Loading
Loading