Skip to content

Commit

Permalink
Merge branch 'main' into py-chat-history-reduce
Browse files Browse the repository at this point in the history
  • Loading branch information
moonbox3 committed Jan 17, 2025
2 parents 66abe04 + b34b16e commit 93f788f
Show file tree
Hide file tree
Showing 17 changed files with 225 additions and 22 deletions.
6 changes: 3 additions & 3 deletions dotnet/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="AWSSDK.BedrockRuntime" Version="3.7.411.5" />
<PackageVersion Include="AWSSDK.BedrockRuntime" Version="4.0.0-preview.5" />
<PackageVersion Include="AWSSDK.Extensions.NETCore.Setup" Version="3.7.301" />
<PackageVersion Include="AWSSDK.Core" Version="3.7.400.64" />
<PackageVersion Include="AWSSDK.Core" Version="4.0.0-preview.5" />
<PackageVersion Include="Azure.AI.Inference" Version="1.0.0-beta.2" />
<PackageVersion Include="Dapr.Actors" Version="1.14.0" />
<PackageVersion Include="Dapr.Actors.AspNetCore" Version="1.14.0" />
Expand Down Expand Up @@ -165,4 +165,4 @@
<PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI.Cuda" Version="0.5.2" />
<PackageVersion Include="Microsoft.ML.OnnxRuntimeGenAI.DirectML" Version="0.5.2" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ internal async Task<IReadOnlyList<ChatMessageContent>> GenerateChatMessageAsync(
{
activityStatus = BedrockClientUtilities.ConvertHttpStatusCodeToActivityStatusCode(response.HttpStatusCode);
activity.SetStatus(activityStatus);
activity.SetPromptTokenUsage(response.Usage.InputTokens);
activity.SetCompletionTokenUsage(response.Usage.OutputTokens);
activity.SetPromptTokenUsage(response?.Usage?.InputTokens ?? default);
activity.SetCompletionTokenUsage(response?.Usage?.OutputTokens ?? default);
}
}
catch (Exception ex)
Expand All @@ -90,8 +90,8 @@ internal async Task<IReadOnlyList<ChatMessageContent>> GenerateChatMessageAsync(
{
activityStatus = BedrockClientUtilities.ConvertHttpStatusCodeToActivityStatusCode(response.HttpStatusCode);
activity.SetStatus(activityStatus);
activity.SetPromptTokenUsage(response.Usage.InputTokens);
activity.SetCompletionTokenUsage(response.Usage.OutputTokens);
activity.SetPromptTokenUsage(response?.Usage?.InputTokens ?? default);
activity.SetCompletionTokenUsage(response?.Usage?.OutputTokens ?? default);
}
else
{
Expand Down Expand Up @@ -191,7 +191,7 @@ internal async IAsyncEnumerable<StreamingChatMessageContent> StreamChatMessageAs
throw;
}
List<StreamingChatMessageContent>? streamedContents = activity is not null ? [] : null;
foreach (var chunk in response.Stream.AsEnumerable())
await foreach (var chunk in response.Stream.ConfigureAwait(false))
{
if (chunk is ContentBlockDeltaEvent deltaEvent)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static Metric GetSDKMetricAlgorithm(VectorStoreRecordVectorProperty vecto
{
DistanceFunction.CosineSimilarity => Metric.Cosine,
DistanceFunction.DotProductSimilarity => Metric.DotProduct,
DistanceFunction.EuclideanDistance => Metric.Euclidean,
DistanceFunction.EuclideanSquaredDistance => Metric.Euclidean,
null => Metric.Cosine,
_ => throw new InvalidOperationException($"Distance function '{vectorProperty.DistanceFunction}' for {nameof(VectorStoreRecordVectorProperty)} '{vectorProperty.DataModelPropertyName}' is not supported by the Pinecone VectorStore.")
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public static string GetSDKDistanceAlgorithm(VectorStoreRecordVectorProperty vec
DistanceFunction.CosineSimilarity => "COSINE",
DistanceFunction.CosineDistance => "COSINE",
DistanceFunction.DotProductSimilarity => "IP",
DistanceFunction.EuclideanDistance => "L2",
DistanceFunction.EuclideanSquaredDistance => "L2",
_ => throw new InvalidOperationException($"Distance function '{vectorProperty.DistanceFunction}' for {nameof(VectorStoreRecordVectorProperty)} '{vectorProperty.DataModelPropertyName}' is not supported by the Redis VectorStore.")
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public static string ResolveDistanceFunction(VectorSearchOptions options, IReadO
DistanceFunction.CosineSimilarity => 1 - redisScore,
DistanceFunction.CosineDistance => redisScore,
DistanceFunction.DotProductSimilarity => redisScore,
DistanceFunction.EuclideanDistance => redisScore,
DistanceFunction.EuclideanSquaredDistance => redisScore,
_ => throw new InvalidOperationException($"The distance function '{distanceFunction}' is not supported."),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ private static string MapDistanceFunction(string? distanceFunction, string vecto
return distanceFunction switch
{
DistanceFunction.CosineDistance => Cosine,
DistanceFunction.DotProductSimilarity => Dot,
DistanceFunction.NegativeDotProductSimilarity => Dot,
DistanceFunction.EuclideanSquaredDistance => EuclideanSquared,
DistanceFunction.Hamming => Hamming,
DistanceFunction.ManhattanDistance => Manhattan,
_ => throw new InvalidOperationException(
$"Distance function '{distanceFunction}' on {nameof(VectorStoreRecordVectorProperty)} '{vectorPropertyName}' is not supported by the Weaviate VectorStore. " +
$"Supported distance functions: {string.Join(", ",
DistanceFunction.CosineDistance,
DistanceFunction.DotProductSimilarity,
DistanceFunction.NegativeDotProductSimilarity,
DistanceFunction.EuclideanSquaredDistance,
DistanceFunction.Hamming,
DistanceFunction.ManhattanDistance)}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,33 @@ ref functionArgumentBuildersByIndex
Assert.Null(exception);
}

[Fact]
public void TrackStreamingToolingUpdateWithEmptyIdNameDoesNotThrowException()
{
// Arrange
Dictionary<int, string>? toolCallIdsByIndex = null;
Dictionary<int, string>? functionNamesByIndex = null;
Dictionary<int, StringBuilder>? functionArgumentBuildersByIndex = null;

// Act
var exception = Record.Exception(() =>
OpenAIFunctionToolCall.TrackStreamingToolingUpdate(
[
GetUpdateChunkFromString("""{"function":{"name":"WeatherPlugin-GetWeather","arguments":"{\"addressCode"},"index":0,"id":"call_74f02d5863864109bae3d1","type":"function"}"""),
GetUpdateChunkFromString("""{"function":{"name":"","arguments":"\": \"44"},"index":0,"id":"","type":"function"}"""),
GetUpdateChunkFromString("""{"function":{"name":"","arguments":"0100"},"index":0,"id":"","type":"function"}"""),
],
ref toolCallIdsByIndex,
ref functionNamesByIndex,
ref functionArgumentBuildersByIndex
));

// Assert
Assert.Null(exception);
Assert.False(string.IsNullOrEmpty(toolCallIdsByIndex![0]));
Assert.False(string.IsNullOrEmpty(functionNamesByIndex![0]));
}

private static StreamingChatToolCallUpdate GetUpdateChunkFromString(string jsonChunk)
=> ModelReaderWriter.Read<StreamingChatToolCallUpdate>(BinaryData.FromString(jsonChunk))!;
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ internal static void TrackStreamingToolingUpdate(
{
// If we have an ID, ensure the index is being tracked. Even if it's not a function update,
// we want to keep track of it so we can send back an error.
if (update.ToolCallId is string id)
if (!string.IsNullOrWhiteSpace(update.ToolCallId))
{
(toolCallIdsByIndex ??= [])[update.Index] = id;
(toolCallIdsByIndex ??= [])[update.Index] = update.ToolCallId;
}

// Ensure we're tracking the function's name.
if (update.FunctionName is string name)
if (!string.IsNullOrWhiteSpace(update.FunctionName))
{
(functionNamesByIndex ??= [])[update.Index] = name;
(functionNamesByIndex ??= [])[update.Index] = update.FunctionName;
}

// Ensure we're tracking the function's arguments.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void MapToSchemaCreatesSchema(bool useDollarPrefix)
new VectorStoreRecordDataProperty("NonFilterableString", typeof(string)),

new VectorStoreRecordVectorProperty("VectorDefaultIndexingOptions", typeof(ReadOnlyMemory<float>)) { Dimensions = 10 },
new VectorStoreRecordVectorProperty("VectorSpecificIndexingOptions", typeof(ReadOnlyMemory<float>)) { Dimensions = 20, IndexKind = IndexKind.Flat, DistanceFunction = DistanceFunction.EuclideanDistance },
new VectorStoreRecordVectorProperty("VectorSpecificIndexingOptions", typeof(ReadOnlyMemory<float>)) { Dimensions = 20, IndexKind = IndexKind.Flat, DistanceFunction = DistanceFunction.EuclideanSquaredDistance },
};

var storagePropertyNames = new Dictionary<string, string>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ public void GetOutputScoreFromRedisScoreConvertsCosineDistanceToSimilarity()
[Theory]
[InlineData(DistanceFunction.CosineDistance, 2)]
[InlineData(DistanceFunction.DotProductSimilarity, 2)]
[InlineData(DistanceFunction.EuclideanDistance, 2)]
[InlineData(DistanceFunction.EuclideanSquaredDistance, 2)]
public void GetOutputScoreFromRedisScoreLeavesNonConsineSimilarityUntouched(string distanceFunction, float score)
{
// Act & Assert.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public void ItThrowsExceptionWithInvalidDistanceFunction()

[Theory]
[InlineData(DistanceFunction.CosineDistance, "cosine")]
[InlineData(DistanceFunction.DotProductSimilarity, "dot")]
[InlineData(DistanceFunction.NegativeDotProductSimilarity, "dot")]
[InlineData(DistanceFunction.EuclideanSquaredDistance, "l2-squared")]
[InlineData(DistanceFunction.Hamming, "hamming")]
[InlineData(DistanceFunction.ManhattanDistance, "manhattan")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,19 @@ public static class DistanceFunction
/// Measures both the length and angle between two vectors.
/// </summary>
/// <remarks>
/// Same as cosine similarity if the vectors are the same length, but more performant.
/// The higher the value, the more similar the vectors.
/// </remarks>
public const string DotProductSimilarity = nameof(DotProductSimilarity);

/// <summary>
/// Measures both the length and angle between two vectors.
/// </summary>
/// <remarks>
/// The value of NegativeDotProduct = -1 * DotProductSimilarity.
/// The higher the value, the greater the distance between the vectors and the less similar the vectors.
/// </remarks>
public const string NegativeDotProductSimilarity = nameof(NegativeDotProductSimilarity);

/// <summary>
/// Measures the Euclidean distance between two vectors.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public async Task VectorSearchShouldReturnExpectedScoresAsync(string distanceFun
// Arrange
var definition = CreateKeyWithVectorRecordDefinition(4, distanceFunction);
var sut = this.GetTargetRecordCollection<KeyWithVectorRecord<TKey>>(
$"scorebydistancefunction{distanceFunction}",
$"scorebydf{distanceFunction}",
definition);

await sut.CreateCollectionIfNotExistsAsync();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft. All rights reserved.

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Connectors.Pinecone;
using SemanticKernel.IntegrationTests.Connectors.Memory.Pinecone.Xunit;
using Xunit;

namespace SemanticKernel.IntegrationTests.Connectors.Memory.Pinecone;

// Disable unused class warning, as this class is marked internal to disable the tests in the base class.
#pragma warning disable CA1812
#pragma warning disable CA1852

/// <summary>
/// Inherits common integration tests that should pass for any <see cref="IVectorStoreRecordCollection{TKey, TRecord}"/>.
/// </summary>
/// <param name="fixture">Pinecone setup and teardown.</param>
[Collection("PineconeVectorStoreTests")]
[PineconeApiKeySetCondition]
internal class CommonPineconeVectorStoreRecordCollectionTests(PineconeVectorStoreFixture fixture) : BaseVectorStoreRecordCollectionTests<string>, IClassFixture<PineconeVectorStoreFixture>
{
protected override string Key1 => "1";
protected override string Key2 => "2";
protected override string Key3 => "3";
protected override string Key4 => "4";

protected override int DelayAfterIndexCreateInMilliseconds => 2000;

protected override int DelayAfterUploadInMilliseconds => 15000;

[SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Pinecone collection names should be lower case.")]
protected override IVectorStoreRecordCollection<string, TRecord> GetTargetRecordCollection<TRecord>(string recordCollectionName, VectorStoreRecordDefinition? vectorStoreRecordDefinition)
{
return new PineconeVectorStoreRecordCollection<TRecord>(fixture.Client, recordCollectionName.ToLowerInvariant(), new()
{
VectorStoreRecordDefinition = vectorStoreRecordDefinition
});
}

protected override HashSet<string> GetSupportedDistanceFunctions()
{
return [DistanceFunction.CosineSimilarity, DistanceFunction.DotProductSimilarity, DistanceFunction.EuclideanSquaredDistance];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) Microsoft. All rights reserved.

using System.Collections.Generic;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Connectors.Redis;
using Xunit;

namespace SemanticKernel.IntegrationTests.Connectors.Memory.Redis;

// Disable unused class warning, as this class is marked internal to disable the tests in the base class.
#pragma warning disable CA1812
#pragma warning disable CA1852

/// <summary>
/// Inherits common integration tests that should pass for any <see cref="IVectorStoreRecordCollection{TKey, TRecord}"/>.
/// </summary>
/// <param name="fixture">Redis setup and teardown.</param>
[Collection("RedisVectorStoreCollection")]
internal class CommonRedisHashsetVectorStoreRecordCollectionTests(RedisVectorStoreFixture fixture) : BaseVectorStoreRecordCollectionTests<string>
{
protected override string Key1 => "1";
protected override string Key2 => "2";
protected override string Key3 => "3";
protected override string Key4 => "4";

protected override IVectorStoreRecordCollection<string, TRecord> GetTargetRecordCollection<TRecord>(string recordCollectionName, VectorStoreRecordDefinition? vectorStoreRecordDefinition)
{
return new RedisHashSetVectorStoreRecordCollection<TRecord>(fixture.Database, recordCollectionName + "hashset", new()
{
VectorStoreRecordDefinition = vectorStoreRecordDefinition
});
}

protected override HashSet<string> GetSupportedDistanceFunctions()
{
// Excluding DotProductSimilarity from the test even though Redis supports it, because the values that redis returns
// are neither DotProductSimilarity nor NegativeDotProduct, but rather 1 - DotProductSimilarity.
return [DistanceFunction.CosineDistance, DistanceFunction.CosineSimilarity, DistanceFunction.EuclideanSquaredDistance];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) Microsoft. All rights reserved.

using System.Collections.Generic;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Connectors.Redis;
using Xunit;

namespace SemanticKernel.IntegrationTests.Connectors.Memory.Redis;

// Disable unused class warning, as this class is marked internal to disable the tests in the base class.
#pragma warning disable CA1812
#pragma warning disable CA1852

/// <summary>
/// Inherits common integration tests that should pass for any <see cref="IVectorStoreRecordCollection{TKey, TRecord}"/>.
/// </summary>
/// <param name="fixture">Redis setup and teardown.</param>
[Collection("RedisVectorStoreCollection")]
internal class CommonRedisJsonVectorStoreRecordCollectionTests(RedisVectorStoreFixture fixture) : BaseVectorStoreRecordCollectionTests<string>
{
protected override string Key1 => "1";
protected override string Key2 => "2";
protected override string Key3 => "3";
protected override string Key4 => "4";

protected override IVectorStoreRecordCollection<string, TRecord> GetTargetRecordCollection<TRecord>(string recordCollectionName, VectorStoreRecordDefinition? vectorStoreRecordDefinition)
{
return new RedisJsonVectorStoreRecordCollection<TRecord>(fixture.Database, recordCollectionName + "json", new()
{
VectorStoreRecordDefinition = vectorStoreRecordDefinition
});
}

protected override HashSet<string> GetSupportedDistanceFunctions()
{
// Excluding DotProductSimilarity from the test even though Redis supports it, because the values that redis returns
// are neither DotProductSimilarity nor NegativeDotProduct, but rather 1 - DotProductSimilarity.
return [DistanceFunction.CosineDistance, DistanceFunction.CosineSimilarity, DistanceFunction.EuclideanSquaredDistance];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Collections.Generic;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Connectors.Weaviate;
using Xunit;

namespace SemanticKernel.IntegrationTests.Connectors.Memory.Weaviate;

/// <summary>
/// Inherits common integration tests that should pass for any <see cref="IVectorStoreRecordCollection{TKey, TRecord}"/>.
/// </summary>
/// <param name="fixture">Weaviate setup and teardown.</param>
[Collection("WeaviateVectorStoreCollection")]
public class CommonWeaviateVectorStoreRecordCollectionTests(WeaviateVectorStoreFixture fixture) : BaseVectorStoreRecordCollectionTests<Guid>
{
protected override Guid Key1 => new("11111111-1111-1111-1111-111111111111");
protected override Guid Key2 => new("22222222-2222-2222-2222-222222222222");
protected override Guid Key3 => new("33333333-3333-3333-3333-333333333333");
protected override Guid Key4 => new("44444444-4444-4444-4444-444444444444");

protected override int DelayAfterUploadInMilliseconds => 1000;

protected override IVectorStoreRecordCollection<Guid, TRecord> GetTargetRecordCollection<TRecord>(string recordCollectionName, VectorStoreRecordDefinition? vectorStoreRecordDefinition)
{
// Weaviate collection names must start with an upper case letter.
var recordCollectionNameChars = recordCollectionName.ToCharArray();
recordCollectionNameChars[0] = char.ToUpperInvariant(recordCollectionNameChars[0]);

return new WeaviateVectorStoreRecordCollection<TRecord>(fixture.HttpClient!, new string(recordCollectionNameChars), new()
{
VectorStoreRecordDefinition = vectorStoreRecordDefinition
});
}

protected override HashSet<string> GetSupportedDistanceFunctions()
{
return [DistanceFunction.CosineDistance, DistanceFunction.NegativeDotProductSimilarity, DistanceFunction.EuclideanSquaredDistance, DistanceFunction.Hamming, DistanceFunction.ManhattanDistance];
}
}

0 comments on commit 93f788f

Please sign in to comment.