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

Adds support for the Assistants API #192

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
18 changes: 17 additions & 1 deletion OpenAI_API/ApiResultBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ abstract public class ApiResultBase

/// The time when the result was generated
[JsonIgnore]
public DateTime? Created => CreatedUnixTime.HasValue ? (DateTime?)(DateTimeOffset.FromUnixTimeSeconds(CreatedUnixTime.Value).DateTime) : null;
public DateTime? Created => ConvertUnixTime(CreatedUnixTime);

/// <summary>
/// The time when the result was generated in unix epoch format
Expand Down Expand Up @@ -55,5 +55,21 @@ abstract public class ApiResultBase
/// </summary>
[JsonIgnore]
public string OpenaiVersion { get; internal set; }

/// <summary>
/// Converts Unix time.
/// </summary>
///
/// <param name="unixTime">
/// The Unix time.
/// </param>
///
/// <returns>
/// The converted Unix time.
/// </returns>
protected static DateTime? ConvertUnixTime(long? unixTime)
{
return unixTime.HasValue ? (DateTime?) DateTimeOffset.FromUnixTimeSeconds(unixTime.Value).DateTime : null;
}
}
}
17 changes: 17 additions & 0 deletions OpenAI_API/Assistants/AssistantFileRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Newtonsoft.Json;

namespace OpenAI_API.Assistants
{
/// <summary>
/// Represents a request to create an assistant file.
/// </summary>
public class AssistantFileRequest
{
/// <summary>
/// A file ID (with <c>purpose="assistants"</c>) that the assistant should use. Useful for tools like
/// <c>retrieval</c> and <c>code_interpreter</c> that can access files.
/// </summary>
[JsonProperty("file_id")]
public string FileId { get; set; }
}
}
35 changes: 35 additions & 0 deletions OpenAI_API/Assistants/AssistantFileResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using Newtonsoft.Json;

namespace OpenAI_API.Assistants
{
/// <summary>
/// Represents a file that is attached to an assistant.
/// </summary>
public class AssistantFileResult : ApiResultBase
{
/// <summary>
/// The identifier, which can be referenced in API endpoints.
/// </summary>
[JsonProperty("id")]
public string Id { get; set; }

/// <summary>
/// The Unix timestamp (in seconds) for when the assistant file was created.
/// </summary>
[JsonProperty("created_at")]
public long? CreatedAtUnixTime { get; set; }

/// <summary>
/// The timestamp for when the assistant file was created.
/// </summary>
[JsonIgnore]
public DateTime? CreatedAt => ConvertUnixTime(CreatedAtUnixTime);

/// <summary>
/// The ID of the assistant this file is attached to.
/// </summary>
[JsonProperty("assistant_id")]
public string AssistantId { get; set; }
}
}
52 changes: 52 additions & 0 deletions OpenAI_API/Assistants/AssistantRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using OpenAI_API.Common;

namespace OpenAI_API.Assistants
{
/// <summary>
/// Represents a request to create an assistant.
/// </summary>
public class AssistantRequest : MetadataRequest
{
/// <summary>
/// The ID of the model to use.
/// </summary>
[JsonProperty("model")]
public string Model { get; set; }

/// <summary>
/// The name of the assistant. The maximum length is 256 characters.
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }

/// <summary>
/// The description of the assistant. The maximum length is 512 characters.
/// </summary>
[JsonProperty("description")]
public string Description { get; set; }

/// <summary>
/// The system instructions that the assistant uses. The maximum length is 32768 characters.
/// </summary>
[JsonProperty("instructions")]
public string Instructions { get; set; }

/// <summary>
/// A list of tools enabled on the assistant. There can be a maximum of 128 tools per assistant. Tools can be
/// be of types <b>code_interpreter</b>, <b>retrieval</b> or <b>function</b>.
/// </summary>
[JsonProperty("tools")]
public IList<AssistantTool> Tools { get; set; } = Array.Empty<AssistantTool>();

/// <summary>
/// A list of file IDs attached to the assistant. This can be useful for storing additional information about
/// the object in a structured format. Keys can be a maximum of 64 characters long and values can be a maximum
/// of 512 characters long.
/// </summary>
[JsonProperty("file_ids")]
public IList<string> FileIds { get; set; } = Array.Empty<string>();
}
}
70 changes: 70 additions & 0 deletions OpenAI_API/Assistants/AssistantResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace OpenAI_API.Assistants
{
/// <summary>
/// Represents an assistant that can call the model and use tools.
/// </summary>
public class AssistantResult : ApiResultBase
{
/// <summary>
/// The identifier, which can be referenced in API endpoints.
/// </summary>
[JsonProperty("id")]
public string Id { get; set; }

/// <summary>
/// The Unix timestamp (in seconds) for when the assistant was created.
/// </summary>
[JsonProperty("created_at")]
public long? CreatedAtUnixTime { get; set; }

/// <summary>
/// The timestamp for when the assistant was created.
/// </summary>
[JsonIgnore]
public DateTime? CreatedAt => ConvertUnixTime(CreatedAtUnixTime);

/// <summary>
/// The name of the assistant. The maximum length is 256 characters.
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }

/// <summary>
/// The description of the assistant. The maximum length is 512 characters.
/// </summary>
[JsonProperty("description")]
public string Description { get; set; }

/// <summary>
/// The system instructions that the assistant uses. The maximum length is 32768 characters.
/// </summary>
[JsonProperty("instructions")]
public string Instructions { get; set; }

/// <summary>
/// A list of tools enabled on the assistant. There can be a maximum of 128 tools per assistant. Tools can be of
/// types <c>code_interpreter</c>, <c>retrieval</c> or <c>function</c>.
/// </summary>
[JsonProperty("tools")]
public IReadOnlyList<AssistantTool> Tools { get; set; }

/// <summary>
/// A list of file IDs attached to this assistant. There can be a maximum of 20 files attached to an assistant.
/// Files are ordered by their creation date in ascending order.
/// </summary>
[JsonProperty("file_ids")]
public IReadOnlyList<string> FileIds { get; set; }

/// <summary>
/// Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional
/// information about the object in a structured format. Keys can be a maximum of 64 characters long and values
/// can be a maximum of 512 characters long.
/// </summary>
[JsonProperty("metadata")]
public IReadOnlyDictionary<string, string> Metadata { get; set; }
}
}
65 changes: 65 additions & 0 deletions OpenAI_API/Assistants/AssistantTool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;

