Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Azure OpenAI: add capabilities up through 2023-07-01-preview #37539

Merged
merged 16 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 125 additions & 3 deletions sdk/openai/Azure.AI.OpenAI/api/Azure.AI.OpenAI.netstandard2.0.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

using System;
using System.Collections.Generic;
using System.Linq;
using Azure.Core.Pipeline;

namespace Azure.AI.OpenAI
{
Expand All @@ -31,5 +31,41 @@ public static Choice Choice(string text = null, int index = default, Completions

return new Choice(text, index, logProbabilityModel, finishReason);
}

/// <summary>
/// Initializes a new instance of ImageLocation for testing and mocking.
/// </summary>
/// <param name="url">The URL to represent as a download source for an image</param>
/// <param name="pipeline">
/// An optional HttpPipeline to associate with the ImageLocation, needed for the
/// GetStream() convenience method to function.
/// </param>
/// <returns>A new instance of ImageLocation</returns>
/// <exception cref="ArgumentNullException">Thrown if url is null</exception>
public static ImageLocation ImageLocation(Uri url, HttpPipeline pipeline = default)
{
if (url == null)
{
throw new ArgumentNullException(nameof(url));
}

return new ImageLocation(url)
{
ClientPipeline = pipeline,
};
}

/// <summary>
/// Initializes a new instance of ImageGenerations for tests and mocking.
/// </summary>
/// <param name="created">The timestamp to use for image generation origination</param>
/// <param name="data">The collection of ImageLocations to associate with the result</param>
/// <returns>A new instance of ImageGenerations</returns>
public static ImageGenerations ImageGenerations(
DateTimeOffset created,
IEnumerable<ImageLocation> data)
{
return new ImageGenerations(created.ToUnixTimeSeconds(), data);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#nullable disable

using System;
using System.Collections.Generic;
using System.Text.Json;
using Azure;
Expand All @@ -25,6 +26,38 @@ void IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
writer.WriteObjectValue(item);
}
writer.WriteEndArray();
if (Optional.IsDefined(Functions) && Functions.Count > 0)
{
writer.WritePropertyName("functions"u8);
writer.WriteStartArray();
foreach (var item in Functions)
{
if (item.IsPredefined)
{
throw new ArgumentException(
@"Predefined function definitions such as 'auto' and 'none' cannot be provided as
custom functions. These should only be used to constrain the FunctionCall option.");
}
writer.WriteObjectValue(item);
}
writer.WriteEndArray();
}
if (Optional.IsDefined(FunctionCall))
{
writer.WritePropertyName("function_call");

if (FunctionCall.IsPredefined)
{
writer.WriteStringValue(FunctionCall.Name);
}
else
{
writer.WriteStartObject();
writer.WritePropertyName("name");
writer.WriteStringValue(FunctionCall.Name);
writer.WriteEndObject();
}
}
if (Optional.IsDefined(MaxTokens))
{
if (MaxTokens != null)
Expand Down
27 changes: 27 additions & 0 deletions sdk/openai/Azure.AI.OpenAI/src/Custom/ChatCompletionsOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,32 @@ public partial class ChatCompletionsOptions
/// <inheritdoc cref="CompletionsOptions.User"/>
public string User { get; set; }

/// <summary> A list of functions the model may generate JSON inputs for. </summary>
public IList<FunctionDefinition> Functions { get; set; }

/// <summary>
/// Controls how the model will use provided Functions.
/// </summary>
/// <remarks>
/// <list type="bullet">
/// <item>
/// Providing a custom <see cref="FunctionDefinition"/> will request that the model limit its
/// completions to function calls for that function.
/// </item>
/// <item>
/// <see cref="FunctionDefinition.Auto"/> represents the default behavior and will allow the model
/// to freely select between issuing a stanard completions response or a call to any provided
/// function.
/// </item>
/// <item>
/// <see cref="FunctionDefinition.None"/> will request that the model only issue standard
/// completions responses, irrespective of provided functions. Note that the function definitions
/// provided may still influence the completions content.
/// </item>
/// </list>
/// </remarks>
public FunctionDefinition FunctionCall { get; set; }

internal IDictionary<string, int> InternalStringKeyedTokenSelectionBiases { get; }

internal string InternalNonAzureModelName { get; set; }
Expand All @@ -64,6 +90,7 @@ public ChatCompletionsOptions(IEnumerable<ChatMessage> messages)
Messages = messages.ToList();
TokenSelectionBiases = new ChangeTrackingDictionary<int, int>();
StopSequences = new ChangeTrackingList<string>();
Functions = new ChangeTrackingList<FunctionDefinition>();
}

/// <inheritdoc cref="ChatCompletionsOptions(IEnumerable{ChatMessage})"/>
Expand Down
41 changes: 41 additions & 0 deletions sdk/openai/Azure.AI.OpenAI/src/Custom/ChatMessage.Serialization.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

using System.Text.Json;
using Azure;
using Azure.Core;

namespace Azure.AI.OpenAI
{
[CodeGenSuppress("global::Azure.Core.IUtf8JsonSerializable.Write", typeof(Utf8JsonWriter))]
public partial class ChatMessage : IUtf8JsonSerializable
{
void IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
{
writer.WriteStartObject();
writer.WritePropertyName("role"u8);
writer.WriteStringValue(Role.ToString());
// Custom code note: we need to force explicit serialization of 'content' even if it's null.
// if (Optional.IsDefined(Content))
{
writer.WritePropertyName("content"u8);
writer.WriteStringValue(Content);
}
if (Optional.IsDefined(Name))
{
writer.WritePropertyName("name"u8);
writer.WriteStringValue(Name);
}
if (Optional.IsDefined(FunctionCall))
{
writer.WritePropertyName("function_call"u8);
writer.WriteObjectValue(FunctionCall);
}
writer.WriteEndObject();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ namespace Azure.AI.OpenAI
/// <summary> Representation of the manner in which a completions response concluded. </summary>
public readonly partial struct CompletionsFinishReason
{
private const string StoppedValue = "stop";
private const string TokenLimitReachedValue = "length";
private const string ContentFilteredValue = "content_filter";

/// <summary> Initializes a new instance of <see cref="CompletionsFinishReason"/>. </summary>
public CompletionsFinishReason(string value)
{
Expand Down
33 changes: 33 additions & 0 deletions sdk/openai/Azure.AI.OpenAI/src/Custom/FunctionCall.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

using System;

namespace Azure.AI.OpenAI
{
/// <summary> The name and arguments of a function that should be called, as generated by the model. </summary>
public partial class FunctionCall
{
/// <summary> Initializes a new instance of FunctionCall. </summary>
/// <param name="name"> The name of the function to call. </param>
/// <param name="arguments">
/// The arguments to call the function with, as generated by the model in JSON format.
/// Note that the model does not always generate valid JSON, and may hallucinate parameters
/// not defined by your function schema. Validate the arguments in your code before calling
/// your function.
/// </param>
public FunctionCall(string name, string arguments)
{
// Custom code note: we suppress null checks for deserialization reuse in streaming scenarios
// Argument.AssertNotNull(name, nameof(name));
// Argument.AssertNotNull(arguments, nameof(arguments));

Name = name;
Arguments = arguments;
}
}
}
9 changes: 9 additions & 0 deletions sdk/openai/Azure.AI.OpenAI/src/Custom/FunctionCallPreset.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;

namespace Azure.AI.OpenAI;

internal readonly partial struct FunctionCallPreset : IEquatable<FunctionCallPreset>
{}
38 changes: 38 additions & 0 deletions sdk/openai/Azure.AI.OpenAI/src/Custom/FunctionDefinition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

using System;
using Azure.Core;

namespace Azure.AI.OpenAI
{
/// <summary> The definition of a caller-specified function that chat completions may invoke in response to matching user input. </summary>
public partial class FunctionDefinition
{
/// <inheritdoc cref="FunctionCallPreset.Auto"/>
public static FunctionDefinition Auto
= CreatePredefinedFunctionDefinition(FunctionCallPreset.Auto.ToString());

/// <inheritdoc cref="FunctionCallPreset.None"/>
public static FunctionDefinition None
= CreatePredefinedFunctionDefinition(FunctionCallPreset.None.ToString());

public FunctionDefinition()
{ }

/// <summary> The name of the function to be called. </summary>
public string Name { get; set; }

internal bool IsPredefined { get; set; } = false;

internal static FunctionDefinition CreatePredefinedFunctionDefinition(string functionName)
=> new FunctionDefinition(functionName)
{
IsPredefined = true
};
}
}
8 changes: 8 additions & 0 deletions sdk/openai/Azure.AI.OpenAI/src/Custom/FunctionName.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Azure.AI.OpenAI
{
public partial class FunctionName
{}
}
31 changes: 31 additions & 0 deletions sdk/openai/Azure.AI.OpenAI/src/Custom/ImageGenerationOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

namespace Azure.AI.OpenAI
{
/// <summary> Represents the request data used to generate images. </summary>
public partial class ImageGenerationOptions
{
/// <summary> Initializes a new instance of ImageGenerationOptions. </summary>
public ImageGenerationOptions()
{
}

/// <summary>
/// Gets or sets the description used to influence the generation of requested images.
/// </summary>
/// <remarks>
/// For best results, ensure that the prompt is specific and sufficiently rich in details about
/// desired topical content.
/// </remarks>
public string Prompt { get; set; }

// Custom code note: we suppress the ResponseFormat field as it'll be handled by unique method signatures
// for the differing response types (separate URL and b64 methods)
internal ImageGenerationResponseFormat? ResponseFormat { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

using System;

namespace Azure.AI.OpenAI
{
// Custom code note: we explicitly pre-set the visibility of the response format "enum-like" to internal as
// response format will be handled by separate method signatures for URL/b64/etc..

internal readonly partial struct ImageGenerationResponseFormat : IEquatable<ImageGenerationResponseFormat>
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

using System.Collections.Generic;
using System.Text.Json;
using Azure;
using Azure.Core;

namespace Azure.AI.OpenAI
{
public partial class ImageGenerations
{
internal static ImageGenerations DeserializeImageGenerations(JsonElement element)
{
if (element.ValueKind == JsonValueKind.Null)
{
return null;
}
long created = default;
IReadOnlyList<ImageLocation> data = default;
foreach (var property in element.EnumerateObject())
{
if (property.NameEquals("created"u8))
{
created = property.Value.GetInt64();
continue;
}
if (property.NameEquals("data"u8))
{
// Custom code note: manual fixup of union deserialization necessary pending expanded options for
// union emission.
List<ImageLocation> array = new List<ImageLocation>();
foreach (var item in property.Value.EnumerateArray())
{
array.Add(ImageLocation.DeserializeImageLocation(item));
}
data = array;
continue;
}
}
return new ImageGenerations(created, data);
}
}
}
Loading