From 4ade9b981df5264e5fa345a061b51304f44af221 Mon Sep 17 00:00:00 2001 From: HavenDV Date: Thu, 24 Oct 2024 10:47:02 +0400 Subject: [PATCH] feat: Updated. --- OpenAI.sln | 28 --- .../CSharpToJsonSchema.Generators.csproj | 29 --- .../Conversion/ToModels.cs | 224 ----------------- .../JsonSchemaGenerator.cs | 60 ----- .../Models/InterfaceData.cs | 6 - .../Models/MethodData.cs | 11 - .../Models/OpenApiSchema.cs | 14 -- .../Sources.Calls.cs | 142 ----------- .../Sources.Tools.cs | 92 ------- .../CSharpToJsonSchema.Generators/Steps.cs | 33 --- .../CSharpToJsonSchema.csproj | 43 ---- .../GenerateJsonSchemaAttribute.cs | 15 -- src/libs/CSharpToJsonSchema/OpenApiSchema.cs | 56 ----- src/libs/CSharpToJsonSchema/Tool.cs | 42 ---- .../CSharpToJsonSchema/TypeToSchemaHelpers.cs | 169 ------------- src/libs/Directory.Build.props | 14 ++ .../AssistantClient.CreateRun.AsStream.cs | 20 +- ...hatClient.CreateChatCompletion.AsStream.cs | 20 +- .../ChatCompletionRequestMessage.cs | 31 +++ .../Conversions/CreateMessageRequest.cs | 6 +- .../OpenAI/Extensions/StringExtensions.cs | 23 +- ...nSerializerContextTypes.AdditionalTypes.cs | 5 + src/libs/OpenAI/OpenAI.csproj | 26 +- src/libs/OpenAI/OpenAiApi.Headers.cs | 2 +- .../Tools/FunctionParameters.Extended.cs | 6 - ...ResponseFormatJsonSchemaSchema.Extended.cs | 7 - .../ModuleInitializer.cs | 13 - .../SnapshotTests.cs | 23 -- ...iousTypesTools.Calls.generated.verified.cs | 76 ------ ...iousTypesTools.Tools.generated.verified.cs | 72 ------ ...ests.VariousTypes_Diagnostics.verified.txt | 1 - ...#IWeatherTools.Calls.generated.verified.cs | 106 -------- ...#IWeatherTools.Tools.generated.verified.cs | 69 ------ ...herStrictTools.Calls.generated.verified.cs | 106 -------- ...herStrictTools.Tools.generated.verified.cs | 69 ------ ...sts.WeatherStrict_Diagnostics.verified.txt | 1 - ...ToolTests.Weather_Diagnostics.verified.txt | 1 - .../TestHelper.cs | 44 ---- ...Schema_NonStrict_JsonTypeInfo.verified.txt | 38 --- ...sonSchema_Strict_JsonTypeInfo.verified.txt | 37 --- ...Schema_NonStrict_JsonTypeInfo.verified.txt | 22 -- ...sonSchema_Strict_JsonTypeInfo.verified.txt | 22 -- .../Tests.AsJsonSchema.cs | 83 ------- .../Examples/Examples.Assistants.AllTools.cs | 36 ++- ...xamples.Assistants.AssistantsWithVision.cs | 202 ++++++++-------- .../Examples.Assistants.FunctionCalling.cs | 24 +- ...les.Assistants.FunctionCallingStreaming.cs | 228 +++++++++--------- ...Assistants.RetrievalAugmentedGeneration.cs | 32 ++- .../OpenAI.IntegrationTests.csproj | 1 - 49 files changed, 336 insertions(+), 2094 deletions(-) delete mode 100644 src/libs/CSharpToJsonSchema.Generators/CSharpToJsonSchema.Generators.csproj delete mode 100644 src/libs/CSharpToJsonSchema.Generators/Conversion/ToModels.cs delete mode 100755 src/libs/CSharpToJsonSchema.Generators/JsonSchemaGenerator.cs delete mode 100644 src/libs/CSharpToJsonSchema.Generators/Models/InterfaceData.cs delete mode 100644 src/libs/CSharpToJsonSchema.Generators/Models/MethodData.cs delete mode 100644 src/libs/CSharpToJsonSchema.Generators/Models/OpenApiSchema.cs delete mode 100755 src/libs/CSharpToJsonSchema.Generators/Sources.Calls.cs delete mode 100755 src/libs/CSharpToJsonSchema.Generators/Sources.Tools.cs delete mode 100644 src/libs/CSharpToJsonSchema.Generators/Steps.cs delete mode 100644 src/libs/CSharpToJsonSchema/CSharpToJsonSchema.csproj delete mode 100644 src/libs/CSharpToJsonSchema/GenerateJsonSchemaAttribute.cs delete mode 100644 src/libs/CSharpToJsonSchema/OpenApiSchema.cs delete mode 100644 src/libs/CSharpToJsonSchema/Tool.cs delete mode 100644 src/libs/CSharpToJsonSchema/TypeToSchemaHelpers.cs delete mode 100644 src/libs/OpenAI/Tools/FunctionParameters.Extended.cs delete mode 100644 src/libs/OpenAI/Tools/ResponseFormatJsonSchemaSchema.Extended.cs delete mode 100755 src/tests/CSharpToJsonSchema.SnapshotTests/ModuleInitializer.cs delete mode 100755 src/tests/CSharpToJsonSchema.SnapshotTests/SnapshotTests.cs delete mode 100644 src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.VariousTypes#IVariousTypesTools.Calls.generated.verified.cs delete mode 100644 src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.VariousTypes#IVariousTypesTools.Tools.generated.verified.cs delete mode 100644 src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.VariousTypes_Diagnostics.verified.txt delete mode 100644 src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.Weather#IWeatherTools.Calls.generated.verified.cs delete mode 100644 src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.Weather#IWeatherTools.Tools.generated.verified.cs delete mode 100644 src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.WeatherStrict#IWeatherStrictTools.Calls.generated.verified.cs delete mode 100644 src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.WeatherStrict#IWeatherStrictTools.Tools.generated.verified.cs delete mode 100644 src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.WeatherStrict_Diagnostics.verified.txt delete mode 100644 src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.Weather_Diagnostics.verified.txt delete mode 100755 src/tests/CSharpToJsonSchema.SnapshotTests/TestHelper.cs delete mode 100644 src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/Weather/UnitTests.TypeAsJsonSchema_NonStrict_JsonTypeInfo.verified.txt delete mode 100644 src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/Weather/UnitTests.TypeAsJsonSchema_Strict_JsonTypeInfo.verified.txt delete mode 100644 src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/WordsResponse/UnitTests.TypeAsJsonSchema_NonStrict_JsonTypeInfo.verified.txt delete mode 100644 src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/WordsResponse/UnitTests.TypeAsJsonSchema_Strict_JsonTypeInfo.verified.txt delete mode 100755 src/tests/CSharpToJsonSchema.UnitTests/Tests.AsJsonSchema.cs diff --git a/OpenAI.sln b/OpenAI.sln index d6d2d83e..968679d1 100755 --- a/OpenAI.sln +++ b/OpenAI.sln @@ -42,14 +42,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GenerateDocs", "src\helpers\GenerateDocs\GenerateDocs.csproj", "{ECC219F0-209A-412B-ADEC-6D97AB379E7C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpToJsonSchema", "src\libs\CSharpToJsonSchema\CSharpToJsonSchema.csproj", "{93367DED-6C55-4267-923A-4412D03376FB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpToJsonSchema.Generators", "src\libs\CSharpToJsonSchema.Generators\CSharpToJsonSchema.Generators.csproj", "{4A7B892E-94C7-493D-8B2F-34ED64AE4DCF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpToJsonSchema.SnapshotTests", "src\tests\CSharpToJsonSchema.SnapshotTests\CSharpToJsonSchema.SnapshotTests.csproj", "{8BDEB07E-C8C8-436C-B736-F3C093CB27AD}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpToJsonSchema.UnitTests", "src\tests\CSharpToJsonSchema.UnitTests\CSharpToJsonSchema.UnitTests.csproj", "{8AFCC30C-C59D-498D-BE68-9A328B3E5599}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -76,22 +68,6 @@ Global {ECC219F0-209A-412B-ADEC-6D97AB379E7C}.Debug|Any CPU.Build.0 = Debug|Any CPU {ECC219F0-209A-412B-ADEC-6D97AB379E7C}.Release|Any CPU.ActiveCfg = Release|Any CPU {ECC219F0-209A-412B-ADEC-6D97AB379E7C}.Release|Any CPU.Build.0 = Release|Any CPU - {93367DED-6C55-4267-923A-4412D03376FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {93367DED-6C55-4267-923A-4412D03376FB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {93367DED-6C55-4267-923A-4412D03376FB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {93367DED-6C55-4267-923A-4412D03376FB}.Release|Any CPU.Build.0 = Release|Any CPU - {4A7B892E-94C7-493D-8B2F-34ED64AE4DCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4A7B892E-94C7-493D-8B2F-34ED64AE4DCF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4A7B892E-94C7-493D-8B2F-34ED64AE4DCF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4A7B892E-94C7-493D-8B2F-34ED64AE4DCF}.Release|Any CPU.Build.0 = Release|Any CPU - {8BDEB07E-C8C8-436C-B736-F3C093CB27AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8BDEB07E-C8C8-436C-B736-F3C093CB27AD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8BDEB07E-C8C8-436C-B736-F3C093CB27AD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8BDEB07E-C8C8-436C-B736-F3C093CB27AD}.Release|Any CPU.Build.0 = Release|Any CPU - {8AFCC30C-C59D-498D-BE68-9A328B3E5599}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8AFCC30C-C59D-498D-BE68-9A328B3E5599}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8AFCC30C-C59D-498D-BE68-9A328B3E5599}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8AFCC30C-C59D-498D-BE68-9A328B3E5599}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -103,10 +79,6 @@ Global {A3F06E45-DFA8-4236-BFF5-425091762548} = {AAA11B78-2764-4520-A97E-46AA7089A588} {2D8B78DE-7269-417B-9D0B-8981FA513ACB} = {E793AF18-4371-4EBD-96FC-195EB1798855} {ECC219F0-209A-412B-ADEC-6D97AB379E7C} = {1A008ECD-2300-4BE4-A302-49DDF8BE0D54} - {93367DED-6C55-4267-923A-4412D03376FB} = {61E7E11E-4558-434C-ACE8-06316A3097B3} - {4A7B892E-94C7-493D-8B2F-34ED64AE4DCF} = {61E7E11E-4558-434C-ACE8-06316A3097B3} - {8BDEB07E-C8C8-436C-B736-F3C093CB27AD} = {AAA11B78-2764-4520-A97E-46AA7089A588} - {8AFCC30C-C59D-498D-BE68-9A328B3E5599} = {AAA11B78-2764-4520-A97E-46AA7089A588} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {CED9A020-DBA5-4BE6-8096-75E528648EC1} diff --git a/src/libs/CSharpToJsonSchema.Generators/CSharpToJsonSchema.Generators.csproj b/src/libs/CSharpToJsonSchema.Generators/CSharpToJsonSchema.Generators.csproj deleted file mode 100644 index e1b7614a..00000000 --- a/src/libs/CSharpToJsonSchema.Generators/CSharpToJsonSchema.Generators.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - netstandard2.0 - false - false - true - true - $(NoWarn);CA1014;CA1031;CA1308 - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - \ No newline at end of file diff --git a/src/libs/CSharpToJsonSchema.Generators/Conversion/ToModels.cs b/src/libs/CSharpToJsonSchema.Generators/Conversion/ToModels.cs deleted file mode 100644 index 48040e94..00000000 --- a/src/libs/CSharpToJsonSchema.Generators/Conversion/ToModels.cs +++ /dev/null @@ -1,224 +0,0 @@ -using System.ComponentModel; -using H.Generators; -using Microsoft.CodeAnalysis; - -namespace OpenAI.Generators.Core.Conversion; - -public static class ToModels -{ - public static InterfaceData PrepareData( - this INamedTypeSymbol interfaceSymbol, - AttributeData attributeData) - { - interfaceSymbol = interfaceSymbol ?? throw new ArgumentNullException(nameof(interfaceSymbol)); - attributeData = attributeData ?? throw new ArgumentNullException(nameof(attributeData)); - - var isStrict = attributeData.NamedArguments.FirstOrDefault(x => x.Key == "Strict").Value.Value is bool strict && - strict; - var methods = interfaceSymbol - .GetMembers() - .OfType() - .Where(static x => x.MethodKind == MethodKind.Ordinary) - .Select(x => - { - var parameters = x.Parameters - .Where(static x => x.Type.MetadataName != "CancellationToken") - .ToArray(); - - return new MethodData( - Name: x.Name, - Description: GetDescription(x), - IsAsync: x.IsAsync || x.ReturnType.Name == "Task", - IsVoid: x.ReturnsVoid, - IsStrict: isStrict, - Parameters: new OpenApiSchema( - Name: x.Name, - Description: GetDescription(x), - Type: "object", - SchemaType: "object", - Properties: parameters - .Select(y => ToParameterData( - typeSymbol: y.Type, - name: y.Name, - description: GetDescription(y), - isRequired: isStrict || !y.IsOptional)) - .ToArray(), - EnumValues: Array.Empty(), - IsNullable: false, - IsRequired: true, - Format: null, - ArrayItem: Array.Empty(), - DefaultValue: string.Empty)); - }) - .ToArray(); - - return new InterfaceData( - Namespace: interfaceSymbol.ContainingNamespace.ToDisplayString(), - Name: interfaceSymbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), - Methods: methods); - } - - private static OpenApiSchema ToParameterData(ITypeSymbol typeSymbol, string? name = null, string? description = null, bool isRequired = true) - { - string schemaType; - string? format = null; - var properties = Array.Empty(); - OpenApiSchema? arrayItem = null; - switch (typeSymbol.TypeKind) - { - case TypeKind.Enum: - schemaType = "string"; - break; - - case TypeKind.Structure: - switch (typeSymbol.SpecialType) - { - case SpecialType.System_Int32: - schemaType = "integer"; - format = "int32"; - break; - - case SpecialType.System_Int64: - schemaType = "integer"; - format = "int64"; - break; - - case SpecialType.System_Single: - schemaType = "number"; - format = "double"; - break; - - case SpecialType.System_Double: - schemaType = "number"; - format = "float"; - break; - - case SpecialType.System_DateTime: - schemaType = "string"; - format = "date-time"; - break; - - case SpecialType.System_Boolean: - schemaType = "boolean"; - break; - - case SpecialType.None: - switch (typeSymbol.Name) - { - case "DateOnly": - schemaType = "string"; - format = "date"; - break; - - default: - throw new NotImplementedException($"{typeSymbol.Name} is not implemented."); - } - break; - - default: - throw new NotImplementedException($"{typeSymbol.SpecialType} is not implemented."); - } - break; - - case TypeKind.Class: - switch (typeSymbol.SpecialType) - { - case SpecialType.System_String: - schemaType = "string"; - break; - - - case SpecialType.None: - schemaType = "object"; - properties = typeSymbol.GetMembers() - .OfType() - .Select(static y => ToParameterData( - typeSymbol: y.Type, - name: y.Name, - description: GetDescription(y), - isRequired: true)) - .ToArray(); - break; - - default: - throw new NotImplementedException($"{typeSymbol.SpecialType} is not implemented."); - } - break; - - case TypeKind.Interface when typeSymbol.MetadataName == "IReadOnlyCollection`1": - schemaType = "array"; - arrayItem = (typeSymbol as INamedTypeSymbol)?.TypeArguments - .Select(static y => ToParameterData(y)) - .FirstOrDefault(); - break; - - case TypeKind.Array: - schemaType = "array"; - arrayItem = ToParameterData((typeSymbol as IArrayTypeSymbol)?.ElementType!); - break; - - default: - throw new NotImplementedException($"{typeSymbol.TypeKind} is not implemented."); - } - - return new OpenApiSchema( - Name: !string.IsNullOrWhiteSpace(name) - ? name! - : typeSymbol.Name, - Description: !string.IsNullOrWhiteSpace(description) - ? description! - : GetDescription(typeSymbol), - Type: typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), - DefaultValue: GetDefaultValue(typeSymbol), - SchemaType: schemaType, - Format: format, - Properties: properties, - ArrayItem: arrayItem != null ? [arrayItem.Value] : Array.Empty(), - EnumValues: typeSymbol.TypeKind == TypeKind.Enum - ? typeSymbol - .GetMembers() - .OfType() - .Select(static x => x.Name.ToLowerInvariant()) - .ToArray() - : [], - IsNullable: IsNullable(typeSymbol), - IsRequired: isRequired); - } - - private static bool IsNullable(ITypeSymbol typeSymbol) - { - if (typeSymbol.TypeKind == TypeKind.Enum) - { - return false; - } - if (typeSymbol.TypeKind == TypeKind.Structure) - { - return false; - } - - return typeSymbol.SpecialType switch - { - SpecialType.System_String => false, - _ => true, - }; - } - - private static string GetDefaultValue(ITypeSymbol typeSymbol) - { - switch (typeSymbol.SpecialType) - { - case SpecialType.System_String: - return "string.Empty"; - - default: - return string.Empty; - } - } - - private static string GetDescription(ISymbol symbol) - { - return symbol.GetAttributes() - .FirstOrDefault(static x => x.AttributeClass?.Name == nameof(DescriptionAttribute))? - .ConstructorArguments.First().Value?.ToString() ?? string.Empty; - } -} \ No newline at end of file diff --git a/src/libs/CSharpToJsonSchema.Generators/JsonSchemaGenerator.cs b/src/libs/CSharpToJsonSchema.Generators/JsonSchemaGenerator.cs deleted file mode 100755 index 34bd4a94..00000000 --- a/src/libs/CSharpToJsonSchema.Generators/JsonSchemaGenerator.cs +++ /dev/null @@ -1,60 +0,0 @@ -using H.Generators; -using H.Generators.Extensions; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using OpenAI.Generators.Core.Conversion; - -namespace CSharpToJsonSchema.Generators; - -[Generator] -public class JsonSchemaGenerator : IIncrementalGenerator -{ - #region Constants - - public const string Name = nameof(JsonSchemaGenerator); - public const string Id = "OATG"; - - #endregion - - #region Methods - - public void Initialize(IncrementalGeneratorInitializationContext context) - { - var attributes = - context.SyntaxProvider - .ForAttributeWithMetadataName("CSharpToJsonSchema.GenerateJsonSchemaAttribute") - .SelectManyAllAttributesOfCurrentInterfaceSyntax() - .SelectAndReportExceptions(PrepareData, context, Id); - - attributes - .SelectAndReportExceptions(AsTools, context, Id) - .AddSource(context); - attributes - .SelectAndReportExceptions(AsCalls, context, Id) - .AddSource(context); - } - - private static InterfaceData PrepareData( - (SemanticModel SemanticModel, AttributeData AttributeData, InterfaceDeclarationSyntax InterfaceSyntax, INamedTypeSymbol InterfaceSymbol) tuple) - { - var (_, attributeData, _, interfaceSymbol) = tuple; - - return interfaceSymbol.PrepareData(attributeData); - } - - private static FileWithName AsTools(InterfaceData @interface) - { - return new FileWithName( - Name: $"{@interface.Name}.Tools.generated.cs", - Text: Sources.GenerateClientImplementation(@interface)); - } - - private static FileWithName AsCalls(InterfaceData @interface) - { - return new FileWithName( - Name: $"{@interface.Name}.Calls.generated.cs", - Text: Sources.GenerateCalls(@interface)); - } - - #endregion -} \ No newline at end of file diff --git a/src/libs/CSharpToJsonSchema.Generators/Models/InterfaceData.cs b/src/libs/CSharpToJsonSchema.Generators/Models/InterfaceData.cs deleted file mode 100644 index 2f78ed9d..00000000 --- a/src/libs/CSharpToJsonSchema.Generators/Models/InterfaceData.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace H.Generators; - -public readonly record struct InterfaceData( - string Namespace, - string Name, - IReadOnlyCollection Methods); \ No newline at end of file diff --git a/src/libs/CSharpToJsonSchema.Generators/Models/MethodData.cs b/src/libs/CSharpToJsonSchema.Generators/Models/MethodData.cs deleted file mode 100644 index a5780d71..00000000 --- a/src/libs/CSharpToJsonSchema.Generators/Models/MethodData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using OpenAI.Generators.Core; - -namespace H.Generators; - -public readonly record struct MethodData( - string Name, - string Description, - bool IsAsync, - bool IsVoid, - bool IsStrict, - OpenApiSchema Parameters); \ No newline at end of file diff --git a/src/libs/CSharpToJsonSchema.Generators/Models/OpenApiSchema.cs b/src/libs/CSharpToJsonSchema.Generators/Models/OpenApiSchema.cs deleted file mode 100644 index 5e954477..00000000 --- a/src/libs/CSharpToJsonSchema.Generators/Models/OpenApiSchema.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace OpenAI.Generators.Core; - -public readonly record struct OpenApiSchema( - string Name, - string Description, - string Type, - string SchemaType, - string? Format, - IReadOnlyCollection EnumValues, - IReadOnlyCollection Properties, - IReadOnlyCollection ArrayItem, - bool IsRequired, - bool IsNullable, - string DefaultValue); \ No newline at end of file diff --git a/src/libs/CSharpToJsonSchema.Generators/Sources.Calls.cs b/src/libs/CSharpToJsonSchema.Generators/Sources.Calls.cs deleted file mode 100755 index adc6d016..00000000 --- a/src/libs/CSharpToJsonSchema.Generators/Sources.Calls.cs +++ /dev/null @@ -1,142 +0,0 @@ -using H.Generators; -using H.Generators.Extensions; - -namespace CSharpToJsonSchema.Generators; - -internal static partial class Sources -{ - public static string GenerateCalls(InterfaceData @interface) - { - var extensionsClassName = @interface.Name.Substring(startIndex: 1) + "Extensions"; - - return @$"#nullable enable - -namespace {@interface.Namespace} -{{ - public static partial class {extensionsClassName} - {{ -{@interface.Methods.Select(static method => $@" - public class {method.Name}Args - {{ - {string.Join("\n ", method.Parameters.Properties.Select(static x => $@"public {x.Type}{(x.IsNullable ? "?" : "")} {x.Name.ToPropertyName()} {{ get; set; }}{(!string.IsNullOrEmpty(x.DefaultValue) ? $" = {x.DefaultValue};" : "")}"))} - }} -").Inject()} - - public static global::System.Collections.Generic.IReadOnlyDictionary>> AsCalls(this {@interface.Name} service) - {{ - return new global::System.Collections.Generic.Dictionary>> - {{ -{@interface.Methods.Where(static x => x is { IsAsync: false, IsVoid: false }).Select(method => $@" - [""{method.Name}""] = (json, _) => - {{ - return global::System.Threading.Tasks.Task.FromResult(service.Call{method.Name}(json)); - }}, -").Inject()} -{@interface.Methods.Where(static x => x is { IsAsync: false, IsVoid: true }).Select(method => $@" - [""{method.Name}""] = (json, _) => - {{ - service.Call{method.Name}(json); - - return global::System.Threading.Tasks.Task.FromResult(string.Empty); - }}, -").Inject()} -{@interface.Methods.Where(static x => x is { IsAsync: true, IsVoid: false }).Select(method => $@" - [""{method.Name}""] = async (json, cancellationToken) => - {{ - return await service.Call{method.Name}(json, cancellationToken); - }}, -").Inject()} -{@interface.Methods.Where(static x => x is { IsAsync: true, IsVoid: true }).Select(method => $@" - [""{method.Name}""] = async (json, cancellationToken) => - {{ - await service.Call{method.Name}(json, cancellationToken); - - return string.Empty; - }}, -").Inject()} - }}; - }} - -{@interface.Methods.Select(method => $@" - public static {extensionsClassName}.{method.Name}Args As{method.Name}Args( - this {@interface.Name} functions, - string json) - {{ - return - global::System.Text.Json.JsonSerializer.Deserialize<{extensionsClassName}.{method.Name}Args>(json, new global::System.Text.Json.JsonSerializerOptions - {{ - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = {{{{ new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }}}} - }}) ?? - throw new global::System.InvalidOperationException(""Could not deserialize JSON.""); - }} -").Inject()} - -{@interface.Methods.Where(static x => x is { IsAsync: false, IsVoid: false }).Select(method => $@" - public static string Call{method.Name}(this {@interface.Name} functions, string json) - {{ - var args = functions.As{method.Name}Args(json); - var jsonResult = functions.{method.Name}({string.Join(", ", method.Parameters.Properties.Select(static parameter => $@"args.{parameter.Name.ToPropertyName()}"))}); - - return global::System.Text.Json.JsonSerializer.Serialize(jsonResult, new global::System.Text.Json.JsonSerializerOptions - {{ - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = {{ new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }}, - }}); - }} -").Inject()} - -{@interface.Methods.Where(static x => x is { IsAsync: false, IsVoid: true }).Select(method => $@" - public static void Call{method.Name}(this {@interface.Name} functions, string json) - {{ - var args = functions.As{method.Name}Args(json); - functions.{method.Name}({string.Join(", ", method.Parameters.Properties.Select(static parameter => $@"args.{parameter.Name.ToPropertyName()}"))}); - }} -").Inject()} - -{@interface.Methods.Where(static x => x is { IsAsync: true, IsVoid: false }).Select(method => $@" - public static async global::System.Threading.Tasks.Task Call{method.Name}( - this {@interface.Name} functions, - string json, - global::System.Threading.CancellationToken cancellationToken = default) - {{ - var args = functions.As{method.Name}Args(json); - var jsonResult = await functions.{method.Name}({string.Join(", ", method.Parameters.Properties - .Select(static parameter => $@"args.{parameter.Name.ToPropertyName()}").Append("cancellationToken"))}); - - return global::System.Text.Json.JsonSerializer.Serialize(jsonResult, new global::System.Text.Json.JsonSerializerOptions - {{ - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = {{ new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }}, - }}); - }} -").Inject()} - -{@interface.Methods.Where(static x => x is { IsAsync: true, IsVoid: true }).Select(method => $@" - public static async global::System.Threading.Tasks.Task Call{method.Name}( - this {@interface.Name} functions, - string json, - global::System.Threading.CancellationToken cancellationToken = default) - {{ - var args = functions.As{method.Name}Args(json); - await functions.{method.Name}({string.Join(", ", method.Parameters.Properties.Select(static parameter => $@"args.{parameter.Name.ToPropertyName()}"))}, cancellationToken); - - return string.Empty; - }} -").Inject()} - - public static async global::System.Threading.Tasks.Task CallAsync( - this {@interface.Name} service, - string functionName, - string argumentsAsJson, - global::System.Threading.CancellationToken cancellationToken = default) - {{ - var calls = service.AsCalls(); - var func = calls[functionName]; - - return await func(argumentsAsJson, cancellationToken); - }} - }} -}}"; - } -} diff --git a/src/libs/CSharpToJsonSchema.Generators/Sources.Tools.cs b/src/libs/CSharpToJsonSchema.Generators/Sources.Tools.cs deleted file mode 100755 index 75645801..00000000 --- a/src/libs/CSharpToJsonSchema.Generators/Sources.Tools.cs +++ /dev/null @@ -1,92 +0,0 @@ -using H.Generators; -using H.Generators.Extensions; -using OpenAI.Generators.Core; - -namespace CSharpToJsonSchema.Generators; - -internal static partial class Sources -{ - /// - /// https://swagger.io/docs/specification/data-models/data-types/ - /// - /// - /// - /// - /// - public static string GenerateOpenApiSchema(OpenApiSchema parameter, int depth = 0, bool schema = true) - { - var indent = new string(' ', depth * 4); - const string name = "global::CSharpToJsonSchema.OpenApiSchema"; - if (parameter.ArrayItem.Count != 0) - { - return $@"new {name} -{indent} {{ -{indent} Type = ""{parameter.SchemaType}"", -{indent} Description = ""{parameter.Description}"", -{indent} Items = {GenerateOpenApiSchema(parameter.ArrayItem.First(), depth: depth + 1)}, -{indent} }}"; - } - if (parameter.SchemaType == "object") - { - return $@"new {name} -{indent} {{ -{indent} Type = ""{parameter.SchemaType}"", -{indent} Description = ""{parameter.Description}"", -{indent} Properties = new global::System.Collections.Generic.Dictionary -{indent} {{ -{indent} {string.Join(",\n " + indent, parameter.Properties.Select(x => $@"[""{x.Name}""] = " + GenerateOpenApiSchema(x, depth: depth + 2)))} -{indent} }}, -{indent} Required = new string[] {{ {string.Join(", ", parameter.Properties - .Where(static x => x.IsRequired) - .Select(static x => $"\"{x.Name}\""))} }}, -{indent} }}"; - } - - if (parameter.EnumValues.Count != 0) - { - return $@"new {name} -{indent} {{ -{indent} Type = ""{parameter.SchemaType}"", -{indent} Description = ""{parameter.Description}"", -{indent} Enum = new string[] {{ {string.Join(", ", parameter.EnumValues.Select(static x => $"\"{x}\""))} }}, -{indent} }}"; - } - - return $@"new {name} -{indent} {{ -{indent} Type = ""{parameter.SchemaType}"",{(parameter.Format != null ? $@" -{indent} Format = ""{parameter.Format}""," : "")} -{indent} Description = ""{parameter.Description}"", -{indent} }}"; - } - - public static string GenerateClientImplementation(InterfaceData @interface) - { - var extensionsClassName = @interface.Name.Substring(startIndex: 1) + "Extensions"; - - return @$" -#nullable enable - -namespace {@interface.Namespace} -{{ - public static partial class {extensionsClassName} - {{ - public static global::System.Collections.Generic.IList AsTools(this {@interface.Name} functions) - {{ - return new global::System.Collections.Generic.List - {{ -{@interface.Methods.Select(method => $@" - new global::CSharpToJsonSchema.Tool - {{ - Name = ""{method.Name}"", - Description = ""{method.Description}"", - Strict = {(method.IsStrict ? "true" : "false")}, - Parameters = {GenerateOpenApiSchema(method.Parameters, schema: false)}, - }}, -").Inject()} - }}; - }} - }} -}}"; - } -} diff --git a/src/libs/CSharpToJsonSchema.Generators/Steps.cs b/src/libs/CSharpToJsonSchema.Generators/Steps.cs deleted file mode 100644 index f3e084f9..00000000 --- a/src/libs/CSharpToJsonSchema.Generators/Steps.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace CSharpToJsonSchema.Generators; - -public static class CommonSteps -{ - public static IncrementalValuesProvider - ForAttributeWithMetadataName( - this SyntaxValueProvider source, - string fullyQualifiedMetadataName) - { - return source - .ForAttributeWithMetadataName( - fullyQualifiedMetadataName: fullyQualifiedMetadataName, - predicate: static (node, _) => - node is InterfaceDeclarationSyntax { AttributeLists.Count: > 0 }, - transform: static (context, _) => context); - } - - public static IncrementalValuesProvider<(SemanticModel SemanticModel, AttributeData AttributeData, InterfaceDeclarationSyntax InterfaceSyntax, INamedTypeSymbol InterfaceSymbol)> - SelectManyAllAttributesOfCurrentInterfaceSyntax( - this IncrementalValuesProvider source) - { - return source - .SelectMany(static (context, _) => context.Attributes - .Select(x => ( - context.SemanticModel, - AttributeData: x, - ClassSyntax: (InterfaceDeclarationSyntax)context.TargetNode, - ClassSymbol: (INamedTypeSymbol)context.TargetSymbol))); - } -} diff --git a/src/libs/CSharpToJsonSchema/CSharpToJsonSchema.csproj b/src/libs/CSharpToJsonSchema/CSharpToJsonSchema.csproj deleted file mode 100644 index bf754361..00000000 --- a/src/libs/CSharpToJsonSchema/CSharpToJsonSchema.csproj +++ /dev/null @@ -1,43 +0,0 @@ - - - - netstandard2.0;net4.6.2;net6.0;net8.0 - $(NoWarn);CA1724;CA2227;CA1819 - - - - - - - - - Generated C# SDK based on official OpenAI OpenAPI specification. - Includes C# Source Generator which allows you to define functions natively through a C# interface, and also provides extensions that make it easier to call this interface later - api;client;sdk;dotnet;swagger;openapi;specification;openai;generated;nswag;functions;gpt-3.5;gpt-4;chatgpt;generator;source generator;constants;prices;pricing;vision;audio;embedding;moderation;image;chat - - - - - - - - - - - - - - - <_Parameter1>true - - - - - true - true - true - false - false - - - diff --git a/src/libs/CSharpToJsonSchema/GenerateJsonSchemaAttribute.cs b/src/libs/CSharpToJsonSchema/GenerateJsonSchemaAttribute.cs deleted file mode 100644 index 3d9502f1..00000000 --- a/src/libs/CSharpToJsonSchema/GenerateJsonSchemaAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable once CheckNamespace -namespace CSharpToJsonSchema; - -/// -/// -/// -[AttributeUsage(AttributeTargets.Interface)] -[System.Diagnostics.Conditional("GENERATE_JSON_SCHEMA_ATTRIBUTES")] -public sealed class GenerateJsonSchemaAttribute : Attribute -{ - /// - /// - /// - public bool Strict { get; set; } -} \ No newline at end of file diff --git a/src/libs/CSharpToJsonSchema/OpenApiSchema.cs b/src/libs/CSharpToJsonSchema/OpenApiSchema.cs deleted file mode 100644 index a249ba9f..00000000 --- a/src/libs/CSharpToJsonSchema/OpenApiSchema.cs +++ /dev/null @@ -1,56 +0,0 @@ -// ReSharper disable once CheckNamespace -namespace CSharpToJsonSchema; - -/// -/// -/// -public class OpenApiSchema -{ - /// - /// - /// - [global::System.Text.Json.Serialization.JsonPropertyName("type")] - public string Type { get; set; } = string.Empty; - - /// - /// - /// - [global::System.Text.Json.Serialization.JsonPropertyName("format")] - public string? Format { get; set; } - - /// - /// - /// - [global::System.Text.Json.Serialization.JsonPropertyName("description")] - public string? Description { get; set; } - - /// - /// - /// - [global::System.Text.Json.Serialization.JsonPropertyName("enum")] - public IReadOnlyList? Enum { get; set; } - - /// - /// - /// - [global::System.Text.Json.Serialization.JsonPropertyName("required")] - public IReadOnlyList? Required { get; set; } - - /// - /// - /// - [global::System.Text.Json.Serialization.JsonPropertyName("properties")] - public IReadOnlyDictionary? Properties { get; set; } - - /// - /// - /// - [global::System.Text.Json.Serialization.JsonPropertyName("items")] - public OpenApiSchema? Items { get; set; } - - /// - /// - /// - [global::System.Text.Json.Serialization.JsonPropertyName("additionalProperties")] - public bool AdditionalProperties2 { get; set; } -} \ No newline at end of file diff --git a/src/libs/CSharpToJsonSchema/Tool.cs b/src/libs/CSharpToJsonSchema/Tool.cs deleted file mode 100644 index 6ce3fd15..00000000 --- a/src/libs/CSharpToJsonSchema/Tool.cs +++ /dev/null @@ -1,42 +0,0 @@ -#nullable enable - -namespace CSharpToJsonSchema; - -/// -/// -/// -public sealed partial class Tool -{ - /// - /// The name of the function to be called. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64. - /// - [global::System.Text.Json.Serialization.JsonPropertyName("name")] - [global::System.Text.Json.Serialization.JsonRequired] - public string? Name { get; set; } - - /// - /// A description of what the function does, used by the model to choose when and how to call the function. - /// - [global::System.Text.Json.Serialization.JsonPropertyName("description")] - public string? Description { get; set; } - - /// - /// The parameters the functions accepts, described as a JSON Schema object. See the [guide](/docs/guides/function-calling) for examples, and the [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for documentation about the format.
- /// Omitting `parameters` defines a function with an empty parameter list. - ///
- [global::System.Text.Json.Serialization.JsonPropertyName("parameters")] - public object? Parameters { get; set; } - - /// - /// Whether to enable strict schema adherence when generating the function call. If set to true, the model will follow the exact schema defined in the `parameters` field. Only a subset of JSON Schema is supported when `strict` is `true`. Learn more about Structured Outputs in the [function calling guide](docs/guides/function-calling).
- /// Default Value: false - ///
- [global::System.Text.Json.Serialization.JsonPropertyName("strict")] - public bool? Strict { get; set; } = false; - - /// - /// Additional properties that are not explicitly defined in the schema - /// - [global::System.Text.Json.Serialization.JsonExtensionData] - public global::System.Collections.Generic.IDictionary AdditionalProperties { get; set; } = new global::System.Collections.Generic.Dictionary(); -} \ No newline at end of file diff --git a/src/libs/CSharpToJsonSchema/TypeToSchemaHelpers.cs b/src/libs/CSharpToJsonSchema/TypeToSchemaHelpers.cs deleted file mode 100644 index 7829c495..00000000 --- a/src/libs/CSharpToJsonSchema/TypeToSchemaHelpers.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Schema; -using System.Text.Json.Serialization.Metadata; - -namespace CSharpToJsonSchema; - -/// -/// -/// -public static class TypeToSchemaHelpers -{ - /// - /// - /// - /// - /// - /// - /// - /// - public static OpenApiSchema AsJsonSchema( - JsonTypeInfo typeInfo, - bool strict) - { - typeInfo = typeInfo ?? throw new ArgumentNullException(nameof(typeInfo)); - var resolver = typeInfo.OriginatingResolver ?? throw new InvalidOperationException("OriginatingResolver is required."); - - var node = typeInfo.GetJsonSchemaAsNode(exporterOptions: new JsonSchemaExporterOptions - { - TransformSchemaNode = (context, node) => node, - TreatNullObliviousAsNonNullable = true, - }); -#pragma warning disable IL2026 - return AsJsonSchema(typeInfo.Type, strict, resolver, typeInfo.Options); -#pragma warning restore IL2026 - } - - /// - /// - /// - /// - /// - /// - /// - /// -#if NET6_0_OR_GREATER - [RequiresUnreferencedCode("This method uses reflection to generate a JSON schema. Use overload with IJsonTypeInfoResolver parameter to avoid this")] -#endif - public static OpenApiSchema AsJsonSchema( - Type type, - bool strict, - IJsonTypeInfoResolver? jsonTypeInfoResolver = null, - JsonSerializerOptions? options = null) - { - type = type ?? throw new ArgumentNullException(nameof(type)); - - var node = new JsonSerializerOptions - { - TypeInfoResolver = jsonTypeInfoResolver ?? new DefaultJsonTypeInfoResolver(), - }.GetJsonSchemaAsNode(type, exporterOptions: new JsonSchemaExporterOptions - { - TransformSchemaNode = (context, node) => node, - TreatNullObliviousAsNonNullable = true, - }); - - var schema = Create(type, strict); - if (schema.Type == "object") - { - var properties = new Dictionary(); - if (jsonTypeInfoResolver is not null) - { - var jsonTypeInfo = jsonTypeInfoResolver.GetTypeInfo( - type, - options ?? throw new InvalidOperationException("options is required.")) ?? - throw new InvalidOperationException($"JsonTypeInfo for {type.FullName} is not found."); - - foreach (var property in jsonTypeInfo.Properties) - { - properties.Add(property.Name, AsJsonSchema(property.PropertyType, strict, jsonTypeInfoResolver, options)); - } - } - else - { - foreach (var property in type.GetProperties()) - { - properties.Add(property.Name, AsJsonSchema(property.PropertyType, strict)); - } - } - schema.Properties = properties; - schema.Required = properties.Keys.ToArray(); - } - else if (schema.Type == "array") - { - schema.Items = AsJsonSchema( - type.GetElementType() ?? throw new InvalidOperationException("Array type must have an element type."), - strict: strict, - jsonTypeInfoResolver, - options); - } - - return schema; - } - - /// - /// - /// - /// - /// - /// - public static (string Type, string? Format) ToOpenApiTypeAndFormat(Type type) - { - type = type ?? throw new ArgumentNullException(nameof(type)); - - if (type.FullName == "System.String") - { - return ("string", null); - } - if (type.FullName == "System.Int64") - { - return ("integer", "int64"); - } - if (type.FullName == "System.Int32") - { - return ("integer", "int32"); - } - if (type.FullName == "System.Single") - { - return ("number", "float"); - } - if (type.FullName == "System.Double") - { - return ("number", "double"); - } - if (type.FullName == "System.DateTime") - { - return ("string", "date-time"); - } - if (type.FullName == "System.Boolean") - { - return ("boolean", null); - } - if (type.IsEnum) - { - return ("string", null); - } - if (type.IsArray) - { - return ("array", null); - } - - return ("object", null); - } - - - private static OpenApiSchema Create(Type type, bool strict) - { - var (schemaType, format) = ToOpenApiTypeAndFormat(type); - var schema = new OpenApiSchema - { - Type = schemaType, - Format = strict ? null : format, - }; - if (type.IsEnum) - { - schema.Enum = type.GetEnumNames(); - } - - return schema; - } -} \ No newline at end of file diff --git a/src/libs/Directory.Build.props b/src/libs/Directory.Build.props index b12af925..53913650 100644 --- a/src/libs/Directory.Build.props +++ b/src/libs/Directory.Build.props @@ -8,6 +8,12 @@ true $(MSBuildThisFileDirectory)../key.snk + + + + <_Parameter1>true + + true @@ -48,4 +54,12 @@ All + + true + true + true + false + false + + diff --git a/src/libs/OpenAI/AssistantClient.CreateRun.AsStream.cs b/src/libs/OpenAI/AssistantClient.CreateRun.AsStream.cs index c3539254..fb63046e 100644 --- a/src/libs/OpenAI/AssistantClient.CreateRun.AsStream.cs +++ b/src/libs/OpenAI/AssistantClient.CreateRun.AsStream.cs @@ -26,22 +26,22 @@ public partial class AssistantsClient request.Stream = true; PrepareArguments( - client: _httpClient); + client: HttpClient); PrepareCreateRunArguments( - httpClient: _httpClient, + httpClient: HttpClient, threadId: ref threadId, include: include, request: request); var __pathBuilder = new PathBuilder( path: $"/threads/{threadId}/runs", - baseUri: _httpClient.BaseAddress); + baseUri: HttpClient.BaseAddress); var __path = __pathBuilder.ToString(); using var httpRequest = new global::System.Net.Http.HttpRequestMessage( method: global::System.Net.Http.HttpMethod.Post, requestUri: new global::System.Uri(__path, global::System.UriKind.RelativeOrAbsolute)); - foreach (var _authorization in _authorizations) + foreach (var _authorization in Authorizations) { if (_authorization.Type == "Http" || _authorization.Type == "OAuth2") @@ -64,25 +64,25 @@ public partial class AssistantsClient httpRequest.Content = __httpRequestContent; PrepareRequest( - client: _httpClient, + client: HttpClient, request: httpRequest); PrepareCreateRunRequest( - httpClient: _httpClient, + httpClient: HttpClient, httpRequestMessage: httpRequest, threadId: threadId, include: include, request: request); - using var response = await _httpClient.SendAsync( + using var response = await HttpClient.SendAsync( request: httpRequest, completionOption: global::System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken: cancellationToken).ConfigureAwait(false); ProcessResponse( - client: _httpClient, + client: HttpClient, response: response); ProcessCreateRunResponse( - httpClient: _httpClient, + httpClient: HttpClient, httpResponseMessage: response); response.EnsureSuccessStatusCode(); @@ -184,7 +184,7 @@ public partial class AssistantsClient string? instructions = default, string? additionalInstructions = default, global::System.Collections.Generic.IList? additionalMessages = default, - global::System.Collections.Generic.IList>? tools = default, + global::System.Collections.Generic.IList? tools = default, global::OpenAI.CreateRunRequestMetadata? metadata = default, double? temperature = 1, double? topP = 1, diff --git a/src/libs/OpenAI/ChatClient.CreateChatCompletion.AsStream.cs b/src/libs/OpenAI/ChatClient.CreateChatCompletion.AsStream.cs index bca6ac64..6f496e80 100644 --- a/src/libs/OpenAI/ChatClient.CreateChatCompletion.AsStream.cs +++ b/src/libs/OpenAI/ChatClient.CreateChatCompletion.AsStream.cs @@ -21,20 +21,20 @@ public partial class ChatClient request.Stream = true; PrepareArguments( - client: _httpClient); + client: HttpClient); PrepareCreateChatCompletionArguments( - httpClient: _httpClient, + httpClient: HttpClient, request: request); var __pathBuilder = new PathBuilder( path: "/chat/completions", - baseUri: _httpClient.BaseAddress); + baseUri: HttpClient.BaseAddress); var __path = __pathBuilder.ToString(); using var httpRequest = new global::System.Net.Http.HttpRequestMessage( method: global::System.Net.Http.HttpMethod.Post, requestUri: new global::System.Uri(__path, global::System.UriKind.RelativeOrAbsolute)); - foreach (var _authorization in _authorizations) + foreach (var _authorization in Authorizations) { if (_authorization.Type == "Http" || _authorization.Type == "OAuth2") @@ -57,23 +57,23 @@ public partial class ChatClient httpRequest.Content = __httpRequestContent; PrepareRequest( - client: _httpClient, + client: HttpClient, request: httpRequest); PrepareCreateChatCompletionRequest( - httpClient: _httpClient, + httpClient: HttpClient, httpRequestMessage: httpRequest, request: request); - using var response = await _httpClient.SendAsync( + using var response = await HttpClient.SendAsync( request: httpRequest, completionOption: global::System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken: cancellationToken).ConfigureAwait(false); ProcessResponse( - client: _httpClient, + client: HttpClient, response: response); ProcessCreateChatCompletionResponse( - httpClient: _httpClient, + httpClient: HttpClient, httpResponseMessage: response); response.EnsureSuccessStatusCode(); @@ -210,7 +210,7 @@ public partial class ChatClient int? maxCompletionTokens = default, int? n = 1, double? presencePenalty = 0, - global::OpenAI.OneOf? responseFormat = default, + global::OpenAI.ResponseFormat? responseFormat = default, int? seed = default, global::OpenAI.CreateChatCompletionRequestServiceTier? serviceTier = default, global::OpenAI.OneOf>? stop = default, diff --git a/src/libs/OpenAI/Conversions/ChatCompletionRequestMessage.cs b/src/libs/OpenAI/Conversions/ChatCompletionRequestMessage.cs index 0889499e..50190960 100644 --- a/src/libs/OpenAI/Conversions/ChatCompletionRequestMessage.cs +++ b/src/libs/OpenAI/Conversions/ChatCompletionRequestMessage.cs @@ -52,4 +52,35 @@ public static ChatCompletionRequestMessage FromUri(Uri uri) }, }; } + + /// + /// + /// + /// + /// + /// + /// + /// + public static ChatCompletionRequestMessage FromDataUri( + byte[] bytes, + string mimeType, + ChatCompletionRequestMessageContentPartImageImageUrlDetail detail = ChatCompletionRequestMessageContentPartImageImageUrlDetail.Auto) + { + bytes = bytes ?? throw new ArgumentNullException(nameof(bytes)); + + return new ChatCompletionRequestUserMessage + { + Content = new ChatCompletionRequestUserMessageContentPart[] { + new ChatCompletionRequestMessageContentPartImage + { + ImageUrl = new ChatCompletionRequestMessageContentPartImageImageUrl + { + Url = bytes.AsDataUrl(mimeType), + Detail = detail, + }, + Type = ChatCompletionRequestMessageContentPartImageType.ImageUrl, + }, + }, + }; + } } \ No newline at end of file diff --git a/src/libs/OpenAI/Conversions/CreateMessageRequest.cs b/src/libs/OpenAI/Conversions/CreateMessageRequest.cs index 753fba39..b58135d5 100644 --- a/src/libs/OpenAI/Conversions/CreateMessageRequest.cs +++ b/src/libs/OpenAI/Conversions/CreateMessageRequest.cs @@ -49,8 +49,7 @@ public static CreateMessageRequest FromOpenAIFile( return new CreateMessageRequest { Role = role, - Content = new List> + Content = new List { MessageContentImageFileObject.FromOpenAIFile(file, detail), }, @@ -91,8 +90,7 @@ public static CreateMessageRequest FromUri( return new CreateMessageRequest { Role = role, - Content = new List> + Content = new List { MessageContentImageUrlObject.FromUri(uri, detail), }, diff --git a/src/libs/OpenAI/Extensions/StringExtensions.cs b/src/libs/OpenAI/Extensions/StringExtensions.cs index b8da29e5..c0744a21 100755 --- a/src/libs/OpenAI/Extensions/StringExtensions.cs +++ b/src/libs/OpenAI/Extensions/StringExtensions.cs @@ -114,32 +114,23 @@ public static string AsDataUrl(this byte[] bytes, string mimeType) return $"data:{mimeType};base64,{Convert.ToBase64String(bytes)}"; } - + /// /// /// /// /// + /// /// /// - public static ChatCompletionRequestMessage AsUserMessage(this byte[] bytes, string mimeType) + public static ChatCompletionRequestMessage AsUserMessage( + this byte[] bytes, + string mimeType, + ChatCompletionRequestMessageContentPartImageImageUrlDetail detail = ChatCompletionRequestMessageContentPartImageImageUrlDetail.Auto) { bytes = bytes ?? throw new ArgumentNullException(nameof(bytes)); - return new ChatCompletionRequestUserMessage - { - Content = new ChatCompletionRequestUserMessageContentPart[] { - new ChatCompletionRequestMessageContentPartImage - { - ImageUrl = new ChatCompletionRequestMessageContentPartImageImageUrl - { - Url = bytes.AsDataUrl(mimeType), - Detail = ChatCompletionRequestMessageContentPartImageImageUrlDetail.Auto, - }, - Type = ChatCompletionRequestMessageContentPartImageType.ImageUrl, - }, - }, - }; + return ChatCompletionRequestMessage.FromDataUri(bytes, mimeType, detail); } /// diff --git a/src/libs/OpenAI/JsonSerializerContextTypes.AdditionalTypes.cs b/src/libs/OpenAI/JsonSerializerContextTypes.AdditionalTypes.cs index 29b28df1..9f14a3ad 100644 --- a/src/libs/OpenAI/JsonSerializerContextTypes.AdditionalTypes.cs +++ b/src/libs/OpenAI/JsonSerializerContextTypes.AdditionalTypes.cs @@ -16,4 +16,9 @@ public sealed partial class JsonSerializerContextTypes /// /// public CSharpToJsonSchema.OpenApiSchema? OpenApiSchema { get; set; } + + /// + /// + /// + public JsonElement? JsonElement { get; set; } } \ No newline at end of file diff --git a/src/libs/OpenAI/OpenAI.csproj b/src/libs/OpenAI/OpenAI.csproj index 01570bb7..040daaae 100644 --- a/src/libs/OpenAI/OpenAI.csproj +++ b/src/libs/OpenAI/OpenAI.csproj @@ -1,7 +1,7 @@ - netstandard2.0;net4.6.2;net6.0;net8.0 + netstandard2.0;net4.6.2;net8.0 $(NoWarn);CA1724;CA2227;CA1819;CA1822 @@ -18,37 +18,17 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - - - - - - - - <_Parameter1>true - - - - - true - true - true - false - false - - diff --git a/src/libs/OpenAI/OpenAiApi.Headers.cs b/src/libs/OpenAI/OpenAiApi.Headers.cs index 7ec8a9c2..bbffc9ff 100644 --- a/src/libs/OpenAI/OpenAiApi.Headers.cs +++ b/src/libs/OpenAI/OpenAiApi.Headers.cs @@ -6,6 +6,6 @@ public partial class OpenAiApi { partial void Initialized(HttpClient client) { - _httpClient.DefaultRequestHeaders.Add("OpenAI-Beta", "assistants=v2"); + client.DefaultRequestHeaders.Add("OpenAI-Beta", "assistants=v2"); } } \ No newline at end of file diff --git a/src/libs/OpenAI/Tools/FunctionParameters.Extended.cs b/src/libs/OpenAI/Tools/FunctionParameters.Extended.cs deleted file mode 100644 index 5322912b..00000000 --- a/src/libs/OpenAI/Tools/FunctionParameters.Extended.cs +++ /dev/null @@ -1,6 +0,0 @@ -using CSharpToJsonSchema; - -// ReSharper disable once CheckNamespace -namespace OpenAI; - -public partial class FunctionParameters : OpenApiSchema; \ No newline at end of file diff --git a/src/libs/OpenAI/Tools/ResponseFormatJsonSchemaSchema.Extended.cs b/src/libs/OpenAI/Tools/ResponseFormatJsonSchemaSchema.Extended.cs deleted file mode 100644 index 8ccbb9b8..00000000 --- a/src/libs/OpenAI/Tools/ResponseFormatJsonSchemaSchema.Extended.cs +++ /dev/null @@ -1,7 +0,0 @@ -// ReSharper disable once CheckNamespace - -using CSharpToJsonSchema; - -namespace OpenAI; - -public partial class ResponseFormatJsonSchemaSchema : OpenApiSchema; \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.SnapshotTests/ModuleInitializer.cs b/src/tests/CSharpToJsonSchema.SnapshotTests/ModuleInitializer.cs deleted file mode 100755 index 8901978e..00000000 --- a/src/tests/CSharpToJsonSchema.SnapshotTests/ModuleInitializer.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Runtime.CompilerServices; -using VerifyTests; - -namespace OpenAI.SnapshotTests; - -public static class ModuleInitializer -{ - [ModuleInitializer] - public static void Initialize() - { - VerifySourceGenerators.Initialize(); - } -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.SnapshotTests/SnapshotTests.cs b/src/tests/CSharpToJsonSchema.SnapshotTests/SnapshotTests.cs deleted file mode 100755 index 91e77ebf..00000000 --- a/src/tests/CSharpToJsonSchema.SnapshotTests/SnapshotTests.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace OpenAI.SnapshotTests; - -[TestClass] -public class ToolTests : VerifyBase -{ - [TestMethod] - public Task Weather() - { - return this.CheckSourceAsync(H.Resources.WeatherTools_cs.AsString()); - } - - [TestMethod] - public Task WeatherStrict() - { - return this.CheckSourceAsync(H.Resources.WeatherStrictTools_cs.AsString()); - } - - [TestMethod] - public Task VariousTypes() - { - return this.CheckSourceAsync(H.Resources.VariousTypesTools_cs.AsString()); - } -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.VariousTypes#IVariousTypesTools.Calls.generated.verified.cs b/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.VariousTypes#IVariousTypesTools.Calls.generated.verified.cs deleted file mode 100644 index a6ffc71a..00000000 --- a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.VariousTypes#IVariousTypesTools.Calls.generated.verified.cs +++ /dev/null @@ -1,76 +0,0 @@ -//HintName: IVariousTypesTools.Calls.generated.cs -#nullable enable - -namespace OpenAI.IntegrationTests -{ - public static partial class VariousTypesToolsExtensions - { - public class GetCurrentWeatherArgs - { - public long Parameter1 { get; set; } - public int Parameter2 { get; set; } - public double Parameter3 { get; set; } - public float Parameter4 { get; set; } - public bool Parameter5 { get; set; } - public global::System.DateTime DateTime { get; set; } - public global::System.DateOnly Date { get; set; } - } - - public static global::System.Collections.Generic.IReadOnlyDictionary>> AsCalls(this IVariousTypesTools service) - { - return new global::System.Collections.Generic.Dictionary>> - { - ["GetCurrentWeather"] = (json, _) => - { - return global::System.Threading.Tasks.Task.FromResult(service.CallGetCurrentWeather(json)); - }, - - - - }; - } - - public static VariousTypesToolsExtensions.GetCurrentWeatherArgs AsGetCurrentWeatherArgs( - this IVariousTypesTools functions, - string json) - { - return - global::System.Text.Json.JsonSerializer.Deserialize(json, new global::System.Text.Json.JsonSerializerOptions - { - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = {{ new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }} - }) ?? - throw new global::System.InvalidOperationException("Could not deserialize JSON."); - } - - public static string CallGetCurrentWeather(this IVariousTypesTools functions, string json) - { - var args = functions.AsGetCurrentWeatherArgs(json); - var jsonResult = functions.GetCurrentWeather(args.Parameter1, args.Parameter2, args.Parameter3, args.Parameter4, args.Parameter5, args.DateTime, args.Date); - - return global::System.Text.Json.JsonSerializer.Serialize(jsonResult, new global::System.Text.Json.JsonSerializerOptions - { - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = { new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }, - }); - } - - - - - - - - public static async global::System.Threading.Tasks.Task CallAsync( - this IVariousTypesTools service, - string functionName, - string argumentsAsJson, - global::System.Threading.CancellationToken cancellationToken = default) - { - var calls = service.AsCalls(); - var func = calls[functionName]; - - return await func(argumentsAsJson, cancellationToken); - } - } -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.VariousTypes#IVariousTypesTools.Tools.generated.verified.cs b/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.VariousTypes#IVariousTypesTools.Tools.generated.verified.cs deleted file mode 100644 index 74caa3be..00000000 --- a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.VariousTypes#IVariousTypesTools.Tools.generated.verified.cs +++ /dev/null @@ -1,72 +0,0 @@ -//HintName: IVariousTypesTools.Tools.generated.cs - -#nullable enable - -namespace OpenAI.IntegrationTests -{ - public static partial class VariousTypesToolsExtensions - { - public static global::System.Collections.Generic.IList AsTools(this IVariousTypesTools functions) - { - return new global::System.Collections.Generic.List - { - new global::CSharpToJsonSchema.Tool - { - Name = "GetCurrentWeather", - Description = "Get the current weather in a given location", - Strict = false, - Parameters = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "object", - Description = "Get the current weather in a given location", - Properties = new global::System.Collections.Generic.Dictionary - { - ["parameter1"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "integer", - Format = "int64", - Description = "", - }, - ["parameter2"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "integer", - Format = "int32", - Description = "", - }, - ["parameter3"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "number", - Format = "float", - Description = "", - }, - ["parameter4"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "number", - Format = "double", - Description = "", - }, - ["parameter5"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "boolean", - Description = "", - }, - ["dateTime"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "string", - Format = "date-time", - Description = "", - }, - ["date"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "string", - Format = "date", - Description = "", - } - }, - Required = new string[] { "parameter1", "parameter2", "parameter3", "parameter4", "parameter5", "dateTime", "date" }, - }, - }, - }; - } - } -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.VariousTypes_Diagnostics.verified.txt b/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.VariousTypes_Diagnostics.verified.txt deleted file mode 100644 index ad47dbb9..00000000 --- a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.VariousTypes_Diagnostics.verified.txt +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.Weather#IWeatherTools.Calls.generated.verified.cs b/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.Weather#IWeatherTools.Calls.generated.verified.cs deleted file mode 100644 index 99311bcd..00000000 --- a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.Weather#IWeatherTools.Calls.generated.verified.cs +++ /dev/null @@ -1,106 +0,0 @@ -//HintName: IWeatherTools.Calls.generated.cs -#nullable enable - -namespace OpenAI.IntegrationTests -{ - public static partial class WeatherToolsExtensions - { - public class GetCurrentWeatherArgs - { - public string Location { get; set; } = string.Empty; - public global::OpenAI.IntegrationTests.Unit Unit { get; set; } - } - - public class GetCurrentWeatherAsyncArgs - { - public string Location { get; set; } = string.Empty; - public global::OpenAI.IntegrationTests.Unit Unit { get; set; } - } - - public static global::System.Collections.Generic.IReadOnlyDictionary>> AsCalls(this IWeatherTools service) - { - return new global::System.Collections.Generic.Dictionary>> - { - ["GetCurrentWeather"] = (json, _) => - { - return global::System.Threading.Tasks.Task.FromResult(service.CallGetCurrentWeather(json)); - }, - - ["GetCurrentWeatherAsync"] = async (json, cancellationToken) => - { - return await service.CallGetCurrentWeatherAsync(json, cancellationToken); - }, - - }; - } - - public static WeatherToolsExtensions.GetCurrentWeatherArgs AsGetCurrentWeatherArgs( - this IWeatherTools functions, - string json) - { - return - global::System.Text.Json.JsonSerializer.Deserialize(json, new global::System.Text.Json.JsonSerializerOptions - { - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = {{ new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }} - }) ?? - throw new global::System.InvalidOperationException("Could not deserialize JSON."); - } - - public static WeatherToolsExtensions.GetCurrentWeatherAsyncArgs AsGetCurrentWeatherAsyncArgs( - this IWeatherTools functions, - string json) - { - return - global::System.Text.Json.JsonSerializer.Deserialize(json, new global::System.Text.Json.JsonSerializerOptions - { - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = {{ new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }} - }) ?? - throw new global::System.InvalidOperationException("Could not deserialize JSON."); - } - - public static string CallGetCurrentWeather(this IWeatherTools functions, string json) - { - var args = functions.AsGetCurrentWeatherArgs(json); - var jsonResult = functions.GetCurrentWeather(args.Location, args.Unit); - - return global::System.Text.Json.JsonSerializer.Serialize(jsonResult, new global::System.Text.Json.JsonSerializerOptions - { - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = { new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }, - }); - } - - - - public static async global::System.Threading.Tasks.Task CallGetCurrentWeatherAsync( - this IWeatherTools functions, - string json, - global::System.Threading.CancellationToken cancellationToken = default) - { - var args = functions.AsGetCurrentWeatherAsyncArgs(json); - var jsonResult = await functions.GetCurrentWeatherAsync(args.Location, args.Unit, cancellationToken); - - return global::System.Text.Json.JsonSerializer.Serialize(jsonResult, new global::System.Text.Json.JsonSerializerOptions - { - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = { new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }, - }); - } - - - - public static async global::System.Threading.Tasks.Task CallAsync( - this IWeatherTools service, - string functionName, - string argumentsAsJson, - global::System.Threading.CancellationToken cancellationToken = default) - { - var calls = service.AsCalls(); - var func = calls[functionName]; - - return await func(argumentsAsJson, cancellationToken); - } - } -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.Weather#IWeatherTools.Tools.generated.verified.cs b/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.Weather#IWeatherTools.Tools.generated.verified.cs deleted file mode 100644 index 77a2721c..00000000 --- a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.Weather#IWeatherTools.Tools.generated.verified.cs +++ /dev/null @@ -1,69 +0,0 @@ -//HintName: IWeatherTools.Tools.generated.cs - -#nullable enable - -namespace OpenAI.IntegrationTests -{ - public static partial class WeatherToolsExtensions - { - public static global::System.Collections.Generic.IList AsTools(this IWeatherTools functions) - { - return new global::System.Collections.Generic.List - { - new global::CSharpToJsonSchema.Tool - { - Name = "GetCurrentWeather", - Description = "Get the current weather in a given location", - Strict = false, - Parameters = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "object", - Description = "Get the current weather in a given location", - Properties = new global::System.Collections.Generic.Dictionary - { - ["location"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "string", - Description = "The city and state, e.g. San Francisco, CA", - }, - ["unit"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "string", - Description = "", - Enum = new string[] { "celsius", "fahrenheit" }, - } - }, - Required = new string[] { "location" }, - }, - }, - - new global::CSharpToJsonSchema.Tool - { - Name = "GetCurrentWeatherAsync", - Description = "Get the current weather in a given location", - Strict = false, - Parameters = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "object", - Description = "Get the current weather in a given location", - Properties = new global::System.Collections.Generic.Dictionary - { - ["location"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "string", - Description = "The city and state, e.g. San Francisco, CA", - }, - ["unit"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "string", - Description = "", - Enum = new string[] { "celsius", "fahrenheit" }, - } - }, - Required = new string[] { "location" }, - }, - }, - }; - } - } -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.WeatherStrict#IWeatherStrictTools.Calls.generated.verified.cs b/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.WeatherStrict#IWeatherStrictTools.Calls.generated.verified.cs deleted file mode 100644 index f0ad7e7a..00000000 --- a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.WeatherStrict#IWeatherStrictTools.Calls.generated.verified.cs +++ /dev/null @@ -1,106 +0,0 @@ -//HintName: IWeatherStrictTools.Calls.generated.cs -#nullable enable - -namespace OpenAI.IntegrationTests -{ - public static partial class WeatherStrictToolsExtensions - { - public class GetCurrentWeatherArgs - { - public string Location { get; set; } = string.Empty; - public global::OpenAI.IntegrationTests.Unit2 Unit { get; set; } - } - - public class GetCurrentWeatherAsyncArgs - { - public string Location { get; set; } = string.Empty; - public global::OpenAI.IntegrationTests.Unit2 Unit { get; set; } - } - - public static global::System.Collections.Generic.IReadOnlyDictionary>> AsCalls(this IWeatherStrictTools service) - { - return new global::System.Collections.Generic.Dictionary>> - { - ["GetCurrentWeather"] = (json, _) => - { - return global::System.Threading.Tasks.Task.FromResult(service.CallGetCurrentWeather(json)); - }, - - ["GetCurrentWeatherAsync"] = async (json, cancellationToken) => - { - return await service.CallGetCurrentWeatherAsync(json, cancellationToken); - }, - - }; - } - - public static WeatherStrictToolsExtensions.GetCurrentWeatherArgs AsGetCurrentWeatherArgs( - this IWeatherStrictTools functions, - string json) - { - return - global::System.Text.Json.JsonSerializer.Deserialize(json, new global::System.Text.Json.JsonSerializerOptions - { - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = {{ new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }} - }) ?? - throw new global::System.InvalidOperationException("Could not deserialize JSON."); - } - - public static WeatherStrictToolsExtensions.GetCurrentWeatherAsyncArgs AsGetCurrentWeatherAsyncArgs( - this IWeatherStrictTools functions, - string json) - { - return - global::System.Text.Json.JsonSerializer.Deserialize(json, new global::System.Text.Json.JsonSerializerOptions - { - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = {{ new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }} - }) ?? - throw new global::System.InvalidOperationException("Could not deserialize JSON."); - } - - public static string CallGetCurrentWeather(this IWeatherStrictTools functions, string json) - { - var args = functions.AsGetCurrentWeatherArgs(json); - var jsonResult = functions.GetCurrentWeather(args.Location, args.Unit); - - return global::System.Text.Json.JsonSerializer.Serialize(jsonResult, new global::System.Text.Json.JsonSerializerOptions - { - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = { new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }, - }); - } - - - - public static async global::System.Threading.Tasks.Task CallGetCurrentWeatherAsync( - this IWeatherStrictTools functions, - string json, - global::System.Threading.CancellationToken cancellationToken = default) - { - var args = functions.AsGetCurrentWeatherAsyncArgs(json); - var jsonResult = await functions.GetCurrentWeatherAsync(args.Location, args.Unit, cancellationToken); - - return global::System.Text.Json.JsonSerializer.Serialize(jsonResult, new global::System.Text.Json.JsonSerializerOptions - { - PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase, - Converters = { new global::System.Text.Json.Serialization.JsonStringEnumConverter(global::System.Text.Json.JsonNamingPolicy.CamelCase) }, - }); - } - - - - public static async global::System.Threading.Tasks.Task CallAsync( - this IWeatherStrictTools service, - string functionName, - string argumentsAsJson, - global::System.Threading.CancellationToken cancellationToken = default) - { - var calls = service.AsCalls(); - var func = calls[functionName]; - - return await func(argumentsAsJson, cancellationToken); - } - } -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.WeatherStrict#IWeatherStrictTools.Tools.generated.verified.cs b/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.WeatherStrict#IWeatherStrictTools.Tools.generated.verified.cs deleted file mode 100644 index eb032938..00000000 --- a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.WeatherStrict#IWeatherStrictTools.Tools.generated.verified.cs +++ /dev/null @@ -1,69 +0,0 @@ -//HintName: IWeatherStrictTools.Tools.generated.cs - -#nullable enable - -namespace OpenAI.IntegrationTests -{ - public static partial class WeatherStrictToolsExtensions - { - public static global::System.Collections.Generic.IList AsTools(this IWeatherStrictTools functions) - { - return new global::System.Collections.Generic.List - { - new global::CSharpToJsonSchema.Tool - { - Name = "GetCurrentWeather", - Description = "Get the current weather in a given location", - Strict = true, - Parameters = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "object", - Description = "Get the current weather in a given location", - Properties = new global::System.Collections.Generic.Dictionary - { - ["location"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "string", - Description = "The city and state, e.g. San Francisco, CA", - }, - ["unit"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "string", - Description = "", - Enum = new string[] { "celsius", "fahrenheit" }, - } - }, - Required = new string[] { "location", "unit" }, - }, - }, - - new global::CSharpToJsonSchema.Tool - { - Name = "GetCurrentWeatherAsync", - Description = "Get the current weather in a given location", - Strict = true, - Parameters = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "object", - Description = "Get the current weather in a given location", - Properties = new global::System.Collections.Generic.Dictionary - { - ["location"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "string", - Description = "The city and state, e.g. San Francisco, CA", - }, - ["unit"] = new global::CSharpToJsonSchema.OpenApiSchema - { - Type = "string", - Description = "", - Enum = new string[] { "celsius", "fahrenheit" }, - } - }, - Required = new string[] { "location", "unit" }, - }, - }, - }; - } - } -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.WeatherStrict_Diagnostics.verified.txt b/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.WeatherStrict_Diagnostics.verified.txt deleted file mode 100644 index ad47dbb9..00000000 --- a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.WeatherStrict_Diagnostics.verified.txt +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.Weather_Diagnostics.verified.txt b/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.Weather_Diagnostics.verified.txt deleted file mode 100644 index ad47dbb9..00000000 --- a/src/tests/CSharpToJsonSchema.SnapshotTests/Snapshots/ToolTests.Weather_Diagnostics.verified.txt +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.SnapshotTests/TestHelper.cs b/src/tests/CSharpToJsonSchema.SnapshotTests/TestHelper.cs deleted file mode 100755 index bd686c01..00000000 --- a/src/tests/CSharpToJsonSchema.SnapshotTests/TestHelper.cs +++ /dev/null @@ -1,44 +0,0 @@ -using CSharpToJsonSchema.Generators; -using H.Generators.Tests.Extensions; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; - -namespace OpenAI.SnapshotTests; - -public static class TestHelper -{ - public static async Task CheckSourceAsync( - this VerifyBase verifier, - string source, - CancellationToken cancellationToken = default) - { - var referenceAssemblies = LatestReferenceAssemblies.Net80; - var references = await referenceAssemblies.ResolveAsync(null, cancellationToken); - references = references - .Add(MetadataReference.CreateFromFile(typeof(CSharpToJsonSchema.GenerateJsonSchemaAttribute).Assembly.Location)); - - var compilation = (Compilation)CSharpCompilation.Create( - assemblyName: "Tests", - syntaxTrees: new[] - { - CSharpSyntaxTree.ParseText(source, cancellationToken: cancellationToken), - }, - references: references, - options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - var driver = CSharpGeneratorDriver - .Create(new JsonSchemaGenerator()) - .RunGeneratorsAndUpdateCompilation(compilation, out compilation, out _, cancellationToken); - var diagnostics = compilation.GetDiagnostics(cancellationToken); - - await Task.WhenAll( - verifier - .Verify(diagnostics) - //.AutoVerify() - .UseDirectory("Snapshots") - .UseTextForParameters("Diagnostics"), - verifier - .Verify(driver) - //.AutoVerify() - .UseDirectory("Snapshots")); - } -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/Weather/UnitTests.TypeAsJsonSchema_NonStrict_JsonTypeInfo.verified.txt b/src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/Weather/UnitTests.TypeAsJsonSchema_NonStrict_JsonTypeInfo.verified.txt deleted file mode 100644 index 20e58058..00000000 --- a/src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/Weather/UnitTests.TypeAsJsonSchema_NonStrict_JsonTypeInfo.verified.txt +++ /dev/null @@ -1,38 +0,0 @@ -{ - "description": "", - "name": "Weather", - "schema": { - "type": "object", - "required": [ - "Location", - "Temperature", - "Unit", - "Description" - ], - "properties": { - "Location": { - "type": "string", - "additionalProperties": false - }, - "Temperature": { - "type": "number", - "format": "double", - "additionalProperties": false - }, - "Unit": { - "type": "string", - "enum": [ - "Celsius", - "Fahrenheit" - ], - "additionalProperties": false - }, - "Description": { - "type": "string", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "strict": false -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/Weather/UnitTests.TypeAsJsonSchema_Strict_JsonTypeInfo.verified.txt b/src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/Weather/UnitTests.TypeAsJsonSchema_Strict_JsonTypeInfo.verified.txt deleted file mode 100644 index 0b3e56c1..00000000 --- a/src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/Weather/UnitTests.TypeAsJsonSchema_Strict_JsonTypeInfo.verified.txt +++ /dev/null @@ -1,37 +0,0 @@ -{ - "description": "", - "name": "Weather", - "schema": { - "type": "object", - "required": [ - "Location", - "Temperature", - "Unit", - "Description" - ], - "properties": { - "Location": { - "type": "string", - "additionalProperties": false - }, - "Temperature": { - "type": "number", - "additionalProperties": false - }, - "Unit": { - "type": "string", - "enum": [ - "Celsius", - "Fahrenheit" - ], - "additionalProperties": false - }, - "Description": { - "type": "string", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "strict": true -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/WordsResponse/UnitTests.TypeAsJsonSchema_NonStrict_JsonTypeInfo.verified.txt b/src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/WordsResponse/UnitTests.TypeAsJsonSchema_NonStrict_JsonTypeInfo.verified.txt deleted file mode 100644 index 4faed352..00000000 --- a/src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/WordsResponse/UnitTests.TypeAsJsonSchema_NonStrict_JsonTypeInfo.verified.txt +++ /dev/null @@ -1,22 +0,0 @@ -{ - "description": "", - "name": "WordsResponse", - "schema": { - "type": "object", - "required": [ - "Words" - ], - "properties": { - "Words": { - "type": "array", - "items": { - "type": "string", - "additionalProperties": false - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "strict": false -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/WordsResponse/UnitTests.TypeAsJsonSchema_Strict_JsonTypeInfo.verified.txt b/src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/WordsResponse/UnitTests.TypeAsJsonSchema_Strict_JsonTypeInfo.verified.txt deleted file mode 100644 index 6825a7f7..00000000 --- a/src/tests/CSharpToJsonSchema.UnitTests/Snapshots/Schemas/WordsResponse/UnitTests.TypeAsJsonSchema_Strict_JsonTypeInfo.verified.txt +++ /dev/null @@ -1,22 +0,0 @@ -{ - "description": "", - "name": "WordsResponse", - "schema": { - "type": "object", - "required": [ - "Words" - ], - "properties": { - "Words": { - "type": "array", - "items": { - "type": "string", - "additionalProperties": false - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "strict": true -} \ No newline at end of file diff --git a/src/tests/CSharpToJsonSchema.UnitTests/Tests.AsJsonSchema.cs b/src/tests/CSharpToJsonSchema.UnitTests/Tests.AsJsonSchema.cs deleted file mode 100755 index b0330b96..00000000 --- a/src/tests/CSharpToJsonSchema.UnitTests/Tests.AsJsonSchema.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using CSharpToJsonSchema; - -namespace OpenAI.SnapshotTests; - -[TestClass] -public class UnitTests : VerifyBase -{ - [DataTestMethod] - [DataRow(typeof(WordsResponse))] - [DataRow(typeof(Weather))] - public async Task TypeAsJsonSchema(Type type) - { - // var strictSchema = TypeToSchemaHelpers.AsResponseFormat(type, strict: true); - // var nonStrictSchema = TypeToSchemaHelpers.AsResponseFormat(type, strict: false); - // - // var options = new JsonSerializerOptions - // { - // WriteIndented = true, - // DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, - // }; - // var strictJson = JsonSerializer.Serialize(strictSchema, options); - // var nonStrictJson = JsonSerializer.Serialize(nonStrictSchema, options); - - var typeInfo = SourceGeneratedContext.Default.GetTypeInfo(type); - typeInfo.Should().NotBeNull(); - var strictSchemaTrimmable = TypeToSchemaHelpers2.AsResponseFormat(typeInfo!, strict: true); - var nonStrictSchemaTrimmable = TypeToSchemaHelpers2.AsResponseFormat(typeInfo!, strict: false); - var strictJsonTrimmable = JsonSerializer.Serialize(strictSchemaTrimmable, SourceGeneratedContext.Default.ResponseFormatJsonSchemaJsonSchema); - var nonStrictJsonTrimmable = JsonSerializer.Serialize(nonStrictSchemaTrimmable, SourceGeneratedContext.Default.ResponseFormatJsonSchemaJsonSchema); - - // strictJson.Should().Be(strictJsonTrimmable); - // nonStrictJson.Should().Be(nonStrictJsonTrimmable); - - await Task.WhenAll( - // Verify(strictJson) - // .UseDirectory($"Snapshots/Schemas/{type.Name}") - // .UseTextForParameters("Strict_Type"), - // Verify(nonStrictJson) - // .UseDirectory($"Snapshots/Schemas/{type.Name}") - // .UseTextForParameters("NonStrict_Type"), - Verify(strictJsonTrimmable) - .UseDirectory($"Snapshots/Schemas/{type.Name}") - .UseTextForParameters("Strict_JsonTypeInfo") - .AutoVerify(), - Verify(nonStrictJsonTrimmable) - .UseDirectory($"Snapshots/Schemas/{type.Name}") - .UseTextForParameters("NonStrict_JsonTypeInfo") - .AutoVerify()); - } -} - -public class WordsResponse -{ - //[JsonPropertyName("words")] - public string[] Words { get; set; } = []; -} - -[JsonSourceGenerationOptions( - WriteIndented = true, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, - Converters = [typeof(JsonStringEnumConverter)])] -[JsonSerializable(typeof(WordsResponse))] -[JsonSerializable(typeof(Weather))] -[JsonSerializable(typeof(ResponseFormatJsonSchemaJsonSchema))] -[JsonSerializable(typeof(OpenApiSchema))] -public partial class SourceGeneratedContext : JsonSerializerContext; - - -public enum Unit -{ - Celsius, - Fahrenheit, -} - -public class Weather -{ - public string Location { get; set; } = string.Empty; - public double Temperature { get; set; } - public Unit Unit { get; set; } - public string Description { get; set; } = string.Empty; -} \ No newline at end of file diff --git a/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.AllTools.cs b/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.AllTools.cs index 64cad786..5977cd9e 100644 --- a/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.AllTools.cs +++ b/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.AllTools.cs @@ -27,7 +27,7 @@ public async Task Assistants_AllTools() instructions: "Use functions to resolve family relations into the names of people. Use file search to " + " look up the favorite numbers of people. Use code interpreter to create graphs of lines.", tools: tools - .Select(x => new OneOf(new AssistantToolsFunction + .Select(x => new ToolsItem2(new AssistantToolsFunction { Function = x.Function, })) @@ -101,13 +101,9 @@ ListMessagesResponse messages foreach (MessageObject message in messages.Data) { Console.WriteLine($"[{message.Role.ToString().ToUpper()}]: "); - foreach (OneOf< - MessageContentImageFileObject, - MessageContentImageUrlObject, - MessageContentTextObject, - MessageContentRefusalObject> contentItem in message.Content) + foreach (ContentItem2 contentItem in message.Content) { - if (contentItem.Value1 is {} imageFile) + if (contentItem.MessageImageFileObject is {} imageFile) { OpenAIFile imageInfo = await api.Files.RetrieveFileAsync(imageFile.ImageFile.FileId); byte[] imageBytes = await api.Files.DownloadFileAsync(imageFile.ImageFile.FileId); @@ -118,11 +114,11 @@ ListMessagesResponse messages Console.WriteLine($""); } - if (contentItem.Value2 is {} imageUrl) + if (contentItem.MessageImageUrlObject is {} imageUrl) { Console.WriteLine($" {imageUrl.ImageUrl.Url}"); } - if (contentItem.Value3 is {} text) + if (contentItem.MessageTextObject is {} text) { Console.WriteLine($"{text.Text.Value}"); @@ -130,17 +126,15 @@ ListMessagesResponse messages if (text.Text.Annotations.Count > 0) { Console.WriteLine(); - foreach (OneOf< - MessageContentTextAnnotationsFileCitationObject, - MessageContentTextAnnotationsFilePathObject> annotation in text.Text.Annotations) + foreach (AnnotationsItem annotation in text.Text.Annotations) { - if (annotation.Value1 is {} fileCitation) + if (annotation.MessageContentTextFileCitationObject is {} fileCitation) { Console.WriteLine($"* File citation, file ID: {fileCitation.FileCitation.FileId}"); Console.WriteLine($"* Text to replace: {fileCitation.Text}"); Console.WriteLine($"* Message content index range: {fileCitation.StartIndex}-{fileCitation.EndIndex}"); } - if (annotation.Value2 is {} filePath) + if (annotation.MessageContentTextFilePathObject is {} filePath) { Console.WriteLine($"* File output, new file ID: {filePath.FilePath.FileId}"); Console.WriteLine($"* Text to replace: {filePath.Text}"); @@ -149,7 +143,7 @@ ListMessagesResponse messages } } } - if (contentItem.Value4 is {} refusal) + if (contentItem.MessageRefusalObject is {} refusal) { Console.WriteLine($"Refusal: {refusal.Refusal}"); } @@ -166,24 +160,24 @@ ListMessagesResponse messages foreach (RunStepObject step in runSteps.Data) { Console.WriteLine($"Run step: {step.Status}"); - foreach (var toolCall in step.StepDetails.Value2?.ToolCalls ?? []) + foreach (var toolCall in step.StepDetails.ToolCalls?.ToolCalls ?? []) { - if (toolCall.Value1 is {} codeInterpreter) + if (toolCall.RunStepDetailsCodeObject is {} codeInterpreter) { Console.WriteLine($" --> Tool call: {codeInterpreter.Type}"); foreach (var output in codeInterpreter.CodeInterpreter.Outputs) { - if (output.Value1 is {} logs) + if (output.Logs is {} logs) { Console.WriteLine($" --> Output: {logs.Logs}"); } - if (output.Value2 is {} image) + if (output.Image is {} image) { Console.WriteLine($" --> Output: {image.Image.FileId}"); } } } - if (toolCall.Value2 is {} fileSearch) + if (toolCall.RunStepDetailsFileSearchObject is {} fileSearch) { Console.WriteLine($" --> Tool call: {fileSearch.Type}"); foreach (var output in fileSearch.FileSearch.Results ?? []) @@ -191,7 +185,7 @@ ListMessagesResponse messages Console.WriteLine($" --> Output: {output.FileId}"); } } - if (toolCall.Value3 is {} tool) + if (toolCall.RunStepDetailsFunctionObject is {} tool) { Console.WriteLine($" --> Tool call: {tool.Type}"); } diff --git a/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.AssistantsWithVision.cs b/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.AssistantsWithVision.cs index 25f4ad8c..9a550c49 100644 --- a/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.AssistantsWithVision.cs +++ b/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.AssistantsWithVision.cs @@ -1,101 +1,101 @@ -namespace OpenAI.IntegrationTests.Examples; - -public partial class Examples -{ - [Test] - [Explicit] - public async Task AssistantsWithVision() - { - using var api = GetAuthenticatedClient(); - - ImagesResponse appleImage = await api.Images.CreateImageAsync( - prompt: "picture of apple", - responseFormat: CreateImageRequestResponseFormat.B64Json); - byte[] appleBytes = appleImage.Data[0].Bytes; - - FileInfo appleFileInfo = new($"{Guid.NewGuid()}.png"); - - await File.WriteAllBytesAsync(appleFileInfo.FullName, appleBytes); - - Console.WriteLine($"Apple image available at:\n{new Uri(appleFileInfo.FullName).AbsoluteUri}"); - - Console.WriteLine($"Orange image available at:\n{new Uri("https://raw.githubusercontent.com/tryAGI/OpenAI/d237b700b03fe9913a6ff53fa623041e87705f2f/assets/orange.png")}"); - - OpenAIFile pictureOfAppleFile = await api.Files.CreateFileAsync( - file: appleBytes, - filename: appleFileInfo.Name, - purpose: CreateFileRequestPurpose.Vision); - - AssistantObject assistant = await api.Assistants.CreateAssistantAsync( - model: CreateAssistantRequestModel.Gpt4o, - instructions: "When asked a question, attempt to answer very concisely. " + - "Prefer one-sentence answers whenever feasible."); - - ThreadObject thread = await api.Assistants.CreateThreadAsync(new CreateThreadRequest - { - Messages = [ - "Hello, assistant! Please compare these two images for me:", - pictureOfAppleFile, - new Uri("https://raw.githubusercontent.com/tryAGI/OpenAI/d237b700b03fe9913a6ff53fa623041e87705f2f/assets/orange.png"), - ] - }); - - var streamingUpdates = api.Assistants.CreateRunAsStreamAsync( - threadId: thread.Id, - assistantId: assistant.Id, - instructions: "When possible, try to sneak in puns if you're asked to compare things."); - - await foreach (AssistantStreamEvent streamingUpdate in streamingUpdates) - { - if (streamingUpdate.Error is {} error) - { - Console.WriteLine("--- Error ---"); - Console.WriteLine($"Message: {error.Data.Message}"); - Console.WriteLine($"Code: {error.Data.Code}"); - Console.WriteLine($"Type: {error.Data.Type}"); - } - if (streamingUpdate.Run is {} run) - { - if (run.Value1 is { Event: RunStreamEventVariant1Event.ThreadRunCreated }) - { - Console.WriteLine("--- Run created! ---"); - } - } - if (streamingUpdate.Message is {} message) - { - if (message.Value3 is - { - Event: MessageStreamEventVariant3Event.ThreadMessageDelta - } delta) - { - foreach (var deltaVariation in delta.Data.Delta.Content ?? []) - { - if (deltaVariation.Value1 is {} imageFile) - { - Console.WriteLine(); - Console.WriteLine(imageFile.ImageFile?.FileId); - } - if (deltaVariation.Value2 is {} text) - { - Console.Write(text.Text?.Value); - } - if (deltaVariation.Value3 is {} refusal) - { - Console.WriteLine(); - Console.WriteLine(refusal.Refusal); - } - if (deltaVariation.Value4 is {} imageUrl) - { - Console.WriteLine(); - Console.WriteLine(imageUrl.ImageUrl?.Url); - } - } - } - } - } - - _ = await api.Files.DeleteFileAsync(pictureOfAppleFile.Id); - _ = await api.Assistants.DeleteThreadAsync(thread.Id); - _ = await api.Assistants.DeleteAssistantAsync(assistant.Id); - } -} +// namespace OpenAI.IntegrationTests.Examples; +// +// public partial class Examples +// { +// [Test] +// [Explicit] +// public async Task AssistantsWithVision() +// { +// using var api = GetAuthenticatedClient(); +// +// ImagesResponse appleImage = await api.Images.CreateImageAsync( +// prompt: "picture of apple", +// responseFormat: CreateImageRequestResponseFormat.B64Json); +// byte[] appleBytes = appleImage.Data[0].Bytes; +// +// FileInfo appleFileInfo = new($"{Guid.NewGuid()}.png"); +// +// await File.WriteAllBytesAsync(appleFileInfo.FullName, appleBytes); +// +// Console.WriteLine($"Apple image available at:\n{new Uri(appleFileInfo.FullName).AbsoluteUri}"); +// +// Console.WriteLine($"Orange image available at:\n{new Uri("https://raw.githubusercontent.com/tryAGI/OpenAI/d237b700b03fe9913a6ff53fa623041e87705f2f/assets/orange.png")}"); +// +// OpenAIFile pictureOfAppleFile = await api.Files.CreateFileAsync( +// file: appleBytes, +// filename: appleFileInfo.Name, +// purpose: CreateFileRequestPurpose.Vision); +// +// AssistantObject assistant = await api.Assistants.CreateAssistantAsync( +// model: CreateAssistantRequestModel.Gpt4o, +// instructions: "When asked a question, attempt to answer very concisely. " + +// "Prefer one-sentence answers whenever feasible."); +// +// ThreadObject thread = await api.Assistants.CreateThreadAsync(new CreateThreadRequest +// { +// Messages = [ +// "Hello, assistant! Please compare these two images for me:", +// pictureOfAppleFile, +// new Uri("https://raw.githubusercontent.com/tryAGI/OpenAI/d237b700b03fe9913a6ff53fa623041e87705f2f/assets/orange.png"), +// ] +// }); +// +// var streamingUpdates = api.Assistants.CreateRunAsStreamAsync( +// threadId: thread.Id, +// assistantId: assistant.Id, +// instructions: "When possible, try to sneak in puns if you're asked to compare things."); +// +// await foreach (AssistantStreamEvent streamingUpdate in streamingUpdates) +// { +// if (streamingUpdate.Error is {} error) +// { +// Console.WriteLine("--- Error ---"); +// Console.WriteLine($"Message: {error.Data.Message}"); +// Console.WriteLine($"Code: {error.Data.Code}"); +// Console.WriteLine($"Type: {error.Data.Type}"); +// } +// if (streamingUpdate.Run is {} run) +// { +// if (run.Value1 is { Event: RunStreamEventVariant1Event.ThreadRunCreated }) +// { +// Console.WriteLine("--- Run created! ---"); +// } +// } +// if (streamingUpdate.Message is {} message) +// { +// if (message.Value3 is +// { +// Event: MessageStreamEventVariant3Event.ThreadMessageDelta +// } delta) +// { +// foreach (var deltaVariation in delta.Data.Delta.Content ?? []) +// { +// if (deltaVariation.Value1 is {} imageFile) +// { +// Console.WriteLine(); +// Console.WriteLine(imageFile.ImageFile?.FileId); +// } +// if (deltaVariation.Value2 is {} text) +// { +// Console.Write(text.Text?.Value); +// } +// if (deltaVariation.Value3 is {} refusal) +// { +// Console.WriteLine(); +// Console.WriteLine(refusal.Refusal); +// } +// if (deltaVariation.Value4 is {} imageUrl) +// { +// Console.WriteLine(); +// Console.WriteLine(imageUrl.ImageUrl?.Url); +// } +// } +// } +// } +// } +// +// _ = await api.Files.DeleteFileAsync(pictureOfAppleFile.Id); +// _ = await api.Assistants.DeleteThreadAsync(thread.Id); +// _ = await api.Assistants.DeleteAssistantAsync(assistant.Id); +// } +// } diff --git a/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.FunctionCalling.cs b/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.FunctionCalling.cs index 73b4de7f..276a96dc 100644 --- a/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.FunctionCalling.cs +++ b/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.FunctionCalling.cs @@ -16,7 +16,7 @@ public async Task Assistants_FunctionCalling() name: "Example: Function Calling", instructions: "Don't make assumptions about what values to plug into functions." + " Ask for clarification if a user request is ambiguous.", - tools: tools.Select(x => new OneOf(new AssistantToolsFunction + tools: tools.Select(x => new ToolsItem2(new AssistantToolsFunction { Function = x.Function, })).ToArray()); @@ -68,21 +68,17 @@ ListMessagesResponse messages foreach (MessageObject message in messages.Data) { Console.WriteLine($"[{message.Role.ToString().ToUpper()}]: "); - foreach (OneOf< - MessageContentImageFileObject, - MessageContentImageUrlObject, - MessageContentTextObject, - MessageContentRefusalObject> contentItem in message.Content) + foreach (ContentItem2 contentItem in message.Content) { - if (contentItem.Value1 is {} imageFile) + if (contentItem.MessageImageFileObject is {} imageFile) { Console.WriteLine($" {imageFile.ImageFile.FileId}"); } - if (contentItem.Value2 is {} imageUrl) + if (contentItem.MessageImageUrlObject is {} imageUrl) { Console.WriteLine($" {imageUrl.ImageUrl.Url}"); } - if (contentItem.Value3 is {} text) + if (contentItem.MessageTextObject is {} text) { Console.WriteLine($"{text.Text.Value}"); @@ -90,17 +86,15 @@ ListMessagesResponse messages if (text.Text.Annotations.Count > 0) { Console.WriteLine(); - foreach (OneOf< - MessageContentTextAnnotationsFileCitationObject, - MessageContentTextAnnotationsFilePathObject> annotation in text.Text.Annotations) + foreach (AnnotationsItem annotation in text.Text.Annotations) { - if (annotation.Value1 is {} fileCitation) + if (annotation.MessageContentTextFileCitationObject is {} fileCitation) { Console.WriteLine($"* File citation, file ID: {fileCitation.FileCitation.FileId}"); Console.WriteLine($"* Text to replace: {fileCitation.Text}"); Console.WriteLine($"* Message content index range: {fileCitation.StartIndex}-{fileCitation.EndIndex}"); } - if (annotation.Value2 is {} filePath) + if (annotation.MessageContentTextFilePathObject is {} filePath) { Console.WriteLine($"* File output, new file ID: {filePath.FilePath.FileId}"); Console.WriteLine($"* Text to replace: {filePath.Text}"); @@ -109,7 +103,7 @@ ListMessagesResponse messages } } } - if (contentItem.Value4 is {} refusal) + if (contentItem.MessageRefusalObject is {} refusal) { Console.WriteLine($"Refusal: {refusal.Refusal}"); } diff --git a/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.FunctionCallingStreaming.cs b/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.FunctionCallingStreaming.cs index 8f01d321..f05455df 100644 --- a/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.FunctionCallingStreaming.cs +++ b/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.FunctionCallingStreaming.cs @@ -1,114 +1,114 @@ -namespace OpenAI.IntegrationTests.Examples; - -public partial class Examples -{ - [Test] - [Explicit] - public async Task Assistants_FunctionCallingStreaming() - { - using var api = GetAuthenticatedClient(); - - var service = new FunctionCallingService(); - IList tools = service.AsTools().AsOpenAiTools(); - - AssistantObject assistant = await api.Assistants.CreateAssistantAsync( - model: CreateAssistantRequestModel.Gpt4o, - name: "Example: Function Calling", - instructions: "Don't make assumptions about what values to plug into functions." - + " Ask for clarification if a user request is ambiguous.", - tools: tools.Select(x => new OneOf(new AssistantToolsFunction - { - Function = x.Function, - })).ToArray()); - - ThreadObject thread = await api.Assistants.CreateThreadAsync(new CreateThreadRequest - { - Messages = ["What's the weather like today?"], - }); - - var streamingUpdates = api.Assistants.CreateRunAsStreamAsync( - threadId: thread.Id, - assistantId: assistant.Id); - - RunObject? currentRun; - do - { - currentRun = null; - List outputsToSubmit = []; - - await foreach (AssistantStreamEvent streamingUpdate in streamingUpdates) - { - if (streamingUpdate.Run is {} run) - { - if (run.Value1 is { Event: RunStreamEventVariant1Event.ThreadRunCreated, Data: {} newRun }) - { - Console.WriteLine("--- Run created! ---"); - - currentRun = newRun; - } - if (run.Value4 is - { - Event: RunStreamEventVariant4Event.ThreadRunRequiresAction, - Data.RequiredAction: {} requiredAction, - }) - { - foreach (RunToolCallObject toolCall in requiredAction.SubmitToolOutputs.ToolCalls) - { - var json = await service.CallAsync( - functionName: toolCall.Function.Name, - argumentsAsJson: toolCall.Function.Arguments); - outputsToSubmit.Add(new SubmitToolOutputsRunRequestToolOutput - { - ToolCallId = toolCall.Id, - Output = json, - }); - } - } - } - if (streamingUpdate.Message is {} message) - { - if (message.Value3 is - { - Event: MessageStreamEventVariant3Event.ThreadMessageDelta - } delta) - { - foreach (var deltaVariation in delta.Data.Delta.Content ?? []) - { - if (deltaVariation.Value1 is {} imageFile) - { - Console.WriteLine(); - Console.WriteLine(imageFile.ImageFile?.FileId); - } - if (deltaVariation.Value2 is {} text) - { - Console.Write(text.Text?.Value); - } - if (deltaVariation.Value3 is {} refusal) - { - Console.WriteLine(); - Console.WriteLine(refusal.Refusal); - } - if (deltaVariation.Value4 is {} imageUrl) - { - Console.WriteLine(); - Console.WriteLine(imageUrl.ImageUrl?.Url); - } - } - } - } - } - - if (outputsToSubmit.Count > 0) - { - // streamingUpdates = await api.Assistants.SubmitToolOuputsToRunAsStreamAsync( - // threadId: currentRun.ThreadId, - // runId: currentRun.Id, - // outputsToSubmit); - } - } - while (currentRun?.Status is RunObjectStatus.Queued or RunObjectStatus.InProgress or RunObjectStatus.RequiresAction); - - _ = await api.Assistants.DeleteThreadAsync(thread.Id); - _ = await api.Assistants.DeleteAssistantAsync(assistant.Id); - } -} +// namespace OpenAI.IntegrationTests.Examples; +// +// public partial class Examples +// { +// [Test] +// [Explicit] +// public async Task Assistants_FunctionCallingStreaming() +// { +// using var api = GetAuthenticatedClient(); +// +// var service = new FunctionCallingService(); +// IList tools = service.AsTools().AsOpenAiTools(); +// +// AssistantObject assistant = await api.Assistants.CreateAssistantAsync( +// model: CreateAssistantRequestModel.Gpt4o, +// name: "Example: Function Calling", +// instructions: "Don't make assumptions about what values to plug into functions." +// + " Ask for clarification if a user request is ambiguous.", +// tools: tools.Select(x => new ToolsItem2(new AssistantToolsFunction +// { +// Function = x.Function, +// })).ToArray()); +// +// ThreadObject thread = await api.Assistants.CreateThreadAsync(new CreateThreadRequest +// { +// Messages = ["What's the weather like today?"], +// }); +// +// var streamingUpdates = api.Assistants.CreateRunAsStreamAsync( +// threadId: thread.Id, +// assistantId: assistant.Id); +// +// RunObject? currentRun; +// do +// { +// currentRun = null; +// List outputsToSubmit = []; +// +// await foreach (AssistantStreamEvent streamingUpdate in streamingUpdates) +// { +// if (streamingUpdate.Run is {} run) +// { +// if (run.Value1 is { Event: RunStreamEventVariant1Event.ThreadRunCreated, Data: {} newRun }) +// { +// Console.WriteLine("--- Run created! ---"); +// +// currentRun = newRun; +// } +// if (run.Value4 is +// { +// Event: RunStreamEventVariant4Event.ThreadRunRequiresAction, +// Data.RequiredAction: {} requiredAction, +// }) +// { +// foreach (RunToolCallObject toolCall in requiredAction.SubmitToolOutputs.ToolCalls) +// { +// var json = await service.CallAsync( +// functionName: toolCall.Function.Name, +// argumentsAsJson: toolCall.Function.Arguments); +// outputsToSubmit.Add(new SubmitToolOutputsRunRequestToolOutput +// { +// ToolCallId = toolCall.Id, +// Output = json, +// }); +// } +// } +// } +// if (streamingUpdate.Message is {} message) +// { +// if (message.Value3 is +// { +// Event: MessageStreamEventVariant3Event.ThreadMessageDelta +// } delta) +// { +// foreach (var deltaVariation in delta.Data.Delta.Content ?? []) +// { +// if (deltaVariation.Value1 is {} imageFile) +// { +// Console.WriteLine(); +// Console.WriteLine(imageFile.ImageFile?.FileId); +// } +// if (deltaVariation.Value2 is {} text) +// { +// Console.Write(text.Text?.Value); +// } +// if (deltaVariation.Value3 is {} refusal) +// { +// Console.WriteLine(); +// Console.WriteLine(refusal.Refusal); +// } +// if (deltaVariation.Value4 is {} imageUrl) +// { +// Console.WriteLine(); +// Console.WriteLine(imageUrl.ImageUrl?.Url); +// } +// } +// } +// } +// } +// +// if (outputsToSubmit.Count > 0) +// { +// // streamingUpdates = await api.Assistants.SubmitToolOuputsToRunAsStreamAsync( +// // threadId: currentRun.ThreadId, +// // runId: currentRun.Id, +// // outputsToSubmit); +// } +// } +// while (currentRun?.Status is RunObjectStatus.Queued or RunObjectStatus.InProgress or RunObjectStatus.RequiresAction); +// +// _ = await api.Assistants.DeleteThreadAsync(thread.Id); +// _ = await api.Assistants.DeleteAssistantAsync(assistant.Id); +// } +// } diff --git a/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.RetrievalAugmentedGeneration.cs b/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.RetrievalAugmentedGeneration.cs index bc2cdf90..9d9172a4 100644 --- a/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.RetrievalAugmentedGeneration.cs +++ b/src/tests/OpenAI.IntegrationTests/Examples/Examples.Assistants.RetrievalAugmentedGeneration.cs @@ -105,40 +105,36 @@ ListMessagesResponse messages foreach (MessageObject message in messages.Data) { Console.Write($"[{message.Role.ToString().ToUpper()}]: "); - foreach (OneOf< - MessageContentImageFileObject, - MessageContentImageUrlObject, - MessageContentTextObject, - MessageContentRefusalObject> contentItem in message.Content) + foreach (ContentItem2 contentItem in message.Content) { - if (contentItem.IsValue3) + if (contentItem.MessageTextObject is {} text) { - Console.WriteLine($"{contentItem.Value3.Text.Value}"); + Console.WriteLine($"{text.Text.Value}"); - if (contentItem.Value3.Text.Annotations.Count > 0) + if (text.Text.Annotations.Count > 0) { Console.WriteLine(); } // Include annotations, if any. - foreach (OneOf< - MessageContentTextAnnotationsFileCitationObject, - MessageContentTextAnnotationsFilePathObject> annotation in contentItem.Value3.Text.Annotations) + foreach (AnnotationsItem annotation in text.Text.Annotations) { - if (annotation.IsValue1 && !string.IsNullOrEmpty(annotation.Value1.FileCitation.FileId)) + if (annotation.MessageContentTextFileCitationObject is {} citation && + !string.IsNullOrEmpty(citation.FileCitation.FileId)) { - Console.WriteLine($"* File citation, file ID: {annotation.Value1.FileCitation.FileId}"); + Console.WriteLine($"* File citation, file ID: {citation.FileCitation.FileId}"); } - if (annotation.IsValue2 && !string.IsNullOrEmpty(annotation.Value2.FilePath.FileId)) + if (annotation.MessageContentTextFilePathObject is {} path && + !string.IsNullOrEmpty(path.FilePath.FileId)) { - Console.WriteLine($"* File output, new file ID: {annotation.Value2.FilePath.FileId}"); + Console.WriteLine($"* File output, new file ID: {path.FilePath.FileId}"); } } } - if (contentItem.IsValue1) + if (contentItem.MessageImageFileObject is {} imageFile) { - OpenAIFile imageInfo = await api.Files.RetrieveFileAsync(contentItem.Value1.ImageFile.FileId); - byte[] imageBytes = await api.Files.DownloadFileAsync(contentItem.Value1.ImageFile.FileId); + OpenAIFile imageInfo = await api.Files.RetrieveFileAsync(imageFile.ImageFile.FileId); + byte[] imageBytes = await api.Files.DownloadFileAsync(imageFile.ImageFile.FileId); FileInfo fileInfo = new($"{imageInfo.Filename}.png"); diff --git a/src/tests/OpenAI.IntegrationTests/OpenAI.IntegrationTests.csproj b/src/tests/OpenAI.IntegrationTests/OpenAI.IntegrationTests.csproj index 60ecfa4d..ec1af16c 100644 --- a/src/tests/OpenAI.IntegrationTests/OpenAI.IntegrationTests.csproj +++ b/src/tests/OpenAI.IntegrationTests/OpenAI.IntegrationTests.csproj @@ -31,7 +31,6 @@ - \ No newline at end of file