diff --git a/src/Cnblogs.DashScope.Core/IMaxTokenParameter.cs b/src/Cnblogs.DashScope.Core/IMaxTokenParameter.cs
new file mode 100644
index 0000000..eb89dae
--- /dev/null
+++ b/src/Cnblogs.DashScope.Core/IMaxTokenParameter.cs
@@ -0,0 +1,15 @@
+namespace Cnblogs.DashScope.Core;
+
+///
+/// Marks parameter supports setting maximum number of output tokens.
+///
+public interface IMaxTokenParameter
+{
+ ///
+ /// The maximum number of tokens the model can generate.
+ ///
+ ///
+ /// Default and maximum number of tokens is 1500(qwen-turbo) or 2000(qwen-max, qwen-max-1201, qwen-max-longcontext, qwen-plus).
+ ///
+ public int? MaxTokens { get; }
+}
diff --git a/src/Cnblogs.DashScope.Core/IMultimodalParameters.cs b/src/Cnblogs.DashScope.Core/IMultimodalParameters.cs
index 42faaf7..c1a2f7f 100644
--- a/src/Cnblogs.DashScope.Core/IMultimodalParameters.cs
+++ b/src/Cnblogs.DashScope.Core/IMultimodalParameters.cs
@@ -3,4 +3,12 @@
///
/// Optional parameters for multi-model generation request.
///
-public interface IMultimodalParameters : IProbabilityParameter, ISeedParameter, IIncrementalOutputParameter;
+public interface IMultimodalParameters
+ : IProbabilityParameter, ISeedParameter, IIncrementalOutputParameter, IPenaltyParameter, IMaxTokenParameter,
+ IStopTokenParameter
+{
+ ///
+ /// Allow higher resolution for inputs. When setting to true, increases the maximum input token from 1280 to 16384. Defaults to false.
+ ///
+ public bool? VlHighResolutionImages { get; }
+}
diff --git a/src/Cnblogs.DashScope.Core/IPenaltyParameter.cs b/src/Cnblogs.DashScope.Core/IPenaltyParameter.cs
new file mode 100644
index 0000000..d00a6e3
--- /dev/null
+++ b/src/Cnblogs.DashScope.Core/IPenaltyParameter.cs
@@ -0,0 +1,18 @@
+namespace Cnblogs.DashScope.Core;
+
+///
+/// Marks parameter accepts presence_penalty and repetition_penalty options.
+///
+public interface IPenaltyParameter
+{
+ ///
+ /// Increasing the repetition penalty can reduce the amount of repetition in the model’s output. A value of 1.0 indicates no penalty, with the default set at 1.1.
+ ///
+ public float? RepetitionPenalty { get; }
+
+ ///
+ /// Control the content repetition in text generated by the model.
+ ///
+ /// Must be in [-2.0, 2.0]. Use higher penalty for batter creativity.
+ public float? PresencePenalty { get; }
+}
diff --git a/src/Cnblogs.DashScope.Core/IProbabilityParameter.cs b/src/Cnblogs.DashScope.Core/IProbabilityParameter.cs
index 0b9eb74..0efa681 100644
--- a/src/Cnblogs.DashScope.Core/IProbabilityParameter.cs
+++ b/src/Cnblogs.DashScope.Core/IProbabilityParameter.cs
@@ -1,7 +1,7 @@
namespace Cnblogs.DashScope.Core;
///
-/// Marks parameter accepts top_p and top_k options.
+/// Marks parameter accepts top_p, top_k and temperature options.
///
public interface IProbabilityParameter
{
@@ -16,4 +16,10 @@ public interface IProbabilityParameter
///
/// top_k would been disabled if applied null or any value larger than 100.
public int? TopK { get; }
+
+ ///
+ /// Controls the diversity of generations. Lower temperature leads to more consistent result.
+ ///
+ /// Must be in [0,2), qwen-max defaults to 0.7.
+ public float? Temperature { get; }
}
diff --git a/src/Cnblogs.DashScope.Core/IStopTokenParameter.cs b/src/Cnblogs.DashScope.Core/IStopTokenParameter.cs
new file mode 100644
index 0000000..793f6a0
--- /dev/null
+++ b/src/Cnblogs.DashScope.Core/IStopTokenParameter.cs
@@ -0,0 +1,12 @@
+namespace Cnblogs.DashScope.Core;
+
+///
+/// Marks parameter supports setting stop tokens.
+///
+public interface IStopTokenParameter
+{
+ ///
+ /// Stop generation when next token or string is in given range.
+ ///
+ public TextGenerationStop? Stop { get; }
+}
diff --git a/src/Cnblogs.DashScope.Core/ITextGenerationParameters.cs b/src/Cnblogs.DashScope.Core/ITextGenerationParameters.cs
index 2e2072a..6466e73 100644
--- a/src/Cnblogs.DashScope.Core/ITextGenerationParameters.cs
+++ b/src/Cnblogs.DashScope.Core/ITextGenerationParameters.cs
@@ -3,7 +3,8 @@
///
/// The text generation options.
///
-public interface ITextGenerationParameters : IIncrementalOutputParameter, ISeedParameter, IProbabilityParameter
+public interface ITextGenerationParameters
+ : IIncrementalOutputParameter, ISeedParameter, IProbabilityParameter, IPenaltyParameter, IMaxTokenParameter, IStopTokenParameter
{
///
/// The format of the result message, must be text or message.
@@ -14,30 +15,6 @@ public interface ITextGenerationParameters : IIncrementalOutputParameter, ISeedP
///
public string? ResultFormat { get; }
- ///
- /// The maximum number of tokens the model can generate.
- ///
- ///
- /// Default and maximum number of tokens is 1500(qwen-turbo) or 2000(qwen-max, qwen-max-1201, qwen-max-longcontext, qwen-plus).
- ///
- public int? MaxTokens { get; }
-
- ///
- /// Increasing the repetition penalty can reduce the amount of repetition in the model’s output. A value of 1.0 indicates no penalty, with the default set at 1.1.
- ///
- public float? RepetitionPenalty { get; }
-
- ///
- /// Controls the diversity of generations. Lower temperature leads to more consistent result.
- ///
- /// Must be in [0,2), defaults to 0.85.
- public float? Temperature { get; }
-
- ///
- /// Stop generation when next token or string is in given range.
- ///
- public TextGenerationStop? Stop { get; }
-
///
/// Enable internet search when generation. Defaults to false.
///
@@ -46,5 +23,10 @@ public interface ITextGenerationParameters : IIncrementalOutputParameter, ISeedP
///
/// Available tools for model to call.
///
- public List? Tools { get; }
+ public IEnumerable? Tools { get; }
+
+ ///
+ /// Behavior when choosing tools.
+ ///
+ public ToolChoice? ToolChoice { get; }
}
diff --git a/src/Cnblogs.DashScope.Core/MultimodalParameters.cs b/src/Cnblogs.DashScope.Core/MultimodalParameters.cs
index 8a4a263..dc6b98b 100644
--- a/src/Cnblogs.DashScope.Core/MultimodalParameters.cs
+++ b/src/Cnblogs.DashScope.Core/MultimodalParameters.cs
@@ -11,9 +11,27 @@ public class MultimodalParameters : IMultimodalParameters
///
public int? TopK { get; set; }
+ ///
+ public float? Temperature { get; set; }
+
///
public ulong? Seed { get; set; }
///
public bool? IncrementalOutput { get; set; }
+
+ ///
+ public bool? VlHighResolutionImages { get; set; }
+
+ ///
+ public float? RepetitionPenalty { get; set; }
+
+ ///
+ public float? PresencePenalty { get; set; }
+
+ ///
+ public int? MaxTokens { get; set; }
+
+ ///
+ public TextGenerationStop? Stop { get; set; }
}
diff --git a/src/Cnblogs.DashScope.Core/TextGenerationParameters.cs b/src/Cnblogs.DashScope.Core/TextGenerationParameters.cs
index e4308f6..fbe42e5 100644
--- a/src/Cnblogs.DashScope.Core/TextGenerationParameters.cs
+++ b/src/Cnblogs.DashScope.Core/TextGenerationParameters.cs
@@ -23,6 +23,9 @@ public class TextGenerationParameters : ITextGenerationParameters
///
public float? RepetitionPenalty { get; set; }
+ ///
+ public float? PresencePenalty { get; set; }
+
///
public float? Temperature { get; set; }
@@ -33,7 +36,10 @@ public class TextGenerationParameters : ITextGenerationParameters
public bool? EnableSearch { get; set; }
///
- public List? Tools { get; set; }
+ public IEnumerable? Tools { get; set; }
+
+ ///
+ public ToolChoice? ToolChoice { get; set; }
///
public bool? IncrementalOutput { get; set; }
diff --git a/src/Cnblogs.DashScope.Core/ToolChoice.cs b/src/Cnblogs.DashScope.Core/ToolChoice.cs
new file mode 100644
index 0000000..030c5c4
--- /dev/null
+++ b/src/Cnblogs.DashScope.Core/ToolChoice.cs
@@ -0,0 +1,47 @@
+using System.Text.Json.Serialization;
+
+namespace Cnblogs.DashScope.Core;
+
+///
+/// Specify the behavior for model when tools are applied.
+///
+[JsonConverter(typeof(ToolChoiceJsonConverter))]
+public record ToolChoice
+{
+ ///
+ /// Make sure tool choices can not be initiated directly.
+ ///
+ private ToolChoice(string type, ToolChoiceFunction? function = null)
+ {
+ Type = type;
+ Function = function;
+ }
+
+ ///
+ /// The type of tool choice.
+ ///
+ public string Type { get; }
+
+ ///
+ /// The function that model must call.
+ ///
+ public ToolChoiceFunction? Function { get; }
+
+ ///
+ /// Model can not call any tools.
+ ///
+ public static readonly ToolChoice NoneChoice = new("none");
+
+ ///
+ /// Model can freely pick between generating a message or calling one or more tools.
+ ///
+ public static readonly ToolChoice AutoChoice = new("auto");
+
+ ///
+ /// Model must call function with specified name.
+ ///
+ /// Name of function.
+ ///
+ public static ToolChoice FunctionChoice(string functionName)
+ => new("function", new ToolChoiceFunction(functionName));
+}
diff --git a/src/Cnblogs.DashScope.Core/ToolChoiceFunction.cs b/src/Cnblogs.DashScope.Core/ToolChoiceFunction.cs
new file mode 100644
index 0000000..3e0c856
--- /dev/null
+++ b/src/Cnblogs.DashScope.Core/ToolChoiceFunction.cs
@@ -0,0 +1,7 @@
+namespace Cnblogs.DashScope.Core;
+
+///
+/// Represents functions that model must call.
+///
+/// The name of the function.
+public record ToolChoiceFunction(string Name);
diff --git a/src/Cnblogs.DashScope.Core/ToolChoiceJsonConverter.cs b/src/Cnblogs.DashScope.Core/ToolChoiceJsonConverter.cs
new file mode 100644
index 0000000..14cfefe
--- /dev/null
+++ b/src/Cnblogs.DashScope.Core/ToolChoiceJsonConverter.cs
@@ -0,0 +1,69 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Cnblogs.DashScope.Core;
+
+///
+/// The converter for
+///
+public class ToolChoiceJsonConverter : JsonConverter
+{
+ ///
+ public override ToolChoice? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ if (reader.TokenType == JsonTokenType.String)
+ {
+ var str = reader.GetString();
+ return str switch
+ {
+ "auto" => ToolChoice.AutoChoice,
+ "none" => ToolChoice.NoneChoice,
+ _ => throw new JsonException("Unknown tool choice type")
+ };
+ }
+
+ if (reader.TokenType == JsonTokenType.Null)
+ {
+ return null;
+ }
+
+ if (reader.TokenType != JsonTokenType.StartObject)
+ {
+ throw new JsonException("Unknown tool choice.");
+ }
+
+ var element = JsonSerializer.Deserialize(ref reader, options);
+ var functionValid = element.TryGetProperty("function", out var function);
+ var typeValid = element.TryGetProperty("type", out var type);
+ if (functionValid == false || typeValid == false || type.ValueKind != JsonValueKind.String)
+ {
+ throw new JsonException("Unknown tool choice type");
+ }
+
+ var toolFunction = function.Deserialize(options);
+ var toolChoiceType = type.GetString();
+ if (toolFunction == null || toolChoiceType != "function")
+ {
+ throw new JsonException("Unknown tool choice type");
+ }
+
+ return ToolChoice.FunctionChoice(toolFunction.Name);
+ }
+
+ ///
+ public override void Write(Utf8JsonWriter writer, ToolChoice value, JsonSerializerOptions options)
+ {
+ if (value.Type != "function")
+ {
+ writer.WriteStringValue(value.Type);
+ }
+ else
+ {
+ writer.WriteStartObject();
+ writer.WriteString("type", value.Type);
+ writer.WritePropertyName("function");
+ JsonSerializer.Serialize(writer, value.Function, options);
+ writer.WriteEndObject();
+ }
+ }
+}
diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.request.body.json b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.request.body.json
index 6034d14..0b0bb59 100644
--- a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.request.body.json
+++ b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.request.body.json
@@ -20,6 +20,12 @@
"parameters": {
"seed": 1234,
"top_k": 100,
- "top_p": 0.81
+ "top_p": 0.81,
+ "vl_high_resolution_images": true,
+ "temperature": 1.1,
+ "repetition_penalty": 1.3,
+ "presence_penalty": 1.2,
+ "max_tokens": 120,
+ "stop": "你好"
}
}
diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.body.txt b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.body.txt
index 4ecdb8f..1a206a5 100644
--- a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.body.txt
+++ b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.body.txt
@@ -1 +1 @@
-{"output":{"choices":[{"finish_reason":"stop","message":{"role":"assistant","content":[{"text":"这张照片显示的是海滩景色,但是无法确定具体的位置信息。图中有一名女子和一只狗在沙滩上互动。背景中有海洋和日出或日落的光线。由于缺乏特定地标或者细节特征,仅凭此图像很难精确识别具体的地点。"}]}}]},"usage":{"output_tokens":58,"input_tokens":1284,"image_tokens":1247},"request_id":"a2a5f2e6-c6d7-9e04-9f92-1d3eee274198"}
+{"output":{"choices":[{"finish_reason":"stop","message":{"role":"assistant","content":[{"text":"这是在海滩上。"}]}}]},"usage":{"output_tokens":6,"input_tokens":3613,"image_tokens":3577},"request_id":"e74b364a-034f-9d0d-8e55-8e5b3580045f"}
\ No newline at end of file
diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.header.txt b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.header.txt
index f0a0026..46cc64f 100644
--- a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.header.txt
+++ b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.header.txt
@@ -1,13 +1,15 @@
-HTTP/1.1 200 OK
-eagleeye-traceid: cf6954f685a19435530858304250b3bc
-content-type: application/json
+HTTP/1.1 200 OK
+eagleeye-traceid: c72728928fd0d00883f6edd204cc6721
+Vary: Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Accept-Encoding
+X-Request-ID: e74b364a-034f-9d0d-8e55-8e5b3580045f
+x-dashscope-timeout: 180
x-dashscope-call-gateway: true
-req-cost-time: 4359
-req-arrive-time: 1709019927268
-resp-start-time: 1709019931627
-x-envoy-upstream-service-time: 4353
-content-encoding: gzip
-vary: Accept-Encoding
-date: Tue, 27 Feb 2024 07:45:31 GMT
-server: istio-envoy
-transfer-encoding: chunked
+x-dashscope-finished: true
+req-cost-time: 3064
+req-arrive-time: 1732531979928
+resp-start-time: 1732531982993
+x-envoy-upstream-service-time: 3054
+Set-Cookie: acw_tc=e74b364a-034f-9d0d-8e55-8e5b3580045f47b5c24e3af603d8590358e45e4696a6;path=/;HttpOnly;Max-Age=1800
+Date: Mon, 25 Nov 2024 10:53:02 GMT
+Server: istio-envoy
+Transfer-Encoding: chunked
diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.request.body.json b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.request.body.json
index 74addce..67f0342 100644
--- a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.request.body.json
+++ b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.request.body.json
@@ -15,8 +15,9 @@
"top_p": 0.8,
"top_k": 100,
"repetition_penalty": 1.1,
+ "presence_penalty": 1.2,
"temperature": 0.85,
- "stop": [[37763, 367]],
+ "stop": "你好",
"enable_search": false,
"incremental_output": false,
"tools": [
@@ -46,6 +47,12 @@
}
}
}
- ]
+ ],
+ "tool_choice": {
+ "type": "function",
+ "function": {
+ "name": "get_current_weather"
+ }
+ }
}
}
diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.body.txt b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.body.txt
index c1f1ae6..cb75b47 100644
--- a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.body.txt
+++ b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.body.txt
@@ -1 +1 @@
-{"output":{"choices":[{"finish_reason":"tool_calls","message":{"role":"assistant","tool_calls":[{"function":{"name":"get_current_weather","arguments":"{\"location\": \"浙江省杭州市\", \"unit\": \"Celsius\"}"},"id":"","type":"function"}],"content":""}}]},"usage":{"total_tokens":36,"output_tokens":31,"input_tokens":5},"request_id":"40b4361e-e936-91b5-879d-355a45d670f8"}
+{"output":{"choices":[{"finish_reason":"stop","message":{"role":"assistant","tool_calls":[{"function":{"name":"get_current_weather","arguments":"{\"location\": \"浙江省杭州市\"}"},"index":0,"id":"call_cec4c19d27624537b583af","type":"function"}],"content":""}}]},"usage":{"total_tokens":219,"output_tokens":8,"input_tokens":211},"request_id":"67300049-c108-9987-b1c1-8e0ee2de6b5d"}
\ No newline at end of file
diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.header.txt b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.header.txt
index 62317c7..111c929 100644
--- a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.header.txt
+++ b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.header.txt
@@ -1,14 +1,14 @@
-HTTP/1.1 200 OK
-eagleeye-traceid: 7328e5207abf69133abfe3a68446fc2d
-content-type: application/json
+HTTP/1.1 200 OK
+eagleeye-traceid: 4c11425c43fe6d3cd142b49fa668a3f8
+Vary: Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Accept-Encoding
+X-Request-ID: 67300049-c108-9987-b1c1-8e0ee2de6b5d
+x-dashscope-timeout: 180
x-dashscope-call-gateway: true
-x-dashscope-experiments: 33e6d810-qwen-max-base-default-imbalance-fix-lua
-req-cost-time: 3898
-req-arrive-time: 1710324737299
-resp-start-time: 1710324741198
-x-envoy-upstream-service-time: 3893
-content-encoding: gzip
-vary: Accept-Encoding
-date: Wed, 13 Mar 2024 10:12:21 GMT
-server: istio-envoy
-transfer-encoding: chunked
+x-dashscope-finished: true
+req-cost-time: 1050
+req-arrive-time: 1732528382029
+resp-start-time: 1732528383079
+x-envoy-upstream-service-time: 1042
+Date: Mon, 25 Nov 2024 09:53:03 GMT
+Server: istio-envoy
+Transfer-Encoding: chunked
diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/ToolChoiceJsonConverterTests.cs b/test/Cnblogs.DashScope.Sdk.UnitTests/ToolChoiceJsonConverterTests.cs
new file mode 100644
index 0000000..077a4b0
--- /dev/null
+++ b/test/Cnblogs.DashScope.Sdk.UnitTests/ToolChoiceJsonConverterTests.cs
@@ -0,0 +1,68 @@
+using System.Text.Json;
+using Cnblogs.DashScope.Core;
+using FluentAssertions;
+
+namespace Cnblogs.DashScope.Sdk.UnitTests;
+
+public class ToolChoiceJsonConverterTests
+{
+ private static readonly JsonSerializerOptions SerializerOptions =
+ new() { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower };
+
+ [Theory]
+ [MemberData(nameof(Data))]
+ public void TextGenerationStopConvertor_Serialize_Success(ToolChoice? choice, string json)
+ {
+ // Arrange
+ var obj = new TestObj(choice);
+
+ // Act
+ var actual = JsonSerializer.Serialize(obj, SerializerOptions);
+
+ // Assert
+ actual.Should().Be(json);
+ }
+
+ [Theory]
+ [MemberData(nameof(Data))]
+ public void TextGenerationStopConvertor_Deserialize_Success(ToolChoice? choice, string json)
+ {
+ // Act
+ var obj = JsonSerializer.Deserialize(json, SerializerOptions);
+
+ // Assert
+ obj.Should().BeEquivalentTo(new TestObj(choice));
+ }
+
+ [Theory]
+ [MemberData(nameof(InvalidJson))]
+ public void TextGenerationStopConvertor_InvalidJson_Exception(string json)
+ {
+ // Act
+ var act = () => JsonSerializer.Deserialize(json, SerializerOptions);
+
+ // Assert
+ act.Should().Throw();
+ }
+
+ public record TestObj(ToolChoice? Choice);
+
+ public static TheoryData Data
+ => new()
+ {
+ { ToolChoice.AutoChoice, """{"choice":"auto"}""" },
+ { ToolChoice.NoneChoice, """{"choice":"none"}""" },
+ { ToolChoice.FunctionChoice("weather"), """{"choice":{"type":"function","function":{"name":"weather"}}}""" },
+ { null, """{"choice":null}""" }
+ };
+
+ public static TheoryData InvalidJson
+ => new()
+ {
+ """{"choice":{}}""",
+ """{"choice":"other"}""",
+ """{"choice":{"type":"other"}}""",
+ """{"choice":{"type":"other", "function":{"name": "weather"}}}""",
+ """{"choice":{"type":"function", "function": "other"}}"""
+ };
+}
diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/Utils/Snapshots.cs b/test/Cnblogs.DashScope.Sdk.UnitTests/Utils/Snapshots.cs
index 89d0e5c..ec6cf77 100644
--- a/test/Cnblogs.DashScope.Sdk.UnitTests/Utils/Snapshots.cs
+++ b/test/Cnblogs.DashScope.Sdk.UnitTests/Utils/Snapshots.cs
@@ -297,8 +297,9 @@ public static readonly
TopP = 0.8f,
TopK = 100,
RepetitionPenalty = 1.1f,
+ PresencePenalty = 1.2f,
Temperature = 0.85f,
- Stop = new([[37763, 367]]),
+ Stop = new("你好"),
EnableSearch = false,
IncrementalOutput = false,
Tools =
@@ -314,7 +315,8 @@ public static readonly
PropertyNameResolver = PropertyNameResolvers.LowerSnakeCase
})
.Build()))
- ]
+ ],
+ ToolChoice = ToolChoice.FunctionChoice("get_current_weather")
}
},
new()
@@ -325,28 +327,28 @@ public static readonly
[
new()
{
- FinishReason = "tool_calls",
+ FinishReason = "stop",
Message = new(
"assistant",
string.Empty,
ToolCalls:
[
- new(
- string.Empty,
+ new ToolCall(
+ "call_cec4c19d27624537b583af",
ToolTypes.Function,
new FunctionCall(
"get_current_weather",
- """{"location": "浙江省杭州市", "unit": "Celsius"}"""))
+ """{"location": "浙江省杭州市"}"""))
])
}
]
},
- RequestId = "40b4361e-e936-91b5-879d-355a45d670f8",
+ RequestId = "67300049-c108-9987-b1c1-8e0ee2de6b5d",
Usage = new()
{
- InputTokens = 5,
- OutputTokens = 31,
- TotalTokens = 36
+ InputTokens = 211,
+ OutputTokens = 8,
+ TotalTokens = 219
}
});
@@ -483,7 +485,13 @@ public static class MultimodalGeneration
{
Seed = 1234,
TopK = 100,
- TopP = 0.81f
+ TopP = 0.81f,
+ Temperature = 1.1f,
+ VlHighResolutionImages = true,
+ RepetitionPenalty = 1.3f,
+ PresencePenalty = 1.2f,
+ MaxTokens = 120,
+ Stop = "你好"
}
},
new()
@@ -497,15 +505,15 @@ public static class MultimodalGeneration
[
new(
null,
- "这张照片显示的是海滩景色,但是无法确定具体的位置信息。图中有一名女子和一只狗在沙滩上互动。背景中有海洋和日出或日落的光线。由于缺乏特定地标或者细节特征,仅凭此图像很难精确识别具体的地点。")
+ "这是在海滩上。")
]))
]),
- RequestId = "a2a5f2e6-c6d7-9e04-9f92-1d3eee274198",
+ RequestId = "e74b364a-034f-9d0d-8e55-8e5b3580045f",
Usage = new()
{
- OutputTokens = 58,
- InputTokens = 1284,
- ImageTokens = 1247
+ OutputTokens = 6,
+ InputTokens = 3613,
+ ImageTokens = 3577
}
});