Skip to content

feat: upgrade ms extension ai to 9.3.0 #73

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 7, 2025
Merged
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 @@ -20,7 +20,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.AI" Version="9.0.1-preview.1.24570.5" />
<PackageReference Include="Microsoft.Extensions.AI" Version="9.3.0-preview.1.25114.11" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion sample/Cnblogs.DashScope.Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
4 changes: 2 additions & 2 deletions sample/Cnblogs.DashScope.Sample/ToolCallWithExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Cnblogs.DashScope.AI/Cnblogs.DashScope.AI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" Version="9.0.1-preview.1.24570.5"/>
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" Version="9.3.0-preview.1.25114.11" />
</ItemGroup>

</Project>
58 changes: 26 additions & 32 deletions src/Cnblogs.DashScope.AI/DashScopeChatClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public DashScopeChatClient(IDashScopeClient dashScopeClient, string modelId)

_dashScopeClient = dashScopeClient;
_modelId = modelId;
Metadata = new ChatClientMetadata("dashscope", _dashScopeClient.BaseAddress, _modelId);
}

/// <summary>
Expand All @@ -43,7 +42,7 @@ public DashScopeChatClient(IDashScopeClient dashScopeClient, string modelId)
public JsonSerializerOptions ToolCallJsonSerializerOptions { get; set; } = new(JsonSerializerDefaults.Web);

/// <inheritdoc />
public async Task<ChatCompletion> CompleteAsync(
public async Task<ChatResponse> GetResponseAsync(
IList<ChatMessage> chatMessages,
ChatOptions? options = null,
CancellationToken cancellationToken = default)
Expand All @@ -52,7 +51,6 @@ public async Task<ChatCompletion> 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)
{
Expand All @@ -71,10 +69,10 @@ public async Task<ChatCompletion> 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),
Expand Down Expand Up @@ -107,10 +105,10 @@ public async Task<ChatCompletion> 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),
Expand All @@ -131,15 +129,14 @@ public async Task<ChatCompletion> CompleteAsync(
}

/// <inheritdoc />
public async IAsyncEnumerable<StreamingChatCompletionUpdate> CompleteStreamingAsync(
public async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseAsync(
IList<ChatMessage> 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;
Expand Down Expand Up @@ -167,9 +164,9 @@ public async IAsyncEnumerable<StreamingChatCompletionUpdate> 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,
Expand Down Expand Up @@ -201,10 +198,10 @@ public async IAsyncEnumerable<StreamingChatCompletionUpdate> 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,
Expand Down Expand Up @@ -241,9 +238,9 @@ public async IAsyncEnumerable<StreamingChatCompletionUpdate> 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,
Expand Down Expand Up @@ -289,9 +286,6 @@ public void Dispose()
// nothing to dispose.
}

/// <inheritdoc />
public ChatClientMetadata Metadata { get; }

private static ChatFinishReason? ToFinishReason(string? finishReason)
=> string.IsNullOrEmpty(finishReason)
? null
Expand Down Expand Up @@ -398,10 +392,12 @@ private List<MultimodalMessageContent> ToMultimodalMessageContents(IList<AIConte
var content = aiContent switch
{
TextContent text => 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)
Expand Down Expand Up @@ -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<AIFunctionParameterMetadata> 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<JsonSchema>() ?? EmptyObjectSchema;
}
}
2 changes: 1 addition & 1 deletion src/Cnblogs.DashScope.Core/Cnblogs.DashScope.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.ML.Tokenizers" Version="1.0.1"/>
<PackageReference Include="Microsoft.ML.Tokenizers" Version="1.0.2" />
</ItemGroup>

<ItemGroup>
Expand Down
12 changes: 6 additions & 6 deletions test/Cnblogs.DashScope.Sdk.UnitTests/ChatClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down Expand Up @@ -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()
{
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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()
{
Expand Down