diff --git a/OpenAI/Packages/com.openai.unity/Documentation~/README.md b/OpenAI/Packages/com.openai.unity/Documentation~/README.md index 0be9f792..c1ff18c9 100644 --- a/OpenAI/Packages/com.openai.unity/Documentation~/README.md +++ b/OpenAI/Packages/com.openai.unity/Documentation~/README.md @@ -88,13 +88,13 @@ There are 4 ways to provide your API keys, in order of precedence: #### Pass keys directly with constructor ```csharp -var api = new OpenAIClient("sk-mykeyhere"); +var api = new OpenAIClient("sk-apiKey"); ``` Or create a `OpenAIAuthentication` object manually ```csharp -var api = new OpenAIClient(new OpenAIAuthentication("sk-secretkey")); +var api = new OpenAIClient(new OpenAIAuthentication("sk-apiKey", "org-yourOrganizationId")); ``` #### Unity Scriptable Object @@ -140,19 +140,12 @@ var api = new OpenAIClient(OpenAIAuthentication.LoadFromDirectory("your/path/to/ Use your system's environment variables specify an api key and organization to use. - Use `OPENAI_API_KEY` for your api key. -- Use `OPEN_AI_ORGANIZATION_ID` to specify an organization. +- Use `OPENAI_ORGANIZATION_ID` to specify an organization. ```csharp var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); ``` -or - -```csharp -var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv("org-yourOrganizationId")); -``` - - ### [Models](https://beta.openai.com/docs/api-reference/models) List and describe the various models available in the API. You can refer to the [Models documentation](https://beta.openai.com/docs/models) to understand what models are available and the differences between them. @@ -280,12 +273,12 @@ Creates an image given a prompt. var api = new OpenAIClient(); var results = await api.ImagesEndPoint.GenerateImageAsync("A house riding a velociraptor", 1, ImageSize.Small); -foreach (var result in results) +foreach (var (path, texture) in results) { - Debug.Log(result.Key); - // result.Key == file://path/to/image.png - Assert.IsNotNull(result.Value); - // result.Value == The preloaded Texture2D + Debug.Log(path); + // path == file://path/to/image.png + Assert.IsNotNull(texture); + // texture == The preloaded Texture2D } ``` @@ -297,12 +290,12 @@ Creates an edited or extended image given an original image and a prompt. var api = new OpenAIClient(); var results = await api.ImagesEndPoint.CreateImageEditAsync(Path.GetFullPath(imageAssetPath), Path.GetFullPath(maskAssetPath), "A sunlit indoor lounge area with a pool containing a flamingo", 1, ImageSize.Small); -foreach (var result in results) +foreach (var (path, texture) in results) { - Debug.Log(result.Key); - // result.Key == file://path/to/image.png - Assert.IsNotNull(result.Value); - // result.Value == Texture2D + Debug.Log(path); + // path == file://path/to/image.png + Assert.IsNotNull(texture); + // texture == The preloaded Texture2D } ``` @@ -314,12 +307,12 @@ Creates a variation of a given image. var api = new OpenAIClient(); var results = await api.ImagesEndPoint.CreateImageVariationAsync(Path.GetFullPath(imageAssetPath), 1, ImageSize.Small); -foreach (var result in results) +foreach (var (path, texture) in results) { - Debug.Log(result.Key); - // result.Key == file://path/to/image.png - Assert.IsNotNull(result.Value); - // result.Value == Texture2D + Debug.Log(path); + // path == file://path/to/image.png + Assert.IsNotNull(texture); + // texture == The preloaded Texture2D } ``` diff --git a/OpenAI/Packages/com.openai.unity/Runtime/AuthInfo.cs b/OpenAI/Packages/com.openai.unity/Runtime/AuthInfo.cs index d7c2bbb1..088f3aac 100644 --- a/OpenAI/Packages/com.openai.unity/Runtime/AuthInfo.cs +++ b/OpenAI/Packages/com.openai.unity/Runtime/AuthInfo.cs @@ -12,14 +12,15 @@ internal class AuthInfo { public AuthInfo(string apiKey, string organizationId = null) { - if (!apiKey.Contains("sk-")) + if (string.IsNullOrWhiteSpace(apiKey) || + !apiKey.Contains("sk-")) { throw new InvalidCredentialException($"{apiKey} must start with 'sk-'"); } this.apiKey = apiKey; - if (organizationId != null) + if (!string.IsNullOrWhiteSpace(organizationId)) { if (!organizationId.Contains("org-")) { diff --git a/OpenAI/Packages/com.openai.unity/Runtime/Images/ImageEditRequest.cs b/OpenAI/Packages/com.openai.unity/Runtime/Images/ImageEditRequest.cs index 5e210bd9..d6e7a897 100644 --- a/OpenAI/Packages/com.openai.unity/Runtime/Images/ImageEditRequest.cs +++ b/OpenAI/Packages/com.openai.unity/Runtime/Images/ImageEditRequest.cs @@ -2,6 +2,7 @@ using System; using System.IO; +using UnityEngine; namespace OpenAI.Images { @@ -31,46 +32,52 @@ public sealed class ImageEditRequest : IDisposable /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. /// public ImageEditRequest(string imagePath, string maskPath, string prompt, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null) + : this( + File.OpenRead(imagePath), + Path.GetFileName(imagePath), + string.IsNullOrWhiteSpace(maskPath) ? null : File.OpenRead(maskPath), + string.IsNullOrWhiteSpace(maskPath) ? null : Path.GetFileName(maskPath), + prompt, + numberOfResults, + size, + user) { - if (!File.Exists(imagePath)) - { - throw new FileNotFoundException($"Could not find the {nameof(imagePath)} file located at {imagePath}"); - } - - Image = File.OpenRead(imagePath); - ImageName = Path.GetFileName(imagePath); - - if (!File.Exists(maskPath)) - { - throw new FileNotFoundException($"Could not find the {nameof(maskPath)} file located at {maskPath}"); - } - - Mask = File.OpenRead(maskPath); - MaskName = Path.GetFileName(maskPath); - - if (prompt.Length > 1000) - { - throw new ArgumentOutOfRangeException(nameof(prompt), "The maximum character length for the prompt is 1000 characters."); - } - - Prompt = prompt; - - if (numberOfResults is > 10 or < 1) - { - throw new ArgumentOutOfRangeException(nameof(numberOfResults), "The number of results must be between 1 and 10"); - } - - Number = numberOfResults; - - Size = size switch - { - ImageSize.Small => "256x256", - ImageSize.Medium => "512x512", - ImageSize.Large => "1024x1024", - _ => throw new ArgumentOutOfRangeException(nameof(size), size, null) - }; + } - User = user; + /// + /// Constructor. + /// + /// + /// The image to edit. Must be a valid PNG file, less than 4MB, and square. + /// If mask is not provided, image must have transparency, which will be used as the mask. + /// + /// + /// An additional image whose fully transparent areas (e.g. where alpha is zero) indicate where image should be edited. + /// Must be a valid PNG file, less than 4MB, and have the same dimensions as image. + /// + /// + /// A text description of the desired image(s). The maximum length is 1000 characters. + /// + /// + /// The number of images to generate. Must be between 1 and 10. + /// + /// + /// The size of the generated images. Must be one of 256x256, 512x512, or 1024x1024. + /// + /// + /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. + /// + public ImageEditRequest(Texture2D texture, Texture2D mask, string prompt, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null) + : this( + new MemoryStream(texture.EncodeToPNG()), + $"{texture.name}.png", + mask != null ? new MemoryStream(mask.EncodeToPNG()) : null, + mask != null ? $"{mask.name}.png" : null, + prompt, + numberOfResults, + size, + user) + { } /// @@ -101,9 +108,25 @@ public ImageEditRequest(string imagePath, string maskPath, string prompt, int nu public ImageEditRequest(Stream image, string imageName, Stream mask, string maskName, string prompt, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null) { Image = image; + + if (string.IsNullOrWhiteSpace(imageName)) + { + imageName = "image.png"; + } + ImageName = imageName; - Mask = mask; - MaskName = maskName; + + if (mask != null) + { + Mask = mask; + + if (string.IsNullOrWhiteSpace(maskName)) + { + maskName = "mask.png"; + } + + MaskName = maskName; + } if (prompt.Length > 1000) { diff --git a/OpenAI/Packages/com.openai.unity/Runtime/Images/ImageVariationRequest.cs b/OpenAI/Packages/com.openai.unity/Runtime/Images/ImageVariationRequest.cs index af579c45..ced76d5a 100644 --- a/OpenAI/Packages/com.openai.unity/Runtime/Images/ImageVariationRequest.cs +++ b/OpenAI/Packages/com.openai.unity/Runtime/Images/ImageVariationRequest.cs @@ -2,6 +2,7 @@ using System; using System.IO; +using UnityEngine; namespace OpenAI.Images { @@ -12,7 +13,6 @@ public sealed class ImageVariationRequest : IDisposable /// /// /// The image to edit. Must be a valid PNG file, less than 4MB, and square. - /// If mask is not provided, image must have transparency, which will be used as the mask. /// /// /// The number of images to generate. Must be between 1 and 10. @@ -24,14 +24,58 @@ public sealed class ImageVariationRequest : IDisposable /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. /// public ImageVariationRequest(string imagePath, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null) + : this(File.OpenRead(imagePath), Path.GetFileName(imagePath), numberOfResults, size, user) { - if (!File.Exists(imagePath)) + } + + /// + /// Constructor. + /// + /// + /// The image to edit. Must be a valid PNG file, less than 4MB, and square. + /// + /// + /// The number of images to generate. Must be between 1 and 10. + /// + /// + /// The size of the generated images. Must be one of 256x256, 512x512, or 1024x1024. + /// + /// + /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. + /// + public ImageVariationRequest(Texture2D texture, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null) + : this(new MemoryStream(texture.EncodeToPNG()), $"{texture.name}.png", numberOfResults, size, user) + { + } + + /// + /// Constructor. + /// + /// + /// The image to edit. Must be a valid PNG file, less than 4MB, and square. + /// + /// + /// The name of the image. + /// + /// + /// The number of images to generate. Must be between 1 and 10. + /// + /// + /// The size of the generated images. Must be one of 256x256, 512x512, or 1024x1024. + /// + /// + /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. + /// + public ImageVariationRequest(Stream image, string imageName, int numberOfResults, ImageSize size, string user) + { + Image = image; + + if (string.IsNullOrWhiteSpace(imageName)) { - throw new FileNotFoundException($"Could not find the {nameof(imagePath)} file located at {imagePath}"); + imageName = "image.png"; } - Image = File.OpenRead(imagePath); - ImageName = Path.GetFileName(imagePath); + ImageName = imageName; if (numberOfResults is > 10 or < 1) { diff --git a/OpenAI/Packages/com.openai.unity/Runtime/Images/ImagesEndpoint.cs b/OpenAI/Packages/com.openai.unity/Runtime/Images/ImagesEndpoint.cs index 456f410f..8e70d380 100644 --- a/OpenAI/Packages/com.openai.unity/Runtime/Images/ImagesEndpoint.cs +++ b/OpenAI/Packages/com.openai.unity/Runtime/Images/ImagesEndpoint.cs @@ -78,6 +78,33 @@ public async Task> GenerateImageAsync(Ima public async Task> CreateImageEditAsync(string image, string mask, string prompt, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null, CancellationToken cancellationToken = default) => await CreateImageEditAsync(new ImageEditRequest(image, mask, prompt, numberOfResults, size, user), cancellationToken); + /// + /// Creates an edited or extended image given an original image and a prompt. + /// + /// + /// The image to edit. Must be a valid PNG file, less than 4MB, and square. + /// If mask is not provided, image must have transparency, which will be used as the mask. + /// + /// + /// An additional image whose fully transparent areas (e.g. where alpha is zero) indicate where image should be edited. + /// Must be a valid PNG file, less than 4MB, and have the same dimensions as image. + /// + /// + /// A text description of the desired image(s). The maximum length is 1000 characters. + /// + /// + /// The number of images to generate. Must be between 1 and 10. + /// + /// + /// The size of the generated images. Must be one of 256x256, 512x512, or 1024x1024. + /// + /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. + /// Optional, . + /// A dictionary of file urls and the preloaded that were downloaded. + /// + public async Task> CreateImageEditAsync(Texture2D image, Texture2D mask, string prompt, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null, CancellationToken cancellationToken = default) + => await CreateImageEditAsync(new ImageEditRequest(image, mask, prompt, numberOfResults, size, user), cancellationToken); + /// /// Creates an edited or extended image given an original image and a prompt. /// @@ -91,9 +118,14 @@ public async Task> CreateImageEditAsync(I using var imageData = new MemoryStream(); await request.Image.CopyToAsync(imageData, cancellationToken); content.Add(new ByteArrayContent(imageData.ToArray()), "image", request.ImageName); - using var maskData = new MemoryStream(); - await request.Mask.CopyToAsync(maskData, cancellationToken); - content.Add(new ByteArrayContent(maskData.ToArray()), "mask", request.MaskName); + + if (request.Mask != null) + { + using var maskData = new MemoryStream(); + await request.Mask.CopyToAsync(maskData, cancellationToken); + content.Add(new ByteArrayContent(maskData.ToArray()), "mask", request.MaskName); + } + content.Add(new StringContent(request.Prompt), "prompt"); content.Add(new StringContent(request.Number.ToString()), "n"); content.Add(new StringContent(request.Size), "size"); @@ -114,7 +146,6 @@ public async Task> CreateImageEditAsync(I /// /// /// The image to edit. Must be a valid PNG file, less than 4MB, and square. - /// If mask is not provided, image must have transparency, which will be used as the mask. /// /// /// The number of images to generate. Must be between 1 and 10. @@ -131,6 +162,27 @@ public async Task> CreateImageEditAsync(I public async Task> CreateImageVariationAsync(string imagePath, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null, CancellationToken cancellationToken = default) => await CreateImageVariationAsync(new ImageVariationRequest(imagePath, numberOfResults, size, user), cancellationToken); + /// + /// Creates a variation of a given image. + /// + /// + /// The image to edit. Must be a valid PNG file, less than 4MB, and square. + /// + /// + /// The number of images to generate. Must be between 1 and 10. + /// + /// + /// The size of the generated images. Must be one of 256x256, 512x512, or 1024x1024. + /// + /// + /// A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. + /// + /// Optional, . + /// A dictionary of file urls and the preloaded that were downloaded. + /// + public async Task> CreateImageVariationAsync(Texture2D imagePath, int numberOfResults = 1, ImageSize size = ImageSize.Large, string user = null, CancellationToken cancellationToken = default) + => await CreateImageVariationAsync(new ImageVariationRequest(imagePath, numberOfResults, size, user), cancellationToken); + /// /// Creates a variation of a given image. /// diff --git a/OpenAI/Packages/com.openai.unity/Runtime/OpenAIAuthentication.cs b/OpenAI/Packages/com.openai.unity/Runtime/OpenAIAuthentication.cs index 8d30ce3d..cd5c9c13 100644 --- a/OpenAI/Packages/com.openai.unity/Runtime/OpenAIAuthentication.cs +++ b/OpenAI/Packages/com.openai.unity/Runtime/OpenAIAuthentication.cs @@ -16,6 +16,7 @@ public sealed class OpenAIAuthentication private const string OPENAI_API_KEY = "OPENAI_API_KEY"; private const string OPENAI_SECRET_KEY = "OPENAI_SECRET_KEY"; private const string TEST_OPENAI_SECRET_KEY = "TEST_OPENAI_SECRET_KEY"; + private const string OPENAI_ORGANIZATION_ID = "OPENAI_ORGANIZATION_ID"; private const string OPEN_AI_ORGANIZATION_ID = "OPEN_AI_ORGANIZATION_ID"; private const string ORGANIZATION = "ORGANIZATION"; @@ -126,6 +127,11 @@ public static OpenAIAuthentication LoadFromEnv(string organizationId = null) organizationId = Environment.GetEnvironmentVariable(OPEN_AI_ORGANIZATION_ID); } + if (string.IsNullOrWhiteSpace(organizationId)) + { + organizationId = Environment.GetEnvironmentVariable(OPENAI_ORGANIZATION_ID); + } + return string.IsNullOrEmpty(apiKey) ? null : new OpenAIAuthentication(apiKey, organizationId); } diff --git a/OpenAI/Packages/com.openai.unity/Tests/Images/image_edit_mask.png.meta b/OpenAI/Packages/com.openai.unity/Tests/Images/image_edit_mask.png.meta index 2ff15135..4ecbd9c7 100644 --- a/OpenAI/Packages/com.openai.unity/Tests/Images/image_edit_mask.png.meta +++ b/OpenAI/Packages/com.openai.unity/Tests/Images/image_edit_mask.png.meta @@ -20,7 +20,7 @@ TextureImporter: externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 - isReadable: 0 + isReadable: 1 streamingMipmaps: 0 streamingMipmapsPriority: 0 vTOnly: 0 @@ -70,7 +70,7 @@ TextureImporter: maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 - textureCompression: 1 + textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 diff --git a/OpenAI/Packages/com.openai.unity/Tests/Images/image_edit_original.png.meta b/OpenAI/Packages/com.openai.unity/Tests/Images/image_edit_original.png.meta index 8611d7b3..c28014fe 100644 --- a/OpenAI/Packages/com.openai.unity/Tests/Images/image_edit_original.png.meta +++ b/OpenAI/Packages/com.openai.unity/Tests/Images/image_edit_original.png.meta @@ -20,7 +20,7 @@ TextureImporter: externalNormalMap: 0 heightScale: 0.25 normalMapFilter: 0 - isReadable: 0 + isReadable: 1 streamingMipmaps: 0 streamingMipmapsPriority: 0 vTOnly: 0 @@ -70,7 +70,7 @@ TextureImporter: maxTextureSize: 2048 resizeAlgorithm: 0 textureFormat: -1 - textureCompression: 1 + textureCompression: 0 compressionQuality: 50 crunchedCompression: 0 allowsAlphaSplitting: 0 diff --git a/OpenAI/Packages/com.openai.unity/Tests/TestFixture_04_Images.cs b/OpenAI/Packages/com.openai.unity/Tests/TestFixture_04_Images.cs index 303270c6..3c2897b0 100644 --- a/OpenAI/Packages/com.openai.unity/Tests/TestFixture_04_Images.cs +++ b/OpenAI/Packages/com.openai.unity/Tests/TestFixture_04_Images.cs @@ -25,16 +25,16 @@ public IEnumerator Test_1_GenerateImages() Assert.IsNotNull(results); Assert.NotZero(results.Count); - foreach (var result in results) + foreach (var (path, texture) in results) { - Debug.Log(result.Key); - Assert.IsNotNull(result.Value); + Debug.Log(path); + Assert.IsNotNull(texture); } }); } [UnityTest] - public IEnumerator Test_2_GenerateImageEdits() + public IEnumerator Test_2_CreateImageEdit_Path() { yield return AwaitTestUtilities.Await(async () => { @@ -47,16 +47,62 @@ public IEnumerator Test_2_GenerateImageEdits() Assert.IsNotNull(results); Assert.NotZero(results.Count); - foreach (var result in results) + foreach (var (path, texture) in results) { - Debug.Log(result.Key); - Assert.IsNotNull(result.Value); + Debug.Log(path); + Assert.IsNotNull(texture); } }); } [UnityTest] - public IEnumerator Test_3_GenerateImageVariations() + public IEnumerator Test_3_CreateImageEdit_Texture() + { + yield return AwaitTestUtilities.Await(async () => + { + var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); + Assert.IsNotNull(api.ImagesEndPoint); + var imageAssetPath = AssetDatabase.GUIDToAssetPath("230fd778637d3d84d81355c8c13b1999"); + var image = AssetDatabase.LoadAssetAtPath(imageAssetPath); + var maskAssetPath = AssetDatabase.GUIDToAssetPath("0be6be2fad590cc47930495d2ca37dd6"); + var mask = AssetDatabase.LoadAssetAtPath(maskAssetPath); + var results = await api.ImagesEndPoint.CreateImageEditAsync(image, mask, "A sunlit indoor lounge area with a pool containing a flamingo", 1, ImageSize.Small); + + Assert.IsNotNull(results); + Assert.NotZero(results.Count); + + foreach (var (path, texture) in results) + { + Debug.Log(path); + Assert.IsNotNull(texture); + } + }); + } + + [UnityTest] + public IEnumerator Test_4_CreateImageEdit_MaskAsTransparency() + { + yield return AwaitTestUtilities.Await(async () => + { + var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); + Assert.IsNotNull(api.ImagesEndPoint); + var maskAssetPath = AssetDatabase.GUIDToAssetPath("0be6be2fad590cc47930495d2ca37dd6"); + var mask = AssetDatabase.LoadAssetAtPath(maskAssetPath); + var results = await api.ImagesEndPoint.CreateImageEditAsync(mask, null, "A sunlit indoor lounge area with a pool containing a flamingo", 1, ImageSize.Small); + + Assert.IsNotNull(results); + Assert.NotZero(results.Count); + + foreach (var (path, texture) in results) + { + Debug.Log(path); + Assert.IsNotNull(texture); + } + }); + } + + [UnityTest] + public IEnumerator Test_5_CreateImageVariation_Path() { yield return AwaitTestUtilities.Await(async () => { @@ -68,10 +114,32 @@ public IEnumerator Test_3_GenerateImageVariations() Assert.IsNotNull(results); Assert.NotZero(results.Count); - foreach (var result in results) + foreach (var (path, texture) in results) + { + Debug.Log(path); + Assert.IsNotNull(texture); + } + }); + } + + [UnityTest] + public IEnumerator Test_6_CreateImageVariation_Texture() + { + yield return AwaitTestUtilities.Await(async () => + { + var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); + Assert.IsNotNull(api.ImagesEndPoint); + var imageAssetPath = AssetDatabase.GUIDToAssetPath("230fd778637d3d84d81355c8c13b1999"); + var image = AssetDatabase.LoadAssetAtPath(imageAssetPath); + var results = await api.ImagesEndPoint.CreateImageVariationAsync(image, 1, ImageSize.Small); + + Assert.IsNotNull(results); + Assert.NotZero(results.Count); + + foreach (var (path, texture) in results) { - Debug.Log(result.Key); - Assert.IsNotNull(result.Value); + Debug.Log(path); + Assert.IsNotNull(texture); } }); } diff --git a/OpenAI/Packages/com.openai.unity/package.json b/OpenAI/Packages/com.openai.unity/package.json index f6d82d3e..ae2ecbb5 100644 --- a/OpenAI/Packages/com.openai.unity/package.json +++ b/OpenAI/Packages/com.openai.unity/package.json @@ -3,7 +3,7 @@ "displayName": "OpenAI", "description": "A OpenAI package for the Unity Game Engine to use GPT-3 and Dall-E though their RESTful API (currently in beta).\n\nIndependently developed, this is not an official library and I am not affiliated with OpenAI.\n\nAn OpenAI API account is required.", "keywords": [], - "version": "2.2.3", + "version": "2.2.4", "unity": "2021.3", "documentationUrl": "https://github.com/RageAgainstThePixel/com.openai.unity#documentation", "changelogUrl": "https://github.com/RageAgainstThePixel/com.openai.unity/releases", @@ -18,7 +18,7 @@ }, "dependencies": { "com.unity.nuget.newtonsoft-json": "3.0.2", - "com.utilities.rest": "1.1.0" + "com.utilities.rest": "1.2.2" }, "publishConfig": { "registry": "https://package.openupm.com" diff --git a/README.md b/README.md index 28c7504d..f1386fdd 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ The recommended installation method is though the unity package manager and [Ope - `com.openai` - `com.utilities` -![scoped-registries](https://github.com/RageAgainstThePixel/com.openai.unity/raw/main/OpenAI/Packages/com.openai.unity/Documentation~/images/package-manager-scopes.png) +![scoped-registries](OpenAI/Packages/com.openai.unity/Documentation~/images/package-manager-scopes.png) - Open the Unity Package Manager window - Change the Registry from Unity to `My Registries` @@ -88,13 +88,13 @@ There are 4 ways to provide your API keys, in order of precedence: #### Pass keys directly with constructor ```csharp -var api = new OpenAIClient("sk-mykeyhere"); +var api = new OpenAIClient("sk-apiKey"); ``` Or create a `OpenAIAuthentication` object manually ```csharp -var api = new OpenAIClient(new OpenAIAuthentication("sk-secretkey")); +var api = new OpenAIClient(new OpenAIAuthentication("sk-apiKey", "org-yourOrganizationId")); ``` #### Unity Scriptable Object @@ -103,7 +103,7 @@ You can save the key directly into a scriptable object that is located in the `A You can create a new one by using the context menu of the project pane and creating a new `OpenAIConfigurationSettings` scriptable object. -![Create new OpenAIConfigurationSettings](https://github.com/RageAgainstThePixel/com.openai.unity/raw/main/OpenAI/Packages/com.openai.unity/Documentation~/images/create-scriptable-object.png) +![Create new OpenAIConfigurationSettings](images/create-scriptable-object.png) #### Load key from configuration file @@ -140,19 +140,12 @@ var api = new OpenAIClient(OpenAIAuthentication.LoadFromDirectory("your/path/to/ Use your system's environment variables specify an api key and organization to use. - Use `OPENAI_API_KEY` for your api key. -- Use `OPEN_AI_ORGANIZATION_ID` to specify an organization. +- Use `OPENAI_ORGANIZATION_ID` to specify an organization. ```csharp var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv()); ``` -or - -```csharp -var api = new OpenAIClient(OpenAIAuthentication.LoadFromEnv("org-yourOrganizationId")); -``` - - ### [Models](https://beta.openai.com/docs/api-reference/models) List and describe the various models available in the API. You can refer to the [Models documentation](https://beta.openai.com/docs/models) to understand what models are available and the differences between them. @@ -280,12 +273,12 @@ Creates an image given a prompt. var api = new OpenAIClient(); var results = await api.ImagesEndPoint.GenerateImageAsync("A house riding a velociraptor", 1, ImageSize.Small); -foreach (var result in results) +foreach (var (path, texture) in results) { - Debug.Log(result.Key); - // result.Key == file://path/to/image.png - Assert.IsNotNull(result.Value); - // result.Value == The preloaded Texture2D + Debug.Log(path); + // path == file://path/to/image.png + Assert.IsNotNull(texture); + // texture == The preloaded Texture2D } ``` @@ -297,12 +290,12 @@ Creates an edited or extended image given an original image and a prompt. var api = new OpenAIClient(); var results = await api.ImagesEndPoint.CreateImageEditAsync(Path.GetFullPath(imageAssetPath), Path.GetFullPath(maskAssetPath), "A sunlit indoor lounge area with a pool containing a flamingo", 1, ImageSize.Small); -foreach (var result in results) +foreach (var (path, texture) in results) { - Debug.Log(result.Key); - // result.Key == file://path/to/image.png - Assert.IsNotNull(result.Value); - // result.Value == Texture2D + Debug.Log(path); + // path == file://path/to/image.png + Assert.IsNotNull(texture); + // texture == The preloaded Texture2D } ``` @@ -314,12 +307,12 @@ Creates a variation of a given image. var api = new OpenAIClient(); var results = await api.ImagesEndPoint.CreateImageVariationAsync(Path.GetFullPath(imageAssetPath), 1, ImageSize.Small); -foreach (var result in results) +foreach (var (path, texture) in results) { - Debug.Log(result.Key); - // result.Key == file://path/to/image.png - Assert.IsNotNull(result.Value); - // result.Value == Texture2D + Debug.Log(path); + // path == file://path/to/image.png + Assert.IsNotNull(texture); + // texture == The preloaded Texture2D } ```