diff --git a/OpenAI_API/ApiResultBase.cs b/OpenAI_API/ApiResultBase.cs
index 4bcba5f..fcba3b5 100644
--- a/OpenAI_API/ApiResultBase.cs
+++ b/OpenAI_API/ApiResultBase.cs
@@ -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);
///
/// The time when the result was generated in unix epoch format
@@ -55,5 +55,21 @@ abstract public class ApiResultBase
///
[JsonIgnore]
public string OpenaiVersion { get; internal set; }
+
+ ///
+ /// Converts Unix time.
+ ///
+ ///
+ ///
+ /// The Unix time.
+ ///
+ ///
+ ///
+ /// The converted Unix time.
+ ///
+ protected static DateTime? ConvertUnixTime(long? unixTime)
+ {
+ return unixTime.HasValue ? (DateTime?) DateTimeOffset.FromUnixTimeSeconds(unixTime.Value).DateTime : null;
+ }
}
}
\ No newline at end of file
diff --git a/OpenAI_API/Assistants/AssistantFileRequest.cs b/OpenAI_API/Assistants/AssistantFileRequest.cs
new file mode 100644
index 0000000..cdc9328
--- /dev/null
+++ b/OpenAI_API/Assistants/AssistantFileRequest.cs
@@ -0,0 +1,17 @@
+using Newtonsoft.Json;
+
+namespace OpenAI_API.Assistants
+{
+ ///
+ /// Represents a request to create an assistant file.
+ ///
+ public class AssistantFileRequest
+ {
+ ///
+ /// A file ID (with purpose="assistants") that the assistant should use. Useful for tools like
+ /// retrieval and code_interpreter that can access files.
+ ///
+ [JsonProperty("file_id")]
+ public string FileId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Assistants/AssistantFileResult.cs b/OpenAI_API/Assistants/AssistantFileResult.cs
new file mode 100644
index 0000000..a86a675
--- /dev/null
+++ b/OpenAI_API/Assistants/AssistantFileResult.cs
@@ -0,0 +1,35 @@
+using System;
+using Newtonsoft.Json;
+
+namespace OpenAI_API.Assistants
+{
+ ///
+ /// Represents a file that is attached to an assistant.
+ ///
+ public class AssistantFileResult : ApiResultBase
+ {
+ ///
+ /// The identifier, which can be referenced in API endpoints.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// The Unix timestamp (in seconds) for when the assistant file was created.
+ ///
+ [JsonProperty("created_at")]
+ public long? CreatedAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the assistant file was created.
+ ///
+ [JsonIgnore]
+ public DateTime? CreatedAt => ConvertUnixTime(CreatedAtUnixTime);
+
+ ///
+ /// The ID of the assistant this file is attached to.
+ ///
+ [JsonProperty("assistant_id")]
+ public string AssistantId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Assistants/AssistantRequest.cs b/OpenAI_API/Assistants/AssistantRequest.cs
new file mode 100644
index 0000000..f828aec
--- /dev/null
+++ b/OpenAI_API/Assistants/AssistantRequest.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using OpenAI_API.Common;
+
+namespace OpenAI_API.Assistants
+{
+ ///
+ /// Represents a request to create an assistant.
+ ///
+ public class AssistantRequest : MetadataRequest
+ {
+ ///
+ /// The ID of the model to use.
+ ///
+ [JsonProperty("model")]
+ public string Model { get; set; }
+
+ ///
+ /// The name of the assistant. The maximum length is 256 characters.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ ///
+ /// The description of the assistant. The maximum length is 512 characters.
+ ///
+ [JsonProperty("description")]
+ public string Description { get; set; }
+
+ ///
+ /// The system instructions that the assistant uses. The maximum length is 32768 characters.
+ ///
+ [JsonProperty("instructions")]
+ public string Instructions { get; set; }
+
+ ///
+ /// A list of tools enabled on the assistant. There can be a maximum of 128 tools per assistant. Tools can be
+ /// be of types code_interpreter, retrieval or function.
+ ///
+ [JsonProperty("tools")]
+ public IList Tools { get; set; } = Array.Empty();
+
+ ///
+ /// 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.
+ ///
+ [JsonProperty("file_ids")]
+ public IList FileIds { get; set; } = Array.Empty();
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Assistants/AssistantResult.cs b/OpenAI_API/Assistants/AssistantResult.cs
new file mode 100644
index 0000000..50d7312
--- /dev/null
+++ b/OpenAI_API/Assistants/AssistantResult.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace OpenAI_API.Assistants
+{
+ ///
+ /// Represents an assistant that can call the model and use tools.
+ ///
+ public class AssistantResult : ApiResultBase
+ {
+ ///
+ /// The identifier, which can be referenced in API endpoints.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// The Unix timestamp (in seconds) for when the assistant was created.
+ ///
+ [JsonProperty("created_at")]
+ public long? CreatedAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the assistant was created.
+ ///
+ [JsonIgnore]
+ public DateTime? CreatedAt => ConvertUnixTime(CreatedAtUnixTime);
+
+ ///
+ /// The name of the assistant. The maximum length is 256 characters.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ ///
+ /// The description of the assistant. The maximum length is 512 characters.
+ ///
+ [JsonProperty("description")]
+ public string Description { get; set; }
+
+ ///
+ /// The system instructions that the assistant uses. The maximum length is 32768 characters.
+ ///
+ [JsonProperty("instructions")]
+ public string Instructions { get; set; }
+
+ ///
+ /// A list of tools enabled on the assistant. There can be a maximum of 128 tools per assistant. Tools can be of
+ /// types code_interpreter, retrieval or function.
+ ///
+ [JsonProperty("tools")]
+ public IReadOnlyList Tools { get; set; }
+
+ ///
+ /// 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.
+ ///
+ [JsonProperty("file_ids")]
+ public IReadOnlyList FileIds { get; set; }
+
+ ///
+ /// 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.
+ ///
+ [JsonProperty("metadata")]
+ public IReadOnlyDictionary Metadata { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Assistants/AssistantTool.cs b/OpenAI_API/Assistants/AssistantTool.cs
new file mode 100644
index 0000000..470bf7e
--- /dev/null
+++ b/OpenAI_API/Assistants/AssistantTool.cs
@@ -0,0 +1,65 @@
+using System.Runtime.Serialization;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Linq;
+
+namespace OpenAI_API.Assistants
+{
+ ///
+ /// Represents a tool that an assistant can use.
+ ///
+ public class AssistantTool
+ {
+ ///
+ /// The type of tool being defined.
+ ///
+ [JsonProperty("type")]
+ [JsonConverter(typeof(StringEnumConverter))]
+ public AssistantToolType Type { get; set; }
+
+ ///
+ /// The function of the tool being defined. Only present if is .
+ ///
+ [JsonProperty("function")]
+ public AssistantToolFunction Function { get; set; }
+ }
+
+ ///
+ /// Represents a function of a tool that an assistant can use.
+ ///
+ public class AssistantToolFunction
+ {
+ ///
+ /// 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.
+ ///
+ [JsonProperty("name")]
+ 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.
+ ///
+ [JsonProperty("description")]
+ public string Description { get; set; }
+
+ ///
+ /// 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.
+ ///
+ ///
+ /// Omitting parameters defines a function with an empty parameter list.
+ ///
+ [JsonProperty("parameters")]
+ public JObject Parameters { get; set; }
+ }
+
+ ///
+ /// Enumerates the types of assistant tools.
+ ///
+ public enum AssistantToolType
+ {
+ [EnumMember(Value = "code_interpreter")] CodeInterpreter,
+ [EnumMember(Value = "retrieval")] Retrieval,
+ [EnumMember(Value = "function")] Function
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Assistants/AssistantsEndpoint.cs b/OpenAI_API/Assistants/AssistantsEndpoint.cs
new file mode 100644
index 0000000..341800d
--- /dev/null
+++ b/OpenAI_API/Assistants/AssistantsEndpoint.cs
@@ -0,0 +1,107 @@
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using OpenAI_API.Common;
+
+namespace OpenAI_API.Assistants
+{
+ ///
+ /// The endpoint for the Assistants API.
+ ///
+ public class AssistantsEndpoint : EndpointBase, IAssistantsEndpoint
+ {
+ ///
+ /// The name of the endpoint, which is the final path segment in the API URL.
+ ///
+ protected override string Endpoint => "assistants";
+
+ ///
+ /// Constructs a new .
+ ///
+ ///
+ ///
+ /// The instance to use for making requests.
+ ///
+ public AssistantsEndpoint(OpenAIAPI api) : base(api) { }
+
+ ///
+ public async Task CreateAssistant(AssistantRequest request)
+ {
+ return await HttpPost(Url, request);
+ }
+
+ ///
+ public async Task CreateAssistantFile(string assistantId, AssistantFileRequest request)
+ {
+ var url = $"{Url}/{assistantId}/files";
+
+ return await HttpPost(url, request);
+ }
+
+ ///
+ public async Task> ListAssistants(QueryParams queryParams = null)
+ {
+ queryParams ??= new QueryParams();
+
+ var url = $"{Url}{queryParams}";
+
+ var content = await HttpGetContent(url);
+
+ return JsonConvert.DeserializeObject>(content);
+ }
+
+ ///
+ public async Task> ListAssistantFiles(
+ string assistantId,
+ QueryParams queryParams = null
+ )
+ {
+ queryParams ??= new QueryParams();
+
+ var url = $"{Url}/{assistantId}/files{queryParams}";
+
+ var content = await HttpGetContent(url);
+
+ return JsonConvert.DeserializeObject>(content);
+ }
+
+ ///
+ public Task RetrieveAssistant(string assistantId)
+ {
+ var url = $"{Url}/{assistantId}";
+
+ return HttpGet(url);
+ }
+
+ ///
+ public Task RetrieveAssistantFile(string assistantId, string fileId)
+ {
+ var url = $"{Url}/{assistantId}/files/{fileId}";
+
+ return HttpGet(url);
+ }
+
+ ///
+ public Task ModifyAssistant(string assistantId, AssistantRequest request)
+ {
+ var url = $"{Url}/{assistantId}";
+
+ return HttpPost(url, request);
+ }
+
+ ///
+ public Task DeleteAssistant(string assistantId)
+ {
+ var url = $"{Url}/{assistantId}";
+
+ return HttpDelete(url);
+ }
+
+ ///
+ public Task DeleteAssistantFile(string assistantId, string fileId)
+ {
+ var url = $"{Url}/{assistantId}/files/{fileId}";
+
+ return HttpDelete(url);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Assistants/IAssistantsEndpoint.cs b/OpenAI_API/Assistants/IAssistantsEndpoint.cs
new file mode 100644
index 0000000..ff08db7
--- /dev/null
+++ b/OpenAI_API/Assistants/IAssistantsEndpoint.cs
@@ -0,0 +1,143 @@
+using System.Threading.Tasks;
+using OpenAI_API.Common;
+
+namespace OpenAI_API.Assistants
+{
+ ///
+ /// An interface for the Assistants API endpoint.
+ ///
+ public interface IAssistantsEndpoint
+ {
+ ///
+ /// Creates an assistant with a model and instructions.
+ ///
+ ///
+ ///
+ /// The request to create an assistant.
+ ///
+ ///
+ ///
+ /// The created assistant object.
+ ///
+ Task CreateAssistant(AssistantRequest request);
+
+ ///
+ /// Creates an assistant file by attaching a file to an assistant.
+ ///
+ ///
+ ///
+ /// The ID of the assistant to which to create the file.
+ ///
+ ///
+ /// The request to create an assistant file.
+ ///
+ ///
+ ///
+ /// The created assistant file object.
+ ///
+ Task CreateAssistantFile(string assistantId, AssistantFileRequest request);
+
+ ///
+ /// Lists the assistants.
+ ///
+ ///
+ ///
+ /// The parameters to use to list the assistants. If unspecified, the default parameters are used.
+ ///
+ ///
+ ///
+ /// A list of assistant objects.
+ ///
+ Task> ListAssistants(QueryParams queryParams = null);
+
+ ///
+ /// Lists the assistant files.
+ ///
+ ///
+ ///
+ /// The ID of the assistant for which to list the files.
+ ///
+ ///
+ /// The parameters to use to list the assistant files. If unspecified, the default parameters are used.
+ ///
+ ///
+ ///
+ /// A list of assistant file objects.
+ ///
+ Task> ListAssistantFiles(string assistantId, QueryParams queryParams = null);
+
+ ///
+ /// Retrieves an assistant.
+ ///
+ ///
+ ///
+ /// The ID of the assistant to retrieve.
+ ///
+ ///
+ ///
+ /// The assistant object matching the ID.
+ ///
+ Task RetrieveAssistant(string assistantId);
+
+ ///
+ /// Retrieves an assistant file.
+ ///
+ ///
+ ///
+ /// The ID of the assistant to which the file is attached.
+ ///
+ ///
+ /// The ID of the file to retrieve.
+ ///
+ ///
+ ///
+ /// The assistant file object matching the ID.
+ ///
+ Task RetrieveAssistantFile(string assistantId, string fileId);
+
+ ///
+ /// Modifies an assistant.
+ ///
+ ///
+ ///
+ /// The ID of the assistant to modify.
+ ///
+ ///
+ /// The request to modify the assistant.
+ ///
+ ///
+ ///
+ /// The modified assistant object matching the specified ID.
+ ///
+ Task ModifyAssistant(string assistantId, AssistantRequest request);
+
+ ///
+ /// Deletes an assistant.
+ ///
+ ///
+ ///
+ /// The ID of the assistant to delete.
+ ///
+ ///
+ ///
+ /// The status of the deletion.
+ ///
+ Task DeleteAssistant(string assistantId);
+
+ ///
+ /// Deletes an assistant file.
+ ///
+ ///
+ ///
+ /// The ID of the assistant from which to delete the file.
+ ///
+ ///
+ /// The ID of the file to delete.
+ ///
+ ///
+ ///
+ /// The status of the deletion.
+ ///
+ Task DeleteAssistantFile(string assistantId, string fileId);
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Common/DeletionStatus.cs b/OpenAI_API/Common/DeletionStatus.cs
new file mode 100644
index 0000000..cb9477d
--- /dev/null
+++ b/OpenAI_API/Common/DeletionStatus.cs
@@ -0,0 +1,28 @@
+using Newtonsoft.Json;
+
+namespace OpenAI_API.Common
+{
+ ///
+ /// Represents the status of a deletion request.
+ ///
+ public class DeletionStatus : ApiResultBase
+ {
+ ///
+ /// The ID of the object that was deleted.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// The type of object that was deleted.
+ ///
+ [JsonProperty("object")]
+ public new string Object { get; set; }
+
+ ///
+ /// Whether the object was deleted.
+ ///
+ [JsonProperty("deleted")]
+ public bool Deleted { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Common/MetadataRequest.cs b/OpenAI_API/Common/MetadataRequest.cs
new file mode 100644
index 0000000..52565d6
--- /dev/null
+++ b/OpenAI_API/Common/MetadataRequest.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace OpenAI_API.Common
+{
+ ///
+ /// Represents a request to modify the metadata of an object.
+ ///
+ public class MetadataRequest
+ {
+ ///
+ /// 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.
+ ///
+ [JsonProperty("metadata")]
+ public IDictionary Metadata { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Common/QueryParams.cs b/OpenAI_API/Common/QueryParams.cs
new file mode 100644
index 0000000..118e206
--- /dev/null
+++ b/OpenAI_API/Common/QueryParams.cs
@@ -0,0 +1,75 @@
+using System.Runtime.Serialization;
+
+namespace OpenAI_API.Common
+{
+ ///
+ /// Represents the query parameters for a list request.
+ ///
+ public class QueryParams
+ {
+ ///
+ /// A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 20.
+ ///
+ public int Limit { get; set; } = 20;
+
+ ///
+ /// Sort order by the created_at of the objects. Options are asc for ascending order and
+ /// desc for descending order. The default is desc.
+ ///
+ public OrderMode Order { get; set; } = OrderMode.Desc;
+
+ ///
+ /// The cursor for use in pagination. after is an object ID that defines your place in the list. For
+ /// instance, if you make a list request and receive 100 objects, ending with obj_foo, your subsequent call can
+ /// include after=obj_foo in order to fetch the next page of the list.
+ ///
+ public string After { get; set; }
+
+ ///
+ /// The cursor for use in pagination. before is an object ID that defines your place in the list. For
+ /// instance, if you make a list request and receive 100 objects, starting with obj_bar, your subsequent call can
+ /// include before=obj_bar in order to fetch the previous page of the list.
+ ///
+ public string Before { get; set; }
+
+ ///
+ /// Converts the query parameters to a query string.
+ ///
+ ///
+ ///
+ /// The query string.
+ ///
+ public override string ToString()
+ {
+ var queryString = $"?limit={Limit}&order={Order.ToString().ToLower()}";
+
+ if (!string.IsNullOrEmpty(After))
+ {
+ queryString += $"&after={After}";
+ }
+
+ if (!string.IsNullOrEmpty(Before))
+ {
+ queryString += $"&before={Before}";
+ }
+
+ return queryString;
+ }
+ }
+
+ ///
+ /// Enumerates the available sort modes.
+ ///
+ public enum OrderMode
+ {
+ ///
+ /// Sort in ascending order.
+ ///
+ Asc,
+
+ ///
+ /// Sort in descending order.
+ ///
+ Desc
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Common/ResultsList.cs b/OpenAI_API/Common/ResultsList.cs
new file mode 100644
index 0000000..16fdcf3
--- /dev/null
+++ b/OpenAI_API/Common/ResultsList.cs
@@ -0,0 +1,41 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace OpenAI_API.Common
+{
+ ///
+ /// Represents a list of results.
+ ///
+ public class ResultsList where TResult : ApiResultBase
+ {
+ ///
+ /// The object type. Always "list".
+ ///
+ [JsonProperty("object")]
+ public string Object { get; set; }
+
+ ///
+ /// The list of results.
+ ///
+ [JsonProperty("data")]
+ public IReadOnlyList Data { get; set; }
+
+ ///
+ /// The ID of the first result in the list.
+ ///
+ [JsonProperty("first_id")]
+ public string FirstId { get; set; }
+
+ ///
+ /// The ID of the last result in the list.
+ ///
+ [JsonProperty("last_id")]
+ public string LastId { get; set; }
+
+ ///
+ /// Whether there are more results available.
+ ///
+ [JsonProperty("has_more")]
+ public bool HasMore { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/EndpointBase.cs b/OpenAI_API/EndpointBase.cs
index d981c7e..78a83eb 100644
--- a/OpenAI_API/EndpointBase.cs
+++ b/OpenAI_API/EndpointBase.cs
@@ -72,6 +72,7 @@ protected HttpClient GetClient()
}
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _Api.Auth.ApiKey);
+ client.DefaultRequestHeaders.Add("OpenAI-Beta", "assistants=v1");
// Further authentication-header used for Azure openAI service
client.DefaultRequestHeaders.Add("api-key", _Api.Auth.ApiKey);
client.DefaultRequestHeaders.Add("User-Agent", UserAgent);
diff --git a/OpenAI_API/Messages/Annotation.cs b/OpenAI_API/Messages/Annotation.cs
new file mode 100644
index 0000000..366b836
--- /dev/null
+++ b/OpenAI_API/Messages/Annotation.cs
@@ -0,0 +1,89 @@
+using System.Runtime.Serialization;
+using Newtonsoft.Json;
+
+namespace OpenAI_API.Messages
+{
+ ///
+ /// Represents an annotation in a message content.
+ ///
+ public class Annotation
+ {
+ ///
+ /// The type of annotation.
+ ///
+ [JsonProperty("type")]
+ public AnnotationType Type { get; set; }
+
+ ///
+ /// The text in the message content that needs to be replaced.
+ ///
+ [JsonProperty("text")]
+ public string Text { get; set; }
+
+ ///
+ /// The file citation.
+ ///
+ ///
+ /// Only present if is .
+ ///
+ [JsonProperty("file_annotation")]
+ public FileCitation FileCitation { get; set; }
+
+ ///
+ /// The file path.
+ ///
+ ///
+ /// Only present if is .
+ ///
+ [JsonProperty("file_path")]
+ public FilePath FilePath { get; set; }
+
+ ///
+ /// The start index.
+ ///
+ [JsonProperty("start_index")]
+ public int StartIndex { get; set; }
+
+ ///
+ /// The end index.
+ ///
+ [JsonProperty("end_index")]
+ public int EndIndex { get; set; }
+ }
+
+ ///
+ /// Represents a citation to a file.
+ ///
+ public class FileCitation
+ {
+ ///
+ /// The ID of the specified file the citation is from.
+ ///
+ [JsonProperty("file_id")]
+ public string FileId { get; set; }
+
+ ///
+ /// The specific quote in the file.
+ ///
+ [JsonProperty("quote")]
+ public string Quote { get; set; }
+ }
+
+ ///
+ /// Represents a file path.
+ ///
+ public class FilePath
+ {
+ ///
+ /// The ID of the file that was generated.
+ ///
+ [JsonProperty("file_id")]
+ public string FileId { get; set; }
+ }
+
+ public enum AnnotationType
+ {
+ [EnumMember(Value = "file_citation")] FileCitation,
+ [EnumMember(Value = "file_path")] FilePath
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Messages/IMessagesEndpoint.cs b/OpenAI_API/Messages/IMessagesEndpoint.cs
new file mode 100644
index 0000000..d765cc2
--- /dev/null
+++ b/OpenAI_API/Messages/IMessagesEndpoint.cs
@@ -0,0 +1,120 @@
+using System.Threading.Tasks;
+using OpenAI_API.Common;
+
+namespace OpenAI_API.Messages
+{
+ ///
+ /// An interface for the Messages API endpoint.
+ ///
+ public interface IMessagesEndpoint
+ {
+ ///
+ /// Creates a message.
+ ///
+ ///
+ ///
+ /// The ID of the thread to create the message in.
+ ///
+ ///
+ /// The request object.
+ ///
+ ///
+ ///
+ /// The created message object.
+ ///
+ public Task CreateMessage(string threadId, MessageRequest request);
+
+ ///
+ /// List the messages in a thread.
+ ///
+ ///
+ ///
+ /// The ID of the thread for which to list the messages.
+ ///
+ ///
+ /// The parameters to use to list the messages. If unspecified, the default parameters are used.
+ ///
+ ///
+ ///
+ /// A list of message objects.
+ ///
+ public Task> ListMessages(string threadId, QueryParams queryParams = null);
+
+ ///
+ /// Lists the message files of a message.
+ ///
+ ///
+ ///
+ /// The ID of the thread the message and file belong to.
+ ///
+ ///
+ /// The ID of the message that the file belong to.
+ ///
+ ///
+ /// The parameters to use to list the message files. If unspecified, the default parameters are used.
+ ///
+ ///
+ ///
+ /// A list of message file objects.
+ ///
+ public Task> ListMessageFiles(
+ string threadId,
+ string messageId,
+ QueryParams queryParams = null
+ );
+
+ ///
+ /// Retrieves a message.
+ ///
+ ///
+ ///
+ /// The ID of the thread to retrieve the message from.
+ ///
+ ///
+ /// The ID of the message to retrieve.
+ ///
+ ///
+ ///
+ /// The retrieved message object.
+ ///
+ public Task RetrieveMessage(string threadId, string messageId);
+
+ ///
+ /// Retrieves a message file.
+ ///
+ ///
+ ///
+ /// The ID of the thread to which the message and file belong.
+ ///
+ ///
+ /// The ID of the message the file belongs to.
+ ///
+ ///
+ /// The ID of the file being retrieved.
+ ///
+ ///
+ ///
+ /// The message file object matching the ID.
+ ///
+ public Task RetrieveMessageFile(string threadId, string messageId, string fileId);
+
+ ///
+ /// Modifies a message.
+ ///
+ ///
+ ///
+ /// The ID of the thread to which the message belongs.
+ ///
+ ///
+ /// The ID of the message to modify.
+ ///
+ ///
+ /// The request object.
+ ///
+ ///
+ ///
+ /// The modified message object matching the specified ID.
+ ///
+ public Task ModifyMessage(string threadId, string messageId, MetadataRequest request);
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Messages/MessageFileResult.cs b/OpenAI_API/Messages/MessageFileResult.cs
new file mode 100644
index 0000000..f98a5ae
--- /dev/null
+++ b/OpenAI_API/Messages/MessageFileResult.cs
@@ -0,0 +1,35 @@
+using System;
+using Newtonsoft.Json;
+
+namespace OpenAI_API.Messages
+{
+ ///
+ /// Represents a message file attached to a message.
+ ///
+ public class MessageFileResult : ApiResultBase
+ {
+ ///
+ /// The identifier, which can be referenced in API endpoints.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// The Unix timestamp (in seconds) for when the message file was created.
+ ///
+ [JsonProperty("created_at")]
+ public long? CreatedAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the message file was created.
+ ///
+ [JsonIgnore]
+ public DateTime? CreatedAt => ConvertUnixTime(CreatedAtUnixTime);
+
+ ///
+ /// The message ID this file belongs to.
+ ///
+ [JsonProperty("message_id")]
+ public string MessageId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Messages/MessageRequest.cs b/OpenAI_API/Messages/MessageRequest.cs
new file mode 100644
index 0000000..baaf8ba
--- /dev/null
+++ b/OpenAI_API/Messages/MessageRequest.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using OpenAI_API.Common;
+
+namespace OpenAI_API.Messages
+{
+ ///
+ /// Represents a request to create a message.
+ ///
+ public class MessageRequest : MetadataRequest
+ {
+
+ ///
+ /// The role of the message. Only is currently supported.
+ ///
+ [JsonProperty("role")]
+ [JsonConverter(typeof(StringEnumConverter))]
+ public MessageRole Role { get; set; }
+
+ ///
+ /// The content of the message
+ ///
+ [JsonProperty("content")]
+ public string Content { get; set; }
+
+ ///
+ /// A list of File IDs that the message should use.
+ ///
+ [JsonProperty("file_ids")]
+ public IList FileIds { get; set; } = Array.Empty();
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Messages/MessageResult.cs b/OpenAI_API/Messages/MessageResult.cs
new file mode 100644
index 0000000..a3eff3f
--- /dev/null
+++ b/OpenAI_API/Messages/MessageResult.cs
@@ -0,0 +1,143 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+
+namespace OpenAI_API.Messages
+{
+ ///
+ /// Represents a message.
+ ///
+ public class MessageResult : ApiResultBase
+ {
+ ///
+ /// The identifier, which can be referenced in API endpoints.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// The Unix timestamp (in seconds) for when the message was created.
+ ///
+ [JsonProperty("created_at")]
+ public long? CreatedAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the message was created.
+ ///
+ [JsonIgnore]
+ public DateTime? CreatedAt => ConvertUnixTime(CreatedAtUnixTime);
+
+ ///
+ /// The thread ID this message belongs to.
+ ///
+ [JsonProperty("thread_id")]
+ public string ThreadId { get; set; }
+
+ ///
+ /// The entity that produced the message.
+ ///
+ [JsonProperty("role")]
+ [JsonConverter(typeof(StringEnumConverter))]
+ public MessageRole Role { get; set; }
+
+ ///
+ /// The content of the message in an array of text and/or images.
+ ///
+ [JsonProperty("content")]
+ public IReadOnlyList Content { get; set; }
+
+ ///
+ /// If applicable, the ID of the assistant that authored the message.
+ ///
+ [JsonProperty("assistant_id")]
+ public string AssistantId { get; set; }
+
+ ///
+ /// If applicable, the ID of the run associated with the authoring of this message.
+ ///
+ [JsonProperty("run_id")]
+ public string RunId { get; set; }
+
+ ///
+ /// A list of file IDs that the assistant could use.
+ ///
+ [JsonProperty("file_ids")]
+ public IReadOnlyList FileIds { get; set; }
+
+ ///
+ /// 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.
+ ///
+ [JsonProperty("metadata")]
+ public IReadOnlyDictionary Metadata { get; set; }
+ }
+
+ ///
+ /// Represents the content of a message.
+ ///
+ public class Content
+ {
+ ///
+ /// The type of content.
+ ///
+ [JsonProperty("type")]
+ public MessageContentType Type { get; set; }
+
+ ///
+ /// The text content.
+ ///
+ ///
+ /// Only present if is .
+ ///
+ [JsonProperty("text")]
+ public Text Text { get; set; }
+
+ ///
+ /// References an image file in the content of a message.
+ ///
+ ///
+ /// Only present if is .
+ ///
+ [JsonProperty("image_file")]
+ public ImageFile ImageFile { get; set; }
+ }
+
+ ///
+ /// Represents a text object.
+ ///
+ public class Text
+ {
+ ///
+ /// The value of the text.
+ ///
+ [JsonProperty("value")]
+ public string Value { get; set; }
+
+ ///
+ /// A list of annotations for the text.
+ ///
+ [JsonProperty("annotations")]
+ public IReadOnlyList Annotations { get; set; }
+ }
+
+ ///
+ /// Represents the reference to an image.
+ ///
+ public class ImageFile
+ {
+ ///
+ /// The file ID of the image in the message content.
+ ///
+ [JsonProperty("file_id")]
+ public string FileId { get; set; }
+ }
+
+ public enum MessageContentType
+ {
+ [EnumMember(Value = "test")] Text,
+ [EnumMember(Value = "image_file")] ImageFile
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Messages/MessageRole.cs b/OpenAI_API/Messages/MessageRole.cs
new file mode 100644
index 0000000..bf6b26a
--- /dev/null
+++ b/OpenAI_API/Messages/MessageRole.cs
@@ -0,0 +1,20 @@
+using System.Runtime.Serialization;
+
+namespace OpenAI_API.Messages
+{
+ ///
+ /// Enumerates roles that a message can have.
+ ///
+ public enum MessageRole
+ {
+ ///
+ /// The message was created by the user.
+ ///
+ [EnumMember(Value = "user")] User,
+
+ ///
+ /// The message was created by the assistant.
+ ///
+ [EnumMember(Value = "assistant")] Assistant
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Messages/MessagesEndpoint.cs b/OpenAI_API/Messages/MessagesEndpoint.cs
new file mode 100644
index 0000000..7d1d94d
--- /dev/null
+++ b/OpenAI_API/Messages/MessagesEndpoint.cs
@@ -0,0 +1,86 @@
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using OpenAI_API.Common;
+
+namespace OpenAI_API.Messages
+{
+ ///
+ /// The endpoint for the Messages API.
+ ///
+ public class MessagesEndpoint : EndpointBase, IMessagesEndpoint
+ {
+ ///
+ /// The name of the endpoint, which is the final path segment in the API URL.
+ ///
+ protected override string Endpoint => "threads";
+
+ ///
+ /// Constructs a new .
+ ///
+ ///
+ ///
+ /// The instance to use for making requests.
+ ///
+ public MessagesEndpoint(OpenAIAPI api) : base(api) { }
+
+ ///
+ public async Task CreateMessage(string threadId, MessageRequest request)
+ {
+ var url = $"{Url}/{threadId}/messages";
+
+ return await HttpPost(url, request);
+ }
+
+ ///
+ public async Task> ListMessages(string threadId, QueryParams queryParams = null)
+ {
+ queryParams ??= new QueryParams();
+
+ var url = $"{Url}/{threadId}/messages{queryParams}";
+
+ var content = await HttpGetContent(url);
+
+ return JsonConvert.DeserializeObject>(content);
+ }
+
+ ///
+ public async Task> ListMessageFiles(
+ string threadId,
+ string messageId,
+ QueryParams queryParams = null
+ )
+ {
+ queryParams ??= new QueryParams();
+
+ var url = $"{Url}/{threadId}/messages/{messageId}/files{queryParams}";
+
+ var content = await HttpGetContent(url);
+
+ return JsonConvert.DeserializeObject>(content);
+ }
+
+ ///
+ public async Task RetrieveMessage(string threadId, string messageId)
+ {
+ var url = $"{Url}/{threadId}/messages/{messageId}";
+
+ return await HttpGet(url);
+ }
+
+ ///
+ public async Task RetrieveMessageFile(string threadId, string messageId, string fileId)
+ {
+ var url = $"{Url}/{threadId}/messages/{messageId}/files/{fileId}";
+
+ return await HttpGet(url);
+ }
+
+ ///
+ public async Task ModifyMessage(string threadId, string messageId, MetadataRequest request)
+ {
+ var url = $"{Url}/{threadId}/messages/{messageId}";
+
+ return await HttpPost(url, request);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/OpenAIAPI.cs b/OpenAI_API/OpenAIAPI.cs
index 349f08f..ba2ca3e 100644
--- a/OpenAI_API/OpenAIAPI.cs
+++ b/OpenAI_API/OpenAIAPI.cs
@@ -7,6 +7,10 @@
using OpenAI_API.Models;
using OpenAI_API.Moderation;
using System.Net.Http;
+using OpenAI_API.Assistants;
+using OpenAI_API.Messages;
+using OpenAI_API.Runs;
+using OpenAI_API.Threads;
namespace OpenAI_API
{
@@ -54,6 +58,10 @@ public OpenAIAPI(APIAuthentication apiKeys = null)
TextToSpeech = new TextToSpeechEndpoint(this);
Transcriptions = new TranscriptionEndpoint(this, false);
Translations = new TranscriptionEndpoint(this, true);
+ Assistants = new AssistantsEndpoint(this);
+ Threads = new ThreadsEndpoint(this);
+ Messages = new MessagesEndpoint(this);
+ Runs = new RunsEndpoint(this);
}
///
@@ -120,5 +128,25 @@ public static OpenAIAPI ForAzure(string YourResourceName, string deploymentId, A
/// The endpoint for the audio translation API. This allows you to generate English text from audio in other languages. See
///
public ITranscriptionEndpoint Translations { get; }
+
+ ///
+ /// The endpoint for the Assistants API. This allows you to create and manage assistants. See
+ ///
+ public IAssistantsEndpoint Assistants { get; }
+
+ ///
+ /// The endpoint for the Threads API. This allows you to create and manage threads. See
+ ///
+ public IThreadsEndpoint Threads { get; }
+
+ ///
+ /// The endpoint for the Messages API. This allows you to create and manage messages. See
+ ///
+ public IMessagesEndpoint Messages { get; }
+
+ ///
+ /// The endpoint for the Runs API. This allows you to create and manage runs. See
+ ///
+ public IRunsEndpoint Runs { get; }
}
}
diff --git a/OpenAI_API/Runs/IRunsEndpoint.cs b/OpenAI_API/Runs/IRunsEndpoint.cs
new file mode 100644
index 0000000..cda8971
--- /dev/null
+++ b/OpenAI_API/Runs/IRunsEndpoint.cs
@@ -0,0 +1,170 @@
+using System.Threading.Tasks;
+using OpenAI_API.Common;
+
+namespace OpenAI_API.Runs
+{
+ ///
+ /// An interface for the Runs API endpoint.
+ ///
+ public interface IRunsEndpoint
+ {
+ ///
+ /// Creates a run.
+ ///
+ ///
+ ///
+ /// The ID of the thread in which to create the run.
+ ///
+ ///
+ /// The request object.
+ ///
+ ///
+ ///
+ /// The created run object.
+ ///
+ public Task CreateRun(string threadId, RunRequest request);
+
+ ///
+ /// Creates a thread and runs it.
+ ///
+ ///
+ ///
+ /// The request object.
+ ///
+ ///
+ ///
+ /// The created run object.
+ ///
+ public Task CreateThreadAndRun(ThreadAndRunRequest request);
+
+ ///
+ /// Lists runs belonging to a thread.
+ ///
+ ///
+ ///
+ /// The ID of the thread to which the runs belong to.
+ ///
+ ///
+ /// The query parameters to use for the request. If unspecified, the default parameters are used.
+ ///
+ ///
+ ///
+ /// A list of runs objects belonging to the thread with the specified ID.
+ ///
+ public Task> ListRuns(string threadId, QueryParams queryParams = null);
+
+ ///
+ /// Lists run steps belonging to a run.
+ ///
+ ///
+ ///
+ /// The ID of the thread to which the run and run steps belong to.
+ ///
+ ///
+ /// The ID of the run the run steps belong to.
+ ///
+ ///
+ /// The query parameters to use for the request. If unspecified, the default parameters are used.
+ ///
+ ///
+ ///
+ /// A list of run step objects belonging to the run with the specified ID.
+ ///
+ public Task> ListRunSteps(
+ string threadId,
+ string runId,
+ QueryParams queryParams = null
+ );
+
+ ///
+ /// Retrieves a run.
+ ///
+ ///
+ ///
+ /// The ID of the thread to which the run belongs to.
+ ///
+ ///
+ /// The ID of the run to retrieve.
+ ///
+ ///
+ ///
+ /// The run object matching the specified ID.
+ ///
+ public Task RetrieveRun(string threadId, string runId);
+
+ ///
+ /// Retrieves a run step.
+ ///
+ ///
+ ///
+ /// The ID of the thread to which the run and run step belong to.
+ ///
+ ///
+ /// The ID of the run to which the run step belongs to.
+ ///
+ ///
+ /// The ID of the run step to retrieve.
+ ///
+ ///
+ ///
+ /// The run step object matching the specified ID.
+ ///
+ public Task RetrieveRunStep(string threadId, string runId, string stepId);
+
+ ///
+ /// Modifies a run.
+ ///
+ ///
+ ///
+ /// The ID of the thread to which the run belongs to.
+ ///
+ ///
+ /// The ID of the run to modify.
+ ///
+ ///
+ /// The request object.
+ ///
+ ///
+ ///
+ /// The modified run object matching the specified ID.
+ ///
+ public Task ModifyRun(string threadId, string runId, MetadataRequest request);
+
+ ///
+ /// When a run has the status: "requires_action" and required_action.type is submit_tool_outputs,
+ /// this endpoint can be used to submit the outputs from the tool calls once they're all completed. All outputs
+ /// must be submitted in a single request.
+ ///
+ ///
+ ///
+ /// The ID of the thread to which the run belongs to.
+ ///
+ ///
+ /// The ID of the run that requires the tool output submission.
+ ///
+ ///
+ /// The request object.
+ ///
+ ///
+ ///
+ /// The modified run object matching the specified ID.
+ ///
+ public Task SubmitToolOutputsToRun(string threadId, string runId, ToolOutputsRequest request);
+
+ ///
+ /// Cancels a run.
+ ///
+ ///
+ ///
+ /// The ID of the thread to which the run belongs to.
+ ///
+ ///
+ /// The ID of the run to cancel.
+ ///
+ ///
+ ///
+ /// The cancelled run object matching the specified ID.
+ ///
+ public Task CancelRun(string threadId, string runId);
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Runs/RunError.cs b/OpenAI_API/Runs/RunError.cs
new file mode 100644
index 0000000..9307bbe
--- /dev/null
+++ b/OpenAI_API/Runs/RunError.cs
@@ -0,0 +1,34 @@
+using System.Runtime.Serialization;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+
+namespace OpenAI_API.Runs
+{
+ ///
+ /// Represents an error that occurred during a run.
+ ///
+ public class RunError
+ {
+ ///
+ /// The error code.
+ ///
+ [JsonProperty("code")]
+ [JsonConverter(typeof(StringEnumConverter))]
+ public RunErrorCode Code { get; set; }
+
+ ///
+ /// A human-readable description of the error.
+ ///
+ [JsonProperty("message")]
+ public string Message { get; set; }
+ }
+
+ ///
+ /// Enumerates the possible error codes.
+ ///
+ public enum RunErrorCode
+ {
+ [EnumMember(Value = "server_error")] ServerError,
+ [EnumMember(Value = "rate_limit_exceeded")] RateLimitExceeded,
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Runs/RunRequest.cs b/OpenAI_API/Runs/RunRequest.cs
new file mode 100644
index 0000000..91b83ad
--- /dev/null
+++ b/OpenAI_API/Runs/RunRequest.cs
@@ -0,0 +1,46 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using OpenAI_API.Assistants;
+using OpenAI_API.Common;
+
+namespace OpenAI_API.Runs
+{
+ ///
+ /// Represents a request to create a run.
+ ///
+ public class RunRequest : MetadataRequest
+ {
+ ///
+ /// The ID of the assistant to execute this run.
+ ///
+ [JsonProperty("assistant_id")]
+ public string AssistantId { get; set; }
+
+ ///
+ /// The ID of the Model to be used to execute this run. If a value is provided here, it will override the
+ /// model associated with the assistant. If not, the model associated with the assistant will be used.
+ ///
+ [JsonProperty("model")]
+ public string Model { get; set; }
+
+ ///
+ /// Overrides the instructions of the assistant. This is useful for modifying the behavior on a per-run basis.
+ ///
+ [JsonProperty("instructions")]
+ public string Instructions { get; set; }
+
+ ///
+ /// Appends additional instructions at the end of the of the instructions for the run. This is useful for
+ /// modifying the behavior on a per-run basis, without overriding other instructions.
+ ///
+ [JsonProperty("additional_instructions")]
+ public string AdditionalInstructions { get; set; }
+
+ ///
+ /// Override the tools the assistant can use for this run. This is useful for modifying the behavior on a
+ /// per-run basis.
+ ///
+ [JsonProperty("tools")]
+ public IList Tools { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Runs/RunResult.cs b/OpenAI_API/Runs/RunResult.cs
new file mode 100644
index 0000000..54df886
--- /dev/null
+++ b/OpenAI_API/Runs/RunResult.cs
@@ -0,0 +1,238 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using OpenAI_API.Assistants;
+
+namespace OpenAI_API.Runs
+{
+ ///
+ /// Represents a run.
+ ///
+ public class RunResult : ApiResultBase
+ {
+ ///
+ /// The identifier, which can be referenced in API endpoints.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// The ID of the thread that was executed as part of this run.
+ ///
+ [JsonProperty("thread_id")]
+ public string ThreadId { get; set; }
+
+ ///
+ /// The ID of the assistant used for execution of this run.
+ ///
+ [JsonProperty("assistant_id")]
+ public string AssistantId { get; set; }
+
+ ///
+ /// The status of the run.
+ ///
+ [JsonProperty("status")]
+ [JsonConverter(typeof(StringEnumConverter))]
+ public RunStatus Status { get; set; }
+
+ ///
+ /// Details on the action required to continue the run. Will be null if no action is required.
+ ///
+ [JsonProperty("required_action")]
+ public RequiredAction RequiredAction { get; set; }
+
+ ///
+ /// The last error associated with the run step. Will be null if there are no errors.
+ ///
+ [JsonProperty("last_error")]
+ public RunError LastError { get; set; }
+
+ #region Timestamps
+
+ ///
+ /// The Unix timestamp (in seconds) for when the run was created.
+ ///
+ [JsonProperty("created_at")]
+ public long? CreatedAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the run was created.
+ ///
+ [JsonIgnore]
+ public DateTime? CreatedAt => ConvertUnixTime(CreatedAtUnixTime);
+
+ ///
+ /// The Unix timestamp (in seconds) for when the run will expire.
+ ///
+ [JsonProperty("expires_at")]
+ public long? ExpiresAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the run will expire.
+ ///
+ [JsonIgnore]
+ public DateTime? ExpiresAt => ConvertUnixTime(ExpiresAtUnixTime);
+
+ ///
+ /// The Unix timestamp (in seconds) for when the run was started.
+ ///
+ [JsonProperty("started_at")]
+ public long? StartedAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the run was started.
+ ///
+ [JsonIgnore]
+ public DateTime? StartedAt => ConvertUnixTime(StartedAtUnixTime);
+
+ ///
+ /// The Unix timestamp (in seconds) for when the run was cancelled.
+ ///
+ [JsonProperty("cancelled_at")]
+ public long? CancelledAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the run was cancelled.
+ ///
+ [JsonIgnore]
+ public DateTime? CancelledAt => ConvertUnixTime(CancelledAtUnixTime);
+
+ ///
+ /// The Unix timestamp (in seconds) for when the run failed.
+ ///
+ [JsonProperty("failed_at")]
+ public long? FailedAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the run failed.
+ ///
+ [JsonIgnore]
+ public DateTime? FailedAt => ConvertUnixTime(FailedAtUnixTime);
+
+ ///
+ /// The Unix timestamp (in seconds) for when the run was completed.
+ ///
+ [JsonProperty("completed_at")]
+ public long? CompletedAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the run was completed.
+ ///
+ [JsonIgnore]
+ public DateTime? CompletedAt => ConvertUnixTime(CompletedAtUnixTime);
+
+ #endregion
+
+ ///
+ /// The model that the assistant used for this run.
+ ///
+ [JsonProperty("model")]
+ public new string Model { get; set; }
+
+ ///
+ /// The instructions that the assistant used for this run.
+ ///
+ [JsonProperty("instructions")]
+ public string Instructions { get; set; }
+
+ ///
+ /// The list of tools that the assistant used for this run.
+ ///
+ [JsonProperty("tools")]
+ public IReadOnlyList Tools { get; set; }
+
+ ///
+ /// The list of file IDs the assistant used for this run.
+ ///
+ [JsonProperty("file_ids")]
+ public IReadOnlyList FileIds { get; set; }
+
+ ///
+ /// 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.
+ ///
+ [JsonProperty("metadata")]
+ public IReadOnlyDictionary Metadata { get; set; }
+
+ ///
+ /// Usage statistics related to the run. Will be null if the run is not in a terminal state.
+ ///
+ [JsonProperty("usage")]
+ public RunUsage Usage { get; set; }
+ }
+
+ ///
+ /// Represents the details of the action required to continue a run.
+ ///
+ public class RequiredAction
+ {
+ ///
+ /// For now, this is always submit_tool_outputs.
+ ///
+ [JsonProperty("type")]
+ public string Type { get; set; }
+
+ ///
+ /// Details on the tool outputs needed for this run to continue.
+ ///
+ [JsonProperty("submit_tool_outputs")]
+ public SubmitToolOutputs SubmitToolOutputs { get; set; }
+ }
+
+ ///
+ /// Represents the tool outputs needed for a run to continue.
+ ///
+ public class SubmitToolOutputs
+ {
+ ///
+ /// A list of the relevant tool calls.
+ ///
+ [JsonProperty("tool_calls")]
+ public IReadOnlyList ToolCalls { get; set; }
+ }
+
+ ///
+ /// Represents a tool call.
+ ///
+ public class ToolCall
+ {
+ ///
+ /// The ID of the tool call. This ID must be referenced when you submit the tool outputs in using the
+ /// endpoint.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// The type of tool call the output is required for. For now, this is always function.
+ ///
+ [JsonProperty("type")]
+ public string Type { get; set; }
+
+ ///
+ /// The function definition.
+ ///
+ [JsonProperty("function")]
+ public FunctionDefinition Function { get; set; }
+ }
+
+ ///
+ /// Represents a function definition.
+ ///
+ public class FunctionDefinition
+ {
+ ///
+ /// The name of the function.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ ///
+ /// The arguments that the model expects you to pass to the function.
+ ///
+ [JsonProperty("arguments")]
+ public IReadOnlyList Arguments { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Runs/RunStatus.cs b/OpenAI_API/Runs/RunStatus.cs
new file mode 100644
index 0000000..62c6e6d
--- /dev/null
+++ b/OpenAI_API/Runs/RunStatus.cs
@@ -0,0 +1,19 @@
+using System.Runtime.Serialization;
+
+namespace OpenAI_API.Runs
+{
+ ///
+ /// Represents the status of a run.
+ ///
+ public enum RunStatus
+ {
+ [EnumMember(Value = "queued")] Queued,
+ [EnumMember(Value = "in_progress")] InProgress,
+ [EnumMember(Value = "requires_action")] RequiresAction,
+ [EnumMember(Value = "cancelling")] Cancelling,
+ [EnumMember(Value = "cancelled")] Cancelled,
+ [EnumMember(Value = "failed")] Failed,
+ [EnumMember(Value = "completed")] Completed,
+ [EnumMember(Value = "expired")] Expired
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Runs/RunStepResult.cs b/OpenAI_API/Runs/RunStepResult.cs
new file mode 100644
index 0000000..215f6d3
--- /dev/null
+++ b/OpenAI_API/Runs/RunStepResult.cs
@@ -0,0 +1,251 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+using OpenAI_API.Assistants;
+
+namespace OpenAI_API.Runs
+{
+ ///
+ /// Represents a run step.
+ ///
+ public class RunStepResult : ApiResultBase
+ {
+ ///
+ /// The identifier, which can be referenced in API endpoints.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// The ID of the assistant associated with this run step.
+ ///
+ [JsonProperty("assistant_id")]
+ public string AssistantId { get; set; }
+
+ ///
+ /// The ID of the thread that was run.
+ ///
+ [JsonProperty("thread_id")]
+ public string ThreadId { get; set; }
+
+ ///
+ /// The ID of the run that this run step is part of.
+ ///
+ [JsonProperty("run_id")]
+ public string RunId { get; set; }
+
+ ///
+ /// The type of the run step.
+ ///
+ [JsonProperty("type")]
+ [JsonConverter(typeof(StringEnumConverter))]
+ public RunStepType Type { get; set; }
+
+ ///
+ /// The status of the run step.
+ ///
+ [JsonProperty("status")]
+ [JsonConverter(typeof(StringEnumConverter))]
+ public RunStepStatus Status { get; set; }
+
+ ///
+ /// The details of the run step.
+ ///
+ [JsonProperty("step_details")]
+ public RunStepDetails StepDetails { get; set; }
+
+ ///
+ /// The last error associated with the run step. Will be null if there are no errors.
+ ///
+ [JsonProperty("last_error")]
+ public RunError LastError { get; set; }
+
+ #region Timestamps
+
+ ///
+ /// The Unix timestamp (in seconds) for when the run step was created.
+ ///
+ [JsonProperty("created_at")]
+ public long? CreatedAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the run step was created.
+ ///
+ [JsonIgnore]
+ public DateTime? CreatedAt => ConvertUnixTime(CreatedAtUnixTime);
+
+ ///
+ /// The Unix timestamp (in seconds) for when the run step expired.
+ ///
+ [JsonProperty("expired_at")]
+ public long? ExpiredAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the run step expired.
+ ///
+ [JsonIgnore]
+ public DateTime? ExpiredAt => ConvertUnixTime(ExpiredAtUnixTime);
+
+ ///
+ /// The Unix timestamp (in seconds) for when the run step was cancelled.
+ ///
+ [JsonProperty("cancelled_at")]
+ public long? CancelledAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the run step was cancelled.
+ ///
+ [JsonIgnore]
+ public DateTime? CancelledAt => ConvertUnixTime(CancelledAtUnixTime);
+
+ ///
+ /// The Unix timestamp (in seconds) for when the run step failed.
+ ///
+ [JsonProperty("failed_at")]
+ public long? FailedAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the run step failed.
+ ///
+ [JsonIgnore]
+ public DateTime? FailedAt => ConvertUnixTime(FailedAtUnixTime);
+
+ ///
+ /// The Unix timestamp (in seconds) for when the run step was completed.
+ ///
+ [JsonProperty("completed_at")]
+ public long? CompletedAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the run step was completed.
+ ///
+ [JsonIgnore]
+ public DateTime? CompletedAt => ConvertUnixTime(CompletedAtUnixTime);
+
+ #endregion
+
+ ///
+ /// 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.
+ ///
+ [JsonProperty("metadata")]
+ public IReadOnlyDictionary Metadata { get; set; }
+
+ ///
+ /// Usage statistics related to the run. Will be null if the run is not in a terminal state.
+ ///
+ [JsonProperty("usage")]
+ public RunUsage Usage { get; set; }
+ }
+
+ ///
+ /// Represents the details of a run step.
+ ///
+ public class RunStepDetails
+ {
+ ///
+ /// The type of step details.
+ ///
+ [JsonProperty("type")]
+ [JsonConverter(typeof(StringEnumConverter))]
+ public RunStepDetailsType Type { get; set; }
+
+ ///
+ /// Details of the message creation step. Only present if is .
+ ///
+ [JsonProperty("message_creation")]
+ public RunStepMessageCreation MessageCreation { get; set; }
+
+ ///
+ /// An array of tool calls the run step was involved in. Only present if is .
+ ///
+ [JsonProperty("tool_calls")]
+ public IReadOnlyList ToolCalls { get; set; }
+ }
+
+ ///
+ /// Represents the creation of a message by a run step.
+ ///
+ public class RunStepMessageCreation
+ {
+ ///
+ /// The ID of the message that was created by this run step.
+ ///
+ [JsonProperty("message_id")]
+ public string MessageId { get; set; }
+ }
+
+ ///
+ /// Represents a tool call by a run step.
+ ///
+ public class RunStepToolCall
+ {
+ ///
+ /// The ID of the tool call.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// The type of tool call.
+ ///
+ [JsonProperty("type")]
+ [JsonConverter(typeof(StringEnumConverter))]
+ public AssistantToolType Type { get; set; }
+
+ ///
+ /// The code interpreter tool call definition. Only present if is .
+ ///
+ [JsonProperty("code_interpreter")]
+ public object CodeInterpreter { get; set; }
+
+ ///
+ /// The retrieval tool call definition. For now this is going to be an empty object.
+ ///
+ [JsonProperty("retrieval")]
+ public object Retrieval { get; set; }
+
+ ///
+ /// The definition of the function that was called. Only present if is .
+ ///
+ [JsonProperty("function")]
+ public object Function { get; set; }
+ }
+
+ #region Enums
+
+ ///
+ /// Enumerates the possible types of a run step.
+ ///
+ public enum RunStepType
+ {
+ [EnumMember(Value = "message_creation")] MessageCreation,
+ [EnumMember(Value = "tool_calls")] ToolCalls
+ }
+
+ ///
+ /// Enumerates the possible statuses of a run step.
+ ///
+ public enum RunStepStatus
+ {
+ [EnumMember(Value = "in_progress")] InProgress,
+ [EnumMember(Value = "cancelled")] Cancelled,
+ [EnumMember(Value = "failed")] Failed,
+ [EnumMember(Value = "completed")] Completed,
+ [EnumMember(Value = "expired")] Expired
+ }
+
+ ///
+ /// Enumerates the possible types of step details.
+ ///
+ public enum RunStepDetailsType
+ {
+ [EnumMember(Value = "message_creation")] MessageCreation,
+ [EnumMember(Value = "tool_calls")] ToolCalls
+ }
+
+ #endregion
+}
\ No newline at end of file
diff --git a/OpenAI_API/Runs/RunUsage.cs b/OpenAI_API/Runs/RunUsage.cs
new file mode 100644
index 0000000..298bec6
--- /dev/null
+++ b/OpenAI_API/Runs/RunUsage.cs
@@ -0,0 +1,28 @@
+using Newtonsoft.Json;
+
+namespace OpenAI_API.Runs
+{
+ ///
+ /// Represents the usage statistics related to a run.
+ ///
+ public class RunUsage
+ {
+ ///
+ /// Number of completion tokens used over the course of the run.
+ ///
+ [JsonProperty("completion_tokens")]
+ public int CompletionTokens { get; set; }
+
+ ///
+ /// Number of prompt tokens used over the course of the run.
+ ///
+ [JsonProperty("prompt_tokens")]
+ public int PromptTokens { get; set; }
+
+ ///
+ /// Number of tokens used (prompt + completion) over the course of the run.
+ ///
+ [JsonProperty("total_tokens")]
+ public int TotalTokens { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Runs/RunsEndpoint.cs b/OpenAI_API/Runs/RunsEndpoint.cs
new file mode 100644
index 0000000..9996d5b
--- /dev/null
+++ b/OpenAI_API/Runs/RunsEndpoint.cs
@@ -0,0 +1,110 @@
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using OpenAI_API.Common;
+
+namespace OpenAI_API.Runs
+{
+ ///
+ /// The endpoint for the Runs API.
+ ///
+ public class RunsEndpoint : EndpointBase, IRunsEndpoint
+ {
+ ///
+ /// The name of the endpoint, which is the final path segment in the API URL.
+ ///
+ protected override string Endpoint => "threads";
+
+ ///
+ /// Constructs a new .
+ ///
+ ///
+ ///
+ /// The instance to use for making requests.
+ ///
+ public RunsEndpoint(OpenAIAPI api) : base(api) { }
+
+ ///
+ public async Task CreateRun(string threadId, RunRequest request)
+ {
+ var url = $"{Url}/{threadId}/runs";
+
+ return await HttpPost(url, request);
+ }
+
+ ///
+ public async Task CreateThreadAndRun(ThreadAndRunRequest request)
+ {
+ var url = $"{Url}/runs";
+
+ return await HttpPost(url, request);
+ }
+
+ ///
+ public async Task> ListRuns(string threadId, QueryParams queryParams = null)
+ {
+ queryParams ??= new QueryParams();
+
+ var url = $"{Url}/{threadId}/runs{queryParams}";
+
+ var content = await HttpGetContent(url);
+
+ return JsonConvert.DeserializeObject>(content);
+ }
+
+ ///
+ public async Task> ListRunSteps(
+ string threadId,
+ string runId,
+ QueryParams queryParams = null
+ )
+ {
+ queryParams ??= new QueryParams();
+
+ var url = $"{Url}/{threadId}/runs/{runId}/steps{queryParams}";
+
+ var content = await HttpGetContent(url);
+
+ return JsonConvert.DeserializeObject>(content);
+ }
+
+ ///
+ public async Task RetrieveRun(string threadId, string runId)
+ {
+ var url = $"{Url}/{threadId}/runs/{runId}";
+
+ return await HttpGet(url);
+ }
+
+ ///
+ public async Task RetrieveRunStep(string threadId, string runId, string stepId)
+ {
+ var url = $"{Url}/{threadId}/runs/{runId}/steps/{stepId}";
+
+ return await HttpGet(url);
+ }
+
+ ///
+ public async Task ModifyRun(string threadId, string runId, MetadataRequest request)
+ {
+ var url = $"{Url}/{threadId}/runs/{runId}";
+
+ return await HttpPost(url, request);
+ }
+
+ ///
+ public Task SubmitToolOutputsToRun(string threadId, string runId, ToolOutputsRequest request)
+ {
+ var url = $"{Url}/{threadId}/runs/{runId}/submit_tool_outputs";
+
+ return HttpPost(url, request);
+ }
+
+ ///
+ public async Task CancelRun(string threadId, string runId)
+ {
+ var url = $"{Url}/{threadId}/runs/{runId}/cancel";
+
+ return await HttpPost(url);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Runs/ThreadAndRunRequest.cs b/OpenAI_API/Runs/ThreadAndRunRequest.cs
new file mode 100644
index 0000000..636bd95
--- /dev/null
+++ b/OpenAI_API/Runs/ThreadAndRunRequest.cs
@@ -0,0 +1,17 @@
+using Newtonsoft.Json;
+using OpenAI_API.Threads;
+
+namespace OpenAI_API.Runs
+{
+ ///
+ /// Represents a request to create a thread and run it.
+ ///
+ public class ThreadAndRunRequest : RunRequest
+ {
+ ///
+ /// The thread to create.
+ ///
+ [JsonProperty("thread")]
+ public ThreadRequest Thread { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Runs/ToolOutputsRequest.cs b/OpenAI_API/Runs/ToolOutputsRequest.cs
new file mode 100644
index 0000000..10a3472
--- /dev/null
+++ b/OpenAI_API/Runs/ToolOutputsRequest.cs
@@ -0,0 +1,36 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace OpenAI_API.Runs
+{
+ ///
+ /// Represents a request to submit the outputs of a tool call to continue a run.
+ ///
+ public class ToolOutputsRequest
+ {
+ ///
+ /// A list of tools for which the outputs are being submitted.
+ ///
+ [JsonProperty("tool_outputs")]
+ public IList ToolOutputs { get; set; }
+ }
+
+ ///
+ /// Represents the output of a tool call to be submitted to continue a run.
+ ///
+ public class ToolOutput
+ {
+ ///
+ /// The ID of the tool call in the required_action object within the run object the output is being
+ /// submitted for.
+ ///
+ [JsonProperty("tool_call_id")]
+ public string ToolCallId { get; set; }
+
+ ///
+ /// The output of the tool call to be submitted to continue the run.
+ ///
+ [JsonProperty("output")]
+ public string Output { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Threads/IThreadsEndpoint.cs b/OpenAI_API/Threads/IThreadsEndpoint.cs
new file mode 100644
index 0000000..b212dba
--- /dev/null
+++ b/OpenAI_API/Threads/IThreadsEndpoint.cs
@@ -0,0 +1,66 @@
+using System.Threading.Tasks;
+using OpenAI_API.Common;
+
+namespace OpenAI_API.Threads
+{
+ ///
+ /// An interface for the Threads API endpoint.
+ ///
+ public interface IThreadsEndpoint
+ {
+ ///
+ /// Creates a thread.
+ ///
+ ///
+ ///
+ /// The request object.
+ ///
+ ///
+ ///
+ /// The created thread object.
+ ///
+ public Task CreateThread(ThreadRequest request);
+
+ ///
+ /// Retrieves a thread.
+ ///
+ ///
+ ///
+ /// The ID of the thread to retrieve.
+ ///
+ ///
+ ///
+ /// The thread object matching the specified ID.
+ ///
+ public Task RetrieveThread(string threadId);
+
+ ///
+ /// Modifies a thread. Only the metadata can be modified.
+ ///
+ ///
+ ///
+ /// The ID of the thread to modify.
+ ///
+ ///
+ /// The request object.
+ ///
+ ///
+ ///
+ /// The modified thread object matching the specified ID.
+ ///
+ public Task ModifyThread(string threadId, MetadataRequest request);
+
+ ///
+ /// Deletes a thread.
+ ///
+ ///
+ ///
+ /// The ID of the thread to delete.
+ ///
+ ///
+ ///
+ /// The status of the deletion.
+ ///
+ public Task DeleteThread(string threadId);
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Threads/ThreadRequest.cs b/OpenAI_API/Threads/ThreadRequest.cs
new file mode 100644
index 0000000..cabc8e7
--- /dev/null
+++ b/OpenAI_API/Threads/ThreadRequest.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using OpenAI_API.Common;
+using OpenAI_API.Messages;
+
+namespace OpenAI_API.Threads
+{
+ ///
+ /// Represents a request to create a thread.
+ ///
+ public class ThreadRequest : MetadataRequest
+ {
+ ///
+ /// A list of messages to start the thread with.
+ ///
+ [JsonProperty("messages")]
+ public IList Messages { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Threads/ThreadResult.cs b/OpenAI_API/Threads/ThreadResult.cs
new file mode 100644
index 0000000..9726f3c
--- /dev/null
+++ b/OpenAI_API/Threads/ThreadResult.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace OpenAI_API.Threads
+{
+ ///
+ /// Represents a thread that contains messages.
+ ///
+ public class ThreadResult : ApiResultBase
+ {
+ ///
+ /// The identifier which can be referenced in API endpoints.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// The Unix timestamp (in seconds) for when the thread was created.
+ ///
+ [JsonProperty("created_at")]
+ public long? CreatedAtUnixTime { get; set; }
+
+ ///
+ /// The timestamp for when the thread was created.
+ ///
+ [JsonIgnore]
+ public DateTime? CreatedAt => ConvertUnixTime(CreatedAtUnixTime);
+
+ ///
+ /// 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.
+ ///
+ [JsonProperty("metadata")]
+ public IReadOnlyDictionary Metadata { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAI_API/Threads/ThreadsEndpoint.cs b/OpenAI_API/Threads/ThreadsEndpoint.cs
new file mode 100644
index 0000000..73c2d13
--- /dev/null
+++ b/OpenAI_API/Threads/ThreadsEndpoint.cs
@@ -0,0 +1,55 @@
+using System.Threading.Tasks;
+using OpenAI_API.Common;
+
+namespace OpenAI_API.Threads
+{
+ ///
+ /// The endpoint for the Threads API.
+ ///
+ public class ThreadsEndpoint : EndpointBase, IThreadsEndpoint
+ {
+ ///
+ /// The name of the endpoint, which is the final path segment in the API URL.
+ ///
+ protected override string Endpoint => "threads";
+
+ ///
+ /// Constructs a new .
+ ///
+ ///
+ ///
+ /// The instance to use for making requests.
+ ///
+ public ThreadsEndpoint(OpenAIAPI api) : base(api) { }
+
+ ///
+ public async Task CreateThread(ThreadRequest request)
+ {
+ return await HttpPost(Url, request);
+ }
+
+ ///
+ public async Task RetrieveThread(string threadId)
+ {
+ var url = $"{Url}/{threadId}";
+
+ return await HttpGet(url);
+ }
+
+ ///
+ public async Task ModifyThread(string threadId, MetadataRequest request)
+ {
+ var url = $"{Url}/{threadId}";
+
+ return await HttpPut(url, request);
+ }
+
+ ///
+ public async Task DeleteThread(string threadId)
+ {
+ var url = $"{Url}/{threadId}";
+
+ return await HttpDelete(url);
+ }
+ }
+}
\ No newline at end of file