Skip to content

Commit

Permalink
Merge pull request #3 from Uralstech/preview
Browse files Browse the repository at this point in the history
Merge preview into main for UGemini v1.1.0-preview.3
  • Loading branch information
Uralstech committed Jul 3, 2024
2 parents 9164dbe + 150f655 commit 1d734ed
Show file tree
Hide file tree
Showing 68 changed files with 5,685 additions and 64 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,19 @@ Follow the steps detailed in the OpenUPM installation method and only install th

- [ ] `cachedContents` endpoint :test_tube:
- [ ] `corpora` endpoint :test_tube:
- [ ] `files` endpoint :test_tube: :construction:
- [ ] `media` endpoint :test_tube: :construction:
- [x] `files` endpoint :test_tube:
- [x] `delete` method
- [x] `get` method
- [x] `list` method

- [x] `media` endpoint :test_tube:
- [x] `upload` method :construction:

- [ ] `tunedModels` endpoint
- [ ] `operations` endpoint :construction:

:warning: - Not all methods/features are supported<br/>
:construction: - The feature is being worked on<br/>
:construction: - The feature is being worked on and is unstable<br/>
:test_tube: - Using the v1beta API

### Documentation
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.ComponentModel;
using Uralstech.UGemini.Tools.Declaration;

Expand All @@ -9,7 +10,7 @@ namespace Uralstech.UGemini.Chat
/// Request to generate a response from the model.
/// </summary>
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public class GeminiChatRequest
public class GeminiChatRequest : IGeminiPostRequest
{
/// <summary>
/// The content of the current conversation with the model.
Expand Down Expand Up @@ -44,7 +45,7 @@ public class GeminiChatRequest
/// A list of unique <see cref="GeminiSafetySettings"/> instances for blocking unsafe content.
/// </summary>
/// <remarks>
/// This will be enforced on <see cref="GeminiChatRequest.Contents"/> and <see cref="ChatResponse.GeminiChatResponse.Candidates"/>.<br/>
/// This will be enforced on <see cref="Contents"/> and <see cref="GeminiChatResponse.Candidates"/>.<br/>
/// There should not be more than one setting for each <see cref="GeminiSafetyHarmCategory"/> type. The API will block any<br/>
/// contents and responses that fail to meet the thresholds set by these settings. This list overrides the default<br/>
/// settings for each <see cref="GeminiSafetyHarmCategory"/> specified in the <see cref="SafetySettings"/>. If there is<br/>
Expand Down Expand Up @@ -76,8 +77,50 @@ public class GeminiChatRequest
/// </summary>
/// <remarks>
/// Note: only used in explicit caching, where users can have control over caching (e.g. what content to cache) and enjoy guaranteed cost savings.
/// <br/><br/>
/// Only available in the beta API.
/// </remarks>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore), DefaultValue(null)]
public string CachedContent = null;

/// <summary>
/// The model to use.
/// </summary>
[JsonIgnore]
public string Model;

/// <summary>
/// The API version to use.
/// </summary>
[JsonIgnore]
public string ApiVersion;

/// <inheritdoc/>
[JsonIgnore]
public string ContentType => GeminiContentType.ApplicationJSON.MimeType();

/// <inheritdoc/>
[JsonIgnore]
public string EndpointUri => $"https://generativelanguage.googleapis.com/{ApiVersion}/models/{Model}:generateContent";

/// <summary>
/// Creates a new <see cref="GeminiChatRequest"/>.
/// </summary>
/// <param name="model">The model to use.</param>
/// <param name="useBetaApi">Should the request use the Beta API?</param>
public GeminiChatRequest(string model = GeminiManager.Gemini1_5Flash, bool useBetaApi = false)
{
Model = model;
ApiVersion = useBetaApi ? "v1beta" : "v1";
}

[Obsolete("Please use a different constructor as this constructor is only for the deprecated GeminiManager.Compute method.")]
public GeminiChatRequest() { }

/// <inheritdoc/>
public string GetUtf8EncodedData()
{
return JsonConvert.SerializeObject(this);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System;
using System.Reflection;
using System.Runtime.Serialization;

namespace Uralstech.UGemini
{
/// <summary>
/// Extensions for <see cref="Enum"/> type objects.
/// </summary>
public static class EnumExtensions
{
/// <summary>
/// Converts a <see cref="GeminiContentType"/> to its <see href="https://www.iana.org/assignments/media-types/media-types.xhtml">MIME type</see>.
/// </summary>
/// <param name="enumValue">The <see cref="GeminiContentType"/> value.</param>
/// <returns>The MIME type as a string.</returns>
/// <exception cref="NotImplementedException">Thrown if the MIME type of the enum value could not be found.</exception>
public static string MimeType(this GeminiContentType enumValue)
{
Type type = typeof(GeminiContentType);
MemberInfo[] memberInfo = type.GetMember(enumValue.ToString());

if (memberInfo != null && memberInfo.Length > 0)
{
object[] attributes = memberInfo[0].GetCustomAttributes(typeof(EnumMemberAttribute), false);

if (attributes != null && attributes.Length > 0)
return ((EnumMemberAttribute)attributes[0]).Value;
}

// Throw error if no EnumMember attribute is found.
throw new NotImplementedException($"No {nameof(EnumMemberAttribute)} found for content type \"{enumValue}\"!");
}

/// <summary>
/// Converts a <see cref="string"/> MIME type to a <see cref="GeminiContentType"/>.
/// </summary>
/// <param name="mimeType">The MIME type string.</param>
/// <returns>The <see cref="GeminiContentType"/> equivalent.</returns>
/// <exception cref="NotImplementedException">Thrown if <see cref="GeminiContentType"/> does not have an equivalent MIME type to <paramref name="mimeType"/>.</exception>
public static GeminiContentType ContentType(this string mimeType)
{
Type type = typeof(GeminiContentType);
foreach (string name in Enum.GetNames(type))
{
MemberInfo[] memberInfo = type.GetMember(name);
if (memberInfo != null && memberInfo.Length > 0)
{
object[] attributes = memberInfo[0].GetCustomAttributes(typeof(EnumMemberAttribute), false);
if (attributes != null && attributes.Length > 0 && ((EnumMemberAttribute)attributes[0]).Value == mimeType)
return (GeminiContentType)Enum.Parse(type, name);
}
}

// Throw error if no enum value is found.
throw new NotImplementedException($"No {nameof(GeminiContentType)} found for MIME type \"{mimeType}\"!");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Newtonsoft.Json.Serialization;
using System.ComponentModel;
using UnityEngine;
using Uralstech.UGemini.FileAPI;
using Uralstech.UGemini.Tools;

namespace Uralstech.UGemini
Expand Down Expand Up @@ -101,6 +102,36 @@ public static GeminiContent GetContent(string message, AudioClip audio, GeminiRo
}
#endif

/// <summary>
/// Creates a new <see cref="GeminiContent"/> from a role, message and <see cref="GeminiFile"/>.
/// </summary>
/// <param name="role">The role of the content creator.</param>
/// <param name="message">The message.</param>
/// <param name="file">The <see cref="GeminiFile"/>.</param>
/// <returns>A new <see cref="GeminiContent"/> object.</returns>
public static GeminiContent GetContent(string message, GeminiFile file, GeminiRole role = GeminiRole.Unspecified)
{
return new GeminiContent
{
Role = role,
Parts = new[]
{
new GeminiContentPart
{
Text = message,
},
new GeminiContentPart
{
FileData = new GeminiFileData
{
MimeType = file.MimeType,
FileUri = file.Uri,
},
}
}
};
}

/// <summary>
/// Creates a new <see cref="GeminiContent"/> from a <see cref="GeminiFunctionCall"/>.
/// </summary>
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using UnityEngine;

namespace Uralstech.UGemini
Expand All @@ -16,6 +15,11 @@ public class GeminiContentBlob
/// <summary>
/// The type of the data.
/// </summary>
/// <remarks>
/// You can use <see cref="EnumExtensions.ContentType(string)"/> to convert <see cref="string"/>
/// values to their <see cref="GeminiContentType"/> equivalents, like:
/// <c>"image/png".ContentType()</c>
/// </remarks>
public GeminiContentType MimeType;

/// <summary>
Expand All @@ -38,7 +42,7 @@ public static GeminiContentBlob GetContentBlob(AudioClip audio)
return new GeminiContentBlob()
{
MimeType = GeminiContentType.AudioWAV,
Data = Convert.ToBase64String(Utilities.Encoding.Wav.AudioClipExtensions.EncodeToWav(audio))
Data = audio.ToBase64WAV()
};
}
#endif
Expand All @@ -55,12 +59,12 @@ public static GeminiContentBlob GetContentBlob(Texture2D image, bool useJPEG = f
? new GeminiContentBlob()
{
MimeType = GeminiContentType.ImageJPEG,
Data = Convert.ToBase64String(image.EncodeToJPG())
Data = image.ToBase64JPEG()
}
: new GeminiContentBlob()
{
MimeType = GeminiContentType.ImagePNG,
Data = Convert.ToBase64String(image.EncodeToPNG())
Data = image.ToBase64PNG()
};
}
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ public class GeminiContentPart
/// <summary>
/// URI based data.
/// </summary>
/// <remarks>
/// Only available in the beta API.
/// </remarks>
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore), DefaultValue(null)]
public GeminiFileData FileData = null;
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,95 @@ public enum GeminiContentType
/// </summary>
[EnumMember(Value = "video/3gpp")]
Video3GPP,

/// <summary>
/// (File API) Plain text.
/// </summary>
[EnumMember(Value = "text/plain")]
TextPlain,

/// <summary>
/// (File API) HTML text.
/// </summary>
[EnumMember(Value = "text/html")]
TextHTML,

/// <summary>
/// (File API) CSS text.
/// </summary>
[EnumMember(Value = "text/css")]
TextCSS,

/// <summary>
/// (File API) JavaScript text.
/// </summary>
[EnumMember(Value = "text/javascript")]
TextJavaScript,

/// <summary>
/// (File API) TypeScript text.
/// </summary>
[EnumMember(Value = "text/x-typescript")]
TextXTypeScript,

/// <summary>
/// (File API) CSV text.
/// </summary>
[EnumMember(Value = "text/csv")]
TextCSV,

/// <summary>
/// (File API) Markdown text.
/// </summary>
[EnumMember(Value = "text/markdown")]
TextMarkdown,

/// <summary>
/// (File API) Python text.
/// </summary>
[EnumMember(Value = "text/x-python")]
TextXPython,

/// <summary>
/// (File API) XML text.
/// </summary>
[EnumMember(Value = "text/xml")]
TextXML,

/// <summary>
/// (File API) RTF text.
/// </summary>
[EnumMember(Value = "text/rtf")]
TextRTF,

/// <summary>
/// (File API) Application JavaScript content.
/// </summary>
[EnumMember(Value = "application/x-javascript")]
ApplicationXJavaScript,

/// <summary>
/// (File API) Application TypeScript content.
/// </summary>
[EnumMember(Value = "application/x-typescript")]
ApplicationXTypeScript,

/// <summary>
/// (File API) Application Python content.
/// </summary>
[EnumMember(Value = "application/x-python-code")]
ApplicationXPython,

/// <summary>
/// (File API) Application JSON content.
/// </summary>
[EnumMember(Value = "application/json")]
ApplicationJSON,

/// <summary>
/// (File API) Application RTF content.
/// </summary>
[EnumMember(Value = "application/rtf")]
ApplicationRTF,
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 1d734ed

Please sign in to comment.