diff --git a/sample/Cnblogs.DashScope.Sample/Cnblogs.DashScope.Sample.csproj b/sample/Cnblogs.DashScope.Sample/Cnblogs.DashScope.Sample.csproj
index a5cb962..a7ba2f0 100644
--- a/sample/Cnblogs.DashScope.Sample/Cnblogs.DashScope.Sample.csproj
+++ b/sample/Cnblogs.DashScope.Sample/Cnblogs.DashScope.Sample.csproj
@@ -20,7 +20,7 @@
-
+
diff --git a/sample/Cnblogs.DashScope.Sample/Program.cs b/sample/Cnblogs.DashScope.Sample/Program.cs
index 8245f17..c5958f3 100644
--- a/sample/Cnblogs.DashScope.Sample/Program.cs
+++ b/sample/Cnblogs.DashScope.Sample/Program.cs
@@ -211,7 +211,7 @@ async Task ChatWithMicrosoftExtensions()
new(ChatRole.System, "You are a helpful AI assistant"),
new(ChatRole.User, "What is AI?")
];
- var response = await chatClient.CompleteAsync(conversation);
+ var response = await chatClient.GetResponseAsync(conversation);
var serializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web) { WriteIndented = true };
Console.WriteLine(JsonSerializer.Serialize(response, serializerOptions));
}
diff --git a/sample/Cnblogs.DashScope.Sample/ToolCallWithExtensions.cs b/sample/Cnblogs.DashScope.Sample/ToolCallWithExtensions.cs
index f170c7f..0c30cd4 100644
--- a/sample/Cnblogs.DashScope.Sample/ToolCallWithExtensions.cs
+++ b/sample/Cnblogs.DashScope.Sample/ToolCallWithExtensions.cs
@@ -10,12 +10,12 @@ public static class ToolCallWithExtensions
public static async Task ToolCallWithExtensionAsync(this IDashScopeClient dashScopeClient)
{
[Description("Gets the weather")]
- string GetWeather() => Random.Shared.NextDouble() > 0.5 ? "It's sunny" : "It's raining";
+ string GetWeather(string location) => Random.Shared.NextDouble() > 0.5 ? "It's sunny" : "It's raining";
var chatOptions = new ChatOptions { Tools = [AIFunctionFactory.Create(GetWeather)] };
var client = dashScopeClient.AsChatClient("qwen-max").AsBuilder().UseFunctionInvocation().Build();
- await foreach (var message in client.CompleteStreamingAsync("What is weather today?", chatOptions))
+ await foreach (var message in client.GetStreamingResponseAsync("What is weather of LA today?", chatOptions))
{
Console.WriteLine(JsonSerializer.Serialize(message));
}
diff --git a/src/Cnblogs.DashScope.AI/Cnblogs.DashScope.AI.csproj b/src/Cnblogs.DashScope.AI/Cnblogs.DashScope.AI.csproj
index 8a22a11..fe758a6 100644
--- a/src/Cnblogs.DashScope.AI/Cnblogs.DashScope.AI.csproj
+++ b/src/Cnblogs.DashScope.AI/Cnblogs.DashScope.AI.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/src/Cnblogs.DashScope.AI/DashScopeChatClient.cs b/src/Cnblogs.DashScope.AI/DashScopeChatClient.cs
index b1c69f2..8b0012f 100644
--- a/src/Cnblogs.DashScope.AI/DashScopeChatClient.cs
+++ b/src/Cnblogs.DashScope.AI/DashScopeChatClient.cs
@@ -34,7 +34,6 @@ public DashScopeChatClient(IDashScopeClient dashScopeClient, string modelId)
_dashScopeClient = dashScopeClient;
_modelId = modelId;
- Metadata = new ChatClientMetadata("dashscope", _dashScopeClient.BaseAddress, _modelId);
}
///
@@ -43,7 +42,7 @@ public DashScopeChatClient(IDashScopeClient dashScopeClient, string modelId)
public JsonSerializerOptions ToolCallJsonSerializerOptions { get; set; } = new(JsonSerializerDefaults.Web);
///
- public async Task CompleteAsync(
+ public async Task GetResponseAsync(
IList chatMessages,
ChatOptions? options = null,
CancellationToken cancellationToken = default)
@@ -52,7 +51,6 @@ public async Task CompleteAsync(
var useVlRaw = options?.AdditionalProperties?.GetValueOrDefault("useVl")?.ToString();
var useVl = string.IsNullOrEmpty(useVlRaw)
? modelId.Contains("qwen-vl", StringComparison.OrdinalIgnoreCase)
- || chatMessages.Any(c => c.Contents.Any(m => m is ImageContent))
: string.Equals(useVlRaw, "true", StringComparison.OrdinalIgnoreCase);
if (useVl)
{
@@ -71,10 +69,10 @@ public async Task CompleteAsync(
};
returnMessage.Contents.Add(new TextContent(response.Output.Choices[0].Message.Content[0].Text));
- var completion = new ChatCompletion(returnMessage)
+ var completion = new ChatResponse(returnMessage)
{
RawRepresentation = response,
- CompletionId = response.RequestId,
+ ResponseId = response.RequestId,
CreatedAt = DateTimeOffset.Now,
ModelId = modelId,
FinishReason = ToFinishReason(response.Output.Choices[0].FinishReason),
@@ -107,10 +105,10 @@ public async Task CompleteAsync(
},
cancellationToken);
var returnMessage = ToChatMessage(response.Output.Choices![0].Message);
- var completion = new ChatCompletion(returnMessage)
+ var completion = new ChatResponse(returnMessage)
{
RawRepresentation = response,
- CompletionId = response.RequestId,
+ ResponseId = response.RequestId,
CreatedAt = DateTimeOffset.Now,
ModelId = modelId,
FinishReason = ToFinishReason(response.Output.Choices[0].FinishReason),
@@ -131,15 +129,14 @@ public async Task CompleteAsync(
}
///
- public async IAsyncEnumerable CompleteStreamingAsync(
+ public async IAsyncEnumerable GetStreamingResponseAsync(
IList chatMessages,
ChatOptions? options = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
var useVlRaw = options?.AdditionalProperties?.GetValueOrDefault("useVl")?.ToString();
- var useVl = string.IsNullOrEmpty(useVlRaw)
- ? chatMessages.Any(c => c.Contents.Any(m => m is ImageContent))
- : string.Equals(useVlRaw, "true", StringComparison.OrdinalIgnoreCase);
+ var useVl = string.Equals(useVlRaw, "true", StringComparison.OrdinalIgnoreCase)
+ || (options?.ModelId?.Contains("qwen-vl") ?? false);
var modelId = options?.ModelId ?? _modelId;
ChatRole? streamedRole = null;
@@ -167,9 +164,9 @@ public async IAsyncEnumerable CompleteStreamingAs
: ToFinishReason(response.Output.Choices[0].FinishReason);
completionId ??= response.RequestId;
- var update = new StreamingChatCompletionUpdate()
+ var update = new ChatResponseUpdate()
{
- CompletionId = completionId,
+ ResponseId = completionId,
CreatedAt = DateTimeOffset.Now,
FinishReason = finishReason,
ModelId = modelId,
@@ -201,10 +198,10 @@ public async IAsyncEnumerable CompleteStreamingAs
if (options?.Tools is { Count: > 0 })
{
// qwen does not support streaming with function call, fallback to non-streaming
- var completion = await CompleteAsync(chatMessages, options, cancellationToken);
- yield return new StreamingChatCompletionUpdate()
+ var completion = await GetResponseAsync(chatMessages, options, cancellationToken);
+ yield return new ChatResponseUpdate()
{
- CompletionId = completion.CompletionId,
+ ResponseId = completion.ResponseId,
Role = completion.Message.Role,
AdditionalProperties = completion.AdditionalProperties,
Contents = completion.Message.Contents,
@@ -241,9 +238,9 @@ public async IAsyncEnumerable CompleteStreamingAs
: ToFinishReason(response.Output.Choices[0].FinishReason);
completionId ??= response.RequestId;
- var update = new StreamingChatCompletionUpdate()
+ var update = new ChatResponseUpdate()
{
- CompletionId = completionId,
+ ResponseId = completionId,
CreatedAt = DateTimeOffset.Now,
FinishReason = finishReason,
ModelId = modelId,
@@ -289,9 +286,6 @@ public void Dispose()
// nothing to dispose.
}
- ///
- public ChatClientMetadata Metadata { get; }
-
private static ChatFinishReason? ToFinishReason(string? finishReason)
=> string.IsNullOrEmpty(finishReason)
? null
@@ -398,10 +392,12 @@ private List ToMultimodalMessageContents(IList MultimodalMessageContent.TextContent(text.Text),
- ImageContent { Data.Length: > 0 } image => MultimodalMessageContent.ImageContent(
- image.Data.Value.Span,
- image.MediaType ?? throw new InvalidOperationException("image media type should not be null")),
- ImageContent { Uri: { } uri } => MultimodalMessageContent.ImageContent(uri),
+ DataContent { Data.Length: > 0 } data when data.MediaTypeStartsWith("image") =>
+ MultimodalMessageContent.ImageContent(
+ data.Data.Value.Span,
+ data.MediaType ?? throw new InvalidOperationException("image media type should not be null")),
+ DataContent { Uri: { } uri } data when data.MediaTypeStartsWith("image") =>
+ MultimodalMessageContent.ImageContent(uri),
_ => null
};
if (content is not null)
@@ -513,15 +509,13 @@ RequiredChatToolMode required when string.IsNullOrEmpty(required.RequiredFunctio
f => new ToolDefinition(
"function",
new FunctionDefinition(
- f.Metadata.Name,
- f.Metadata.Description,
- GetParameterSchema(f.Metadata.Parameters))));
+ f.Name,
+ f.Description,
+ GetParameterSchema(f.JsonSchema))));
}
- private static JsonSchema GetParameterSchema(IEnumerable metadata)
+ private static JsonSchema GetParameterSchema(JsonElement metadata)
{
- return new JsonSchemaBuilder()
- .Properties(metadata.Select(c => (c.Name, Schema: c.Schema as JsonSchema ?? EmptyObjectSchema)).ToArray())
- .Build();
+ return metadata.Deserialize() ?? EmptyObjectSchema;
}
}
diff --git a/src/Cnblogs.DashScope.Core/Cnblogs.DashScope.Core.csproj b/src/Cnblogs.DashScope.Core/Cnblogs.DashScope.Core.csproj
index a9262bd..791029d 100644
--- a/src/Cnblogs.DashScope.Core/Cnblogs.DashScope.Core.csproj
+++ b/src/Cnblogs.DashScope.Core/Cnblogs.DashScope.Core.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/src/Cnblogs.DashScope.Sdk/Cnblogs.DashScope.Sdk.csproj b/src/Cnblogs.DashScope.Sdk/Cnblogs.DashScope.Sdk.csproj
index 2d88884..3480ef8 100644
--- a/src/Cnblogs.DashScope.Sdk/Cnblogs.DashScope.Sdk.csproj
+++ b/src/Cnblogs.DashScope.Sdk/Cnblogs.DashScope.Sdk.csproj
@@ -5,7 +5,7 @@
Cnblogs;Dashscope;AI;Sdk;Embedding;
-
+
diff --git a/src/Cnblogs.DashScope.Sdk/QWen/QWenLlm.cs b/src/Cnblogs.DashScope.Sdk/QWen/QWenLlm.cs
index 6a55c06..b8dbc98 100644
--- a/src/Cnblogs.DashScope.Sdk/QWen/QWenLlm.cs
+++ b/src/Cnblogs.DashScope.Sdk/QWen/QWenLlm.cs
@@ -129,4 +129,9 @@ public enum QWenLlm
/// qwen-coder-turbo-latest
///
QWenCoderTurboLatest = 24,
+
+ ///
+ /// qvq-72b-preview
+ ///
+ QwQ72BPreview = 25
}
diff --git a/src/Cnblogs.DashScope.Sdk/QWen/QWenLlmNames.cs b/src/Cnblogs.DashScope.Sdk/QWen/QWenLlmNames.cs
index 6e09718..8bc299e 100644
--- a/src/Cnblogs.DashScope.Sdk/QWen/QWenLlmNames.cs
+++ b/src/Cnblogs.DashScope.Sdk/QWen/QWenLlmNames.cs
@@ -30,6 +30,7 @@ public static string GetModelName(this QWenLlm llm)
QWenLlm.QWenPlusLatest => "qwen-plus-latest",
QWenLlm.QWenTurboLatest => "qwen-turbo-latest",
QWenLlm.QwQ32BPreview => "qwq-32b-preview",
+ QWenLlm.QwQ72BPreview => "qwq-72b-preview",
_ => ThrowHelper.UnknownModelName(nameof(llm), llm)
};
}
diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/ChatClientTests.cs b/test/Cnblogs.DashScope.Sdk.UnitTests/ChatClientTests.cs
index 9a58f70..89ac79c 100644
--- a/test/Cnblogs.DashScope.Sdk.UnitTests/ChatClientTests.cs
+++ b/test/Cnblogs.DashScope.Sdk.UnitTests/ChatClientTests.cs
@@ -26,7 +26,7 @@ public async Task ChatClient_TextCompletion_SuccessAsync()
var parameter = testCase.RequestModel.Parameters;
// Act
- var response = await client.CompleteAsync(
+ var response = await client.GetResponseAsync(
content,
new ChatOptions()
{
@@ -67,7 +67,7 @@ public async Task ChatClient_TextCompletionStream_SuccessAsync()
var parameter = testCase.RequestModel.Parameters;
// Act
- var response = client.CompleteStreamingAsync(
+ var response = client.GetStreamingResponseAsync(
content,
new ChatOptions()
{
@@ -113,12 +113,12 @@ public async Task ChatClient_ImageRecognition_SuccessAsync()
{
new(
ChatRole.User,
- [new ImageContent(contents[0].Image!), new TextContent(contents[1].Text)])
+ [new DataContent(contents[0].Image!, "image/png"), new TextContent(contents[1].Text)])
};
var parameter = testCase.RequestModel.Parameters;
// Act
- var response = await client.CompleteAsync(
+ var response = await client.GetResponseAsync(
messages,
new ChatOptions
{
@@ -157,12 +157,12 @@ public async Task ChatClient_ImageRecognitionStream_SuccessAsync()
{
new(
ChatRole.User,
- [new ImageContent(contents[0].Image!), new TextContent(contents[1].Text)])
+ [new DataContent(contents[0].Image!, "image/png"), new TextContent(contents[1].Text)])
};
var parameter = testCase.RequestModel.Parameters;
// Act
- var response = client.CompleteStreamingAsync(
+ var response = client.GetStreamingResponseAsync(
messages,
new ChatOptions()
{
diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/Cnblogs.DashScope.Sdk.UnitTests.csproj b/test/Cnblogs.DashScope.Sdk.UnitTests/Cnblogs.DashScope.Sdk.UnitTests.csproj
index 85dc33c..0c74f01 100644
--- a/test/Cnblogs.DashScope.Sdk.UnitTests/Cnblogs.DashScope.Sdk.UnitTests.csproj
+++ b/test/Cnblogs.DashScope.Sdk.UnitTests/Cnblogs.DashScope.Sdk.UnitTests.csproj
@@ -6,16 +6,16 @@
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
-
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/QWenTokenizerTests.cs b/test/Cnblogs.DashScope.Sdk.UnitTests/QWenTokenizerTests.cs
index 997f1d4..8f91a35 100644
--- a/test/Cnblogs.DashScope.Sdk.UnitTests/QWenTokenizerTests.cs
+++ b/test/Cnblogs.DashScope.Sdk.UnitTests/QWenTokenizerTests.cs
@@ -517,6 +517,6 @@ public void QWenTokenizer_CountIndex_SuccessAsync()
// Assert
maxIndex.Should().Be(155);
- tokenCount.Should().BeLessOrEqualTo(100);
+ tokenCount.Should().BeLessThanOrEqualTo(100);
}
}