namespace OpenAI_API.Assistants
{
/// <summary>
/// Represents a tool that an assistant can use.
/// </summary>
public class AssistantTool
{
/// <summary>
/// The type of tool being defined.
/// </summary>
[JsonProperty("type")]
[JsonConverter(typeof(StringEnumConverter))]
public AssistantToolType Type { get; set; }

/// <summary>
/// The function of the tool being defined. Only present if <see cref="Type"/> is <see cref="AssistantToolType.Function"/>.
/// </summary>
[JsonProperty("function")]
public AssistantToolFunction Function { get; set; }
}

/// <summary>
/// Represents a function of a tool that an assistant can use.
/// </summary>
public class AssistantToolFunction
{
/// <summary>
/// The name of the function to be called. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a
/// minimum length of 64.
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }

/// <summary>
/// A description of what the function does. Used by the model to choose when and how to call the function.
/// </summary>
[JsonProperty("description")]
public string Description { get; set; }

/// <summary>
/// The parameters the functions accepts, described as a JSON Schema object. See the guide for examples, and the
/// JSON Schema reference for documentation about the format.
/// </summary>
/// <remarks>
/// Omitting parameters defines a function with an empty parameter list.
/// </remarks>
[JsonProperty("parameters")]
public JObject Parameters { get; set; }
}

/// <summary>
/// Enumerates the types of assistant tools.
/// </summary>
public enum AssistantToolType
{
[EnumMember(Value = "code_interpreter")] CodeInterpreter,
[EnumMember(Value = "retrieval")] Retrieval,
[EnumMember(Value = "function")] Function
}
}
107 changes: 107 additions & 0 deletions OpenAI_API/Assistants/AssistantsEndpoint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using System.Threading.Tasks;
using Newtonsoft.Json;
using OpenAI_API.Common;

namespace OpenAI_API.Assistants
{
/// <summary>
/// The endpoint for the Assistants API.
/// </summary>
public class AssistantsEndpoint : EndpointBase, IAssistantsEndpoint
{
/// <summary>
/// The name of the endpoint, which is the final path segment in the API URL.
/// </summary>
protected override string Endpoint => "assistants";

/// <summary>
/// Constructs a new <see cref="AssistantsEndpoint"/>.
/// </summary>
///
/// <param name="api">
/// The <see cref="OpenAIAPI"/> instance to use for making requests.
/// </param>
public AssistantsEndpoint(OpenAIAPI api) : base(api) { }

/// <inheritdoc />
public async Task<AssistantResult> CreateAssistant(AssistantRequest request)
{
return await HttpPost<AssistantResult>(Url, request);
}

/// <inheritdoc />
public async Task<AssistantFileResult> CreateAssistantFile(string assistantId, AssistantFileRequest request)
{
var url = $"{Url}/{assistantId}/files";

return await HttpPost<AssistantFileResult>(url, request);
}

/// <inheritdoc />
public async Task<ResultsList<AssistantResult>> ListAssistants(QueryParams queryParams = null)
{
queryParams ??= new QueryParams();

var url = $"{Url}{queryParams}";

var content = await HttpGetContent(url);

return JsonConvert.DeserializeObject<ResultsList<AssistantResult>>(content);
}

/// <inheritdoc />
public async Task<ResultsList<AssistantFileResult>> ListAssistantFiles(
string assistantId,
QueryParams queryParams = null
)
{
queryParams ??= new QueryParams();

var url = $"{Url}/{assistantId}/files{queryParams}";

var content = await HttpGetContent(url);

return JsonConvert.DeserializeObject<ResultsList<AssistantFileResult>>(content);
}

/// <inheritdoc />
public Task<AssistantResult> RetrieveAssistant(string assistantId)
{
var url = $"{Url}/{assistantId}";

return HttpGet<AssistantResult>(url);
}

/// <inheritdoc />
public Task<AssistantFileResult> RetrieveAssistantFile(string assistantId, string fileId)
{
var url = $"{Url}/{assistantId}/files/{fileId}";

return HttpGet<AssistantFileResult>(url);
}

/// <inheritdoc />
public Task<AssistantResult> ModifyAssistant(string assistantId, AssistantRequest request)
{
var url = $"{Url}/{assistantId}";

return HttpPost<AssistantResult>(url, request);
}

/// <inheritdoc />
public Task<DeletionStatus> DeleteAssistant(string assistantId)
{
var url = $"{Url}/{assistantId}";

return HttpDelete<DeletionStatus>(url);
}

/// <inheritdoc />
public Task<DeletionStatus> DeleteAssistantFile(string assistantId, string fileId)
{
var url = $"{Url}/{assistantId}/files/{fileId}";

return HttpDelete<DeletionStatus>(url);
}
}
}
Loading