Skip to content
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

[automated] Merge branch 'main' => 'dev' #6133

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2bb24da
Memory usage in CG Slice path could be 0 (#6110)
makazeu Mar 14, 2025
0e16702
Add an option to log unsupported route (#6077)
amadeuszl Mar 14, 2025
6dec70a
Fix tree expansion in evaluation report (#6107)
shyamnamboodiripad Mar 14, 2025
2810fc5
Use just-built packages in the AI chat template by default (#6096)
MackinnonBuck Mar 14, 2025
a2aa47e
Avoid multiple enumerations of messages in FunctionInvokingChatClient…
stephentoub Mar 15, 2025
3d61789
Add AsChatClient for OpenAIResponseClient (#6103)
stephentoub Mar 15, 2025
e4e3187
[AI extensions] Add jsonSchemaIsStrict option to OpenAI options mappi…
danielwinkler Mar 16, 2025
e953b17
pin actions (#6123)
danmoseley Mar 16, 2025
c111414
Expose failed Verify asserts as CI artifacts (#6129)
RussKie Mar 17, 2025
c428df2
Set preferNameDirectory to True (#6122)
makazeu Mar 17, 2025
a89537c
Add AIJsonSchemaCreateOptions.IncludeParameter filter (#6125)
stephentoub Mar 17, 2025
5310768
Update package dependencies (#6115)
peterwald Mar 17, 2025
15adb0b
Update dependencies from https://github.com/dotnet/arcade build 20250…
dotnet-maestro[bot] Mar 17, 2025
a8f71fd
Fix AIFunctionFactory functions to fail for missing required paramete…
stephentoub Mar 17, 2025
824ff6e
Update changelogs for M.E.AI (#6079)
stephentoub Mar 17, 2025
8002436
Merge branch 'dev' into merge/main-to-dev
RussKie Mar 17, 2025
a63d9bb
Fix chat template test version scrubbing (#6140)
MackinnonBuck Mar 18, 2025
037c866
[Telemetry, Logging] Emit {OriginalFormat} as the last property of th…
iliar-turdushev Mar 18, 2025
354bf8d
HybridCache: richer detection for field-only types (ref STJ) (#6118)
mgravell Mar 18, 2025
6a23beb
Fixes #5856 (#6147)
iliar-turdushev Mar 18, 2025
9cd1186
Fix indentation in chat template readme (#6134)
SteveSandersonMS Mar 18, 2025
8eb39af
In chat template, display preformatted/code snippet outputs sensibly …
SteveSandersonMS Mar 18, 2025
c1fcca2
Use only a single TFM for M.E.AI.Eval.Reporting.Console (#6148)
peterwald Mar 18, 2025
dac7c3e
Update algorithm spelling in /// (#6149)
gewarren Mar 18, 2025
13dad08
Merge branch 'main' into merge/main-to-dev
RussKie Mar 18, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/backport.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ permissions:
jobs:
backport:
if: ${{ contains(github.event.comment.body, '/backport to') || github.event_name == 'schedule' }}
uses: dotnet/arcade/.github/workflows/backport-base.yml@main
uses: dotnet/arcade/.github/workflows/backport-base.yml@1912d9f4fc410d421a01b5a09131aae234b603fa # main
with:
pr_description_template: |
Backport of #%source_pr_number% to %target_branch%
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/inter-branch-merge-flow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ permissions:

jobs:
Merge:
uses: dotnet/arcade/.github/workflows/inter-branch-merge-base.yml@main
uses: dotnet/arcade/.github/workflows/inter-branch-merge-base.yml@1912d9f4fc410d421a01b5a09131aae234b603fa # main
2 changes: 1 addition & 1 deletion .github/workflows/locker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
if: ${{ github.repository_owner == 'dotnet' }}
steps:
- name: Checkout Actions
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
repository: "microsoft/vscode-github-triage-actions"
path: ./actions
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
name: Update .NET SDK
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
ref: dev
- uses: martincostello/update-dotnet-sdk@76e2c0df2303d4f6a404228105ebb7d60ace0556 # v3.4.0
Expand Down
4 changes: 0 additions & 4 deletions eng/Version.Details.xml
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,5 @@
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha />
</Dependency>
<Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="9.0.0-beta.25161.4">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>f33d9e642f0e68a61312164cd9e0baf4e142a999</Sha>
</Dependency>
</ToolsetDependencies>
</Dependencies>
4 changes: 1 addition & 3 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -201,19 +201,17 @@
<!-- Compatibility with VS 17.8/.NET SDK 8.0.1xx -->
<MicrosoftCodeAnalysisVersion>4.8.0</MicrosoftCodeAnalysisVersion>
<MicrosoftCodeAnalysisAnalyzersVersion>3.3.4</MicrosoftCodeAnalysisAnalyzersVersion>

<!-- AI templates -->
<AzureAIProjectsVersion>1.0.0-beta.3</AzureAIProjectsVersion>
<AzureAIOpenAIVersion>2.2.0-beta.1</AzureAIOpenAIVersion>
<AzureIdentityVersion>1.13.2</AzureIdentityVersion>
<AzureSearchDocumentsVersion>11.6.0</AzureSearchDocumentsVersion>
<MicrosoftSemanticKernelConnectorsAzureAISearchVersion>1.37.0-preview</MicrosoftSemanticKernelConnectorsAzureAISearchVersion>
<MicrosoftSemanticKernelCoreVersion>1.37.0</MicrosoftSemanticKernelCoreVersion>
<OllamaSharpVersion>5.0.7</OllamaSharpVersion>
<OllamaSharpVersion>5.1.5</OllamaSharpVersion>
<OpenAIVersion>2.2.0-beta.1</OpenAIVersion>
<PdfPigVersion>0.1.9</PdfPigVersion>
<SystemLinqAsyncVersion>6.0.1</SystemLinqAsyncVersion>

<!--
xUnit version is configured by the Arcade SDK.
https://github.com/dotnet/arcade/blob/f5a7c5d5c56197b09715dece7541ca06beb94eb0/src/Microsoft.DotNet.Arcade.Sdk/tools/XUnit/XUnit.targets#L9
Expand Down
2 changes: 1 addition & 1 deletion eng/packages/General.props
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<PackageVersion Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.0" />
<PackageVersion Include="Microsoft.ML.Tokenizers" Version="$(MicrosoftMLTokenizersVersion)" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="OpenAI" Version="2.2.0-beta.1" />
<PackageVersion Include="OpenAI" Version="2.2.0-beta.3" />
<PackageVersion Include="Polly" Version="8.4.2" />
<PackageVersion Include="Polly.Core" Version="8.4.2" />
<PackageVersion Include="Polly.Extensions" Version="8.4.2" />
Expand Down
2 changes: 1 addition & 1 deletion eng/packages/TestOnly.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageVersion Include="AutoFixture.AutoMoq" Version="4.17.0" />
<PackageVersion Include="Azure.AI.OpenAI" Version="2.2.0-beta.1" />
<PackageVersion Include="Azure.AI.OpenAI" Version="2.2.0-beta.2" />
<PackageVersion Include="Azure.Identity" Version="1.13.2" />
<PackageVersion Include="autofixture" Version="4.17.0" />
<PackageVersion Include="BenchmarkDotNet" Version="0.13.5" />
Expand Down
42 changes: 42 additions & 0 deletions eng/pipelines/templates/BuildAndTest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,48 @@ steps:
"${{ parameters.buildScript }} -test -configuration ${{ parameters.buildConfig }} /bl:${{ parameters.repoLogPath }}/tests.binlog $(_OfficialBuildIdArgs)"
displayName: Run tests

- pwsh: |
$SourcesDirectory = '$(Build.SourcesDirectory)';

$destinationPath = "${{ parameters.repoLogPath }}/FailedAssertions"
if (-not (Test-Path -Path $destinationPath)) {
New-Item -Path $destinationPath -ItemType Directory -Force | Out-Null
}

Get-ChildItem $SourcesDirectory -Filter "*.received.*" -Recurse | `
ForEach-Object {
# Exclude files that are already in the test results path
if ($_.FullName -like "*FailedAssertions*") {
return
}

if ($_.PSIsContainer) {
# Delete the folder if it exists
$dest = Join-Path -Path $destinationPath -ChildPath $_.Name
if (Test-Path -Path $dest) {
Remove-Item -Path $dest -Recurse -Force
}
# Copy folder to logs
Copy-Item -Path $_.FullName -Destination $destinationPath -Recurse -Force
}
else {
# Calculates the relative path of the file with respect to `$SourcesDirectory`.
$relativePath = [System.IO.Path]::GetRelativePath($SourcesDirectory, $_.FullName)
# Constructs the full destination path for the file, preserving the relative directory structure.
$destinationFile = Join-Path -Path $destinationPath -ChildPath $relativePath
$destinationDirectory = [System.IO.Path]::GetDirectoryName($destinationFile)
# Ensures the destination directory exists (creates it if necessary).
if (-not (Test-Path -Path $destinationDirectory)) {
New-Item -Path $destinationDirectory -ItemType Directory -Force | Out-Null
}
# Copies the file to the destination path.
Copy-Item -Path $_.FullName -Destination $destinationFile -Force
}
}
displayName: Copy failed assertions results to logs
condition: always()
continueOnError: true

- pwsh: |
Get-ChildItem ${{ parameters.repoTestResultsPath }} -Include "*_hangdump.dmp","Sequence_*.xml" -Recurse | `
ForEach-Object {
Expand Down
17 changes: 10 additions & 7 deletions src/Generators/Microsoft.Gen.Logging/Emission/Emitter.Method.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ private void GenLogMethod(LoggingMethod lm)
OutLn($"[{GeneratorUtilities.GeneratedCodeAttribute}] static string ({lambdaStateName}, {exceptionLambdaName}) =>");
OutOpenBrace();

if (GenVariableAssignments(lm, lambdaStateName, numReservedUnclassifiedTags, numReservedClassifiedTags))
if (!string.IsNullOrEmpty(lm.Message) &&
GenVariableAssignments(lm, lambdaStateName, numReservedUnclassifiedTags, numReservedClassifiedTags))
{
var mapped = Parsing.TemplateProcessor.MapTemplates(lm.Message, t =>
{
Expand Down Expand Up @@ -318,7 +319,14 @@ void GenTagWrites(LoggingMethod lm, string stateName, out int numReservedUnclass
{
OutLn();
OutLn($"_ = {stateName}.ReserveTagSpace({numReservedUnclassifiedTags});");

int count = numReservedUnclassifiedTags;

if (!string.IsNullOrEmpty(lm.Message))
{
OutLn($"{stateName}.TagArray[{--count}] = new(\"{{OriginalFormat}}\", {EscapeMessageString(lm.Message)});");
}

foreach (var p in lm.Parameters)
{
if (NeedsASlot(p) && !p.HasDataClassification)
Expand Down Expand Up @@ -367,11 +375,6 @@ void GenTagWrites(LoggingMethod lm, string stateName, out int numReservedUnclass
});
}
}

if (!string.IsNullOrEmpty(lm.Message))
{
OutLn($"{stateName}.TagArray[{--count}] = new(\"{{OriginalFormat}}\", {EscapeMessageString(lm.Message)});");
}
}

if (numReservedClassifiedTags > 0)
Expand Down Expand Up @@ -516,7 +519,7 @@ bool GenVariableAssignments(LoggingMethod lm, string lambdaStateName, int numRes
{
bool generatedAssignments = false;

int index = numReservedUnclassifiedTags - 1;
int index = numReservedUnclassifiedTags - 2;
foreach (var p in lm.Parameters)
{
if (NeedsASlot(p) && !p.HasDataClassification)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ internal sealed class HttpLoggingRedactionInterceptor : IHttpLoggingInterceptor
private readonly HeaderReader _responseHeadersReader;
private readonly string[] _excludePathStartsWith;
private readonly FrozenDictionary<string, DataClassification> _parametersToRedactMap;
private readonly bool _includeUnmatchedRoutes;

public HttpLoggingRedactionInterceptor(
IOptions<LoggingRedactionOptions> options,
Expand All @@ -59,6 +60,7 @@ public HttpLoggingRedactionInterceptor(
_responseHeadersReader = new(optionsValue.ResponseHeadersDataClasses, redactorProvider, HttpLoggingTagNames.ResponseHeaderPrefix);

_excludePathStartsWith = optionsValue.ExcludePathStartsWith.ToArray();
_includeUnmatchedRoutes = optionsValue.IncludeUnmatchedRoutes;
}

public ValueTask OnRequestAsync(HttpLoggingInterceptorContext logContext)
Expand Down Expand Up @@ -115,6 +117,10 @@ public ValueTask OnRequestAsync(HttpLoggingInterceptorContext logContext)
}
}
}
else if (_includeUnmatchedRoutes)
{
path = context.Request.Path.ToString();
}
}
else if (request.Path.HasValue)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,15 @@ public class LoggingRedactionOptions
#pragma warning disable CA2227 // Collection properties should be read only
public ISet<string> ExcludePathStartsWith { get; set; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
#pragma warning restore CA2227 // Collection properties should be read only

/// <summary>
/// Gets or sets a value indicating whether to report unmatched routes.
/// </summary>
/// <remarks>
/// If set to true, instead of logging <i>unknown</i> value for path attribute it will log whole path of routes not identified by ASP.NET Routing.
/// </remarks>
/// <value>Defaults to <see langword="false"/>.</value>
public bool IncludeUnmatchedRoutes { get; set; }
}

#endif
13 changes: 13 additions & 0 deletions src/Libraries/Microsoft.Extensions.AI.Abstractions/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Release History

## 9.3.0-preview.1.25161.3

- Changed `IChatClient.GetResponseAsync` and `IChatClient.GetStreamingResponseAsync` to accept an `IEnumerable<ChatMessage>` rather than an `IList<ChatMessage>`. It is no longer mutated by implementations.
- Removed `ChatResponse.Choice` and `ChatResponseUpdate.ChoiceIndex`.
- Replaced `ChatResponse.Message` with `ChatResponse.Messages`. Responses now carry with them all messages generated as part of the operation, rather than all but the last being added to the history and the last returned.
- Added `GetRequiredService` extension method for `IChatClient`/`IEmbeddingGenerator`.
- Added non-generic `IEmbeddingGenerator` interface, which is inherited by `IEmbeddingGenerator<TInput, TEmbedding>`. The `GetService` method moves down to the non-generic interface, and the `GetService`/`GetRequiredService` extension methods are now in terms of the non-generic.
- `AIJsonUtilities.CreateFunctionJsonSchema` now special-cases `CancellationToken` to not include it in the schema.
- Improved the debugger displays for `ChatMessage` and the `AIContent` types.
- Added a static `AIJsonUtilities.HashDataToString` method.
- Split `DataContent`, which handled both in-memory data and URIs to remote data, into `DataContent` (for the former) and `UriContent` (for the latter).
- Renamed `DataContent.MediaTypeStartsWith` to `DataContent.HasTopLevelMediaType`, and changed semantics accordingly.

## 9.3.0-preview.1.25114.11

- Renamed `IChatClient.Complete{Streaming}Async` to `IChatClient.Get{Streaming}ResponseAsync`. This is to avoid confusion with "Complete" being about stopping an operation, as well as to avoid tying the methods to a particular implementation detail of how responses are generated. Along with this, renamed `ChatCompletion` to `ChatResponse`, `StreamingChatCompletionUpdate` to `ChatResponseUpdate`, `CompletionId` to `ResponseId`, `ToStreamingChatCompletionUpdates` to `ToChatResponseUpdates`, and `ToChatCompletion{Async}` to `ToChatResponse{Async}`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -47,7 +48,7 @@ public static void AddMessages(this IList<ChatMessage> list, ChatResponse respon
/// <exception cref="ArgumentNullException"><paramref name="list"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException"><paramref name="updates"/> is <see langword="null"/>.</exception>
/// <remarks>
/// As part of combining <paramref name="updates"/> into a series of <see cref="ChatMessage"/> instances, tne
/// As part of combining <paramref name="updates"/> into a series of <see cref="ChatMessage"/> instances, the
/// method may use <see cref="ChatResponseUpdate.ResponseId"/> to determine message boundaries, as well as coalesce
/// contiguous <see cref="AIContent"/> items where applicable, e.g. multiple
/// <see cref="TextContent"/> instances in a row may be combined into a single <see cref="TextContent"/>.
Expand All @@ -65,6 +66,33 @@ public static void AddMessages(this IList<ChatMessage> list, IEnumerable<ChatRes
list.AddMessages(updates.ToChatResponse());
}

/// <summary>Converts the <paramref name="update"/> into a <see cref="ChatMessage"/> instance and adds it to <paramref name="list"/>.</summary>
/// <param name="list">The destination list to which the newly constructed message should be added.</param>
/// <param name="update">The <see cref="ChatResponseUpdate"/> instance to convert to a message and add to the list.</param>
/// <param name="filter">A predicate to filter which <see cref="AIContent"/> gets included in the message.</param>
/// <exception cref="ArgumentNullException"><paramref name="list"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException"><paramref name="update"/> is <see langword="null"/>.</exception>
/// <remarks>
/// If the <see cref="ChatResponseUpdate"/> has no content, or all its content gets excluded by <paramref name="filter"/>, then
/// no <see cref="ChatMessage"/> will be added to the <paramref name="list"/>.
/// </remarks>
public static void AddMessages(this IList<ChatMessage> list, ChatResponseUpdate update, Func<AIContent, bool>? filter = null)
{
_ = Throw.IfNull(list);
_ = Throw.IfNull(update);

var contentsList = filter is null ? update.Contents : update.Contents.Where(filter).ToList();
if (contentsList.Count > 0)
{
list.Add(new ChatMessage(update.Role ?? ChatRole.Assistant, contentsList)
{
AuthorName = update.AuthorName,
RawRepresentation = update.RawRepresentation,
AdditionalProperties = update.AdditionalProperties,
});
}
}

/// <summary>Converts the <paramref name="updates"/> into <see cref="ChatMessage"/> instances and adds them to <paramref name="list"/>.</summary>
/// <param name="list">The list to which the newly constructed messages should be added.</param>
/// <param name="updates">The <see cref="ChatResponseUpdate"/> instances to convert to messages and add to the list.</param>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.Extensions.AI;

/// <summary>Represents a hosted tool that can be specified to an AI service to enable it to execute code it generates.</summary>
/// <remarks>
/// This tool does not itself implement code interpretation. It is a marker that can be used to inform a service
/// that the service is allowed to execute its generated code if the service is capable of doing so.
/// </remarks>
public class HostedCodeInterpreterTool : AITool
{
/// <summary>Initializes a new instance of the <see cref="HostedCodeInterpreterTool"/> class.</summary>
public HostedCodeInterpreterTool()
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.Extensions.AI;

/// <summary>Represents a hosted tool that can be specified to an AI service to enable it to perform web searches.</summary>
/// <remarks>
/// This tool does not itself implement web searches. It is a marker that can be used to inform a service
/// that the service is allowed to perform web searches if the service is capable of doing so.
/// </remarks>
public class HostedWebSearchTool : AITool
{
/// <summary>Initializes a new instance of the <see cref="HostedWebSearchTool"/> class.</summary>
public HostedWebSearchTool()
{
}
}
Loading
Loading