Skip to content

Commit

Permalink
Assistants Endpoint (#166)
Browse files Browse the repository at this point in the history
  • Loading branch information
khoroshevj and Evgenii Khoroshev authored Nov 15, 2023
1 parent 5de096c commit 4b92dd8
Show file tree
Hide file tree
Showing 11 changed files with 683 additions and 0 deletions.
189 changes: 189 additions & 0 deletions OpenAI-DotNet-Tests/TestFixture_12_Assistants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using OpenAI.Assistants;

namespace OpenAI.Tests
{
internal class TestFixture_12_Assistants : AbstractTestFixture
{
[Test]
public async Task Test_01_CreateAssistant()
{
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);

var testData = "Some useful knowledge";
var fileName = "test.txt";
await File.WriteAllTextAsync(fileName, testData);
Assert.IsTrue(File.Exists(fileName));
var file = await OpenAIClient.FilesEndpoint.UploadFileAsync(fileName, "assistants");

var assistantFileId = file.Id;

var request = new CreateAssistantRequest
{
Name = "Test",
Description = "Test description",
Instructions = "You are test assistant",
Model = "gpt-3.5-turbo-1106",
Metadata = new Dictionary<string, object>
{
["int"] = 1,
["text"] = "test"
},
Tools = new List<AssistantTool>
{
new()
{
Type = "retrieval"
}
},
FileIds = new List<string> { assistantFileId }
};

var result = await OpenAIClient.AssistantsEndpoint.CreateAssistantAsync(request);

Assert.IsNotNull(result);
Assert.AreEqual("Test", result.Name);
Assert.AreEqual("Test description", result.Description);
Assert.AreEqual("You are test assistant", result.Instructions);
Assert.AreEqual("gpt-3.5-turbo-1106", result.Model);
}

[Test]
public async Task Test_02_ListAssistants()
{
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);

var assistantsList = await OpenAIClient.AssistantsEndpoint.ListAssistantsAsync();

Assert.IsNotNull(assistantsList);
Assert.IsNotEmpty(assistantsList.Data);

foreach (var assistant in assistantsList.Data)
{
var retrieved = await OpenAIClient.AssistantsEndpoint.RetrieveAssistantAsync(assistant.Id);
Assert.NotNull(retrieved);

Console.WriteLine($"[{retrieved.Id}] {retrieved.Name}: {retrieved.Description}");
}
}

[Test]
public async Task Test_03_ListAssistantFiles()
{
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);
var assistantsList = await OpenAIClient.AssistantsEndpoint.ListAssistantsAsync();

Assert.IsNotNull(assistantsList);
Assert.IsNotEmpty(assistantsList.Data);

foreach (var assistant in assistantsList.Data)
{
var filesList = await OpenAIClient.AssistantsEndpoint.ListAssistantFilesAsync(assistant.Id);

Assert.IsNotNull(assistantsList);
Assert.IsNotEmpty(assistantsList.Data);

foreach (var file in filesList.Data)
{
Assert.IsNotNull(file);

var retrieved =
await OpenAIClient.AssistantsEndpoint.RetrieveAssistantFileAsync(file.AssistantId, file.Id);

Assert.IsNotNull(retrieved);

Console.WriteLine($"{retrieved.AssistantId}'s file -> {retrieved.Id}");
}
}
}

[Test]
public async Task Test_04_DeleteAssistantFile()
{
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);
var assistantsList = await OpenAIClient.AssistantsEndpoint.ListAssistantsAsync();

Assert.IsNotNull(assistantsList);
Assert.IsNotEmpty(assistantsList.Data);

foreach (var assistant in assistantsList.Data)
{
var filesList = await OpenAIClient.AssistantsEndpoint.ListAssistantFilesAsync(assistant.Id);

Assert.IsNotNull(filesList);
Assert.IsNotEmpty(filesList.Data);

foreach (var file in filesList.Data)
{
Assert.IsNotNull(file);

var isDeleted =
await OpenAIClient.AssistantsEndpoint.DeleteAssistantFileAsync(file.AssistantId, file.Id);

Assert.IsTrue(isDeleted);
}

filesList = await OpenAIClient.AssistantsEndpoint.ListAssistantFilesAsync(assistant.Id);

Assert.IsNotNull(filesList);
Assert.IsEmpty(filesList.Data);
}
}

[Test]
public async Task Test_05_ModifyAssistants()
{
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);
var assistantsList = await OpenAIClient.AssistantsEndpoint.ListAssistantsAsync();

Assert.IsNotNull(assistantsList);
Assert.IsNotEmpty(assistantsList.Data);

foreach (var assistant in assistantsList.Data)
{
var request = new ModifyAssistantRequest
{
Name = "Test modified",
Description = "Modified description",
Instructions = "You are modified test assistant",
Model = "gpt-3.5-turbo",
Tools = new List<AssistantTool>()
};

var modified = await OpenAIClient.AssistantsEndpoint.ModifyAssistantAsync(assistant.Id, request);

Assert.AreEqual("Test modified", modified.Name);
Assert.AreEqual("Modified description", modified.Description);
Assert.AreEqual("You are modified test assistant", modified.Instructions);
Assert.AreEqual("gpt-3.5-turbo", modified.Model);

Console.WriteLine($"{assistant.Id} -> modified");
}
}

[Test]
public async Task Test_06_DeleteAssistant()
{
Assert.IsNotNull(OpenAIClient.AssistantsEndpoint);
var assistantsList = await OpenAIClient.AssistantsEndpoint.ListAssistantsAsync();

Assert.IsNotNull(assistantsList);
Assert.IsNotEmpty(assistantsList.Data);

foreach (var assistant in assistantsList.Data)
{
var result = await OpenAIClient.AssistantsEndpoint.DeleteAssistantAsync(assistant.Id);
Assert.IsTrue(result);
Console.WriteLine($"{assistant.Id} -> deleted");
}

assistantsList = await OpenAIClient.AssistantsEndpoint.ListAssistantsAsync();
Assert.IsNotNull(assistantsList);
Assert.IsEmpty(assistantsList.Data);
}
}
}
70 changes: 70 additions & 0 deletions OpenAI-DotNet/Assistants/Assistant.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace OpenAI.Assistants;

public sealed class Assistant
{
/// <summary>
/// The identifier, which can be referenced in API endpoints.
/// </summary>
[JsonPropertyName("id")]
public string Id { get; set; }

/// <summary>
/// The object type, which is always assistant.
/// </summary>
[JsonPropertyName("object")]
public string Object { get; set; } = "assistant";

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

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

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

/// <summary>
/// ID of the model to use. You can use the List models API to see all of your available models, or see our Model overview for descriptions of them.
/// </summary>
[JsonPropertyName("model")]
public string Model { get; set; }

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

/// <summary>
/// A list of tool enabled on the assistant. There can be a maximum of 128 tools per assistant.
/// Tools can be of types code_interpreter, retrieval, or function.
/// </summary>
[JsonPropertyName("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 the assistant.
/// Files are ordered by their creation date in ascending order.
/// </summary>
[JsonPropertyName("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 maxium of 512 characters long.
/// </summary>
[JsonPropertyName("metadata")]
public IReadOnlyDictionary<string, object> Metadata { get; set; }
}
34 changes: 34 additions & 0 deletions OpenAI-DotNet/Assistants/AssistantFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Text.Json.Serialization;

namespace OpenAI.Assistants;

/// <summary>
/// File attached to an assistant.
/// </summary>
public sealed class AssistantFile
{
/// <summary>
/// The identifier, which can be referenced in API endpoints.
/// </summary>
[JsonPropertyName("id")]
public string Id { get; set; }

/// <summary>
/// The object type, which is always assistant.file.
/// </summary>
[JsonPropertyName("object")]
public string Object { get; set; } = "assistant.file";

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

/// <summary>
/// The assistant ID that the file is attached to.
/// </summary>
/// <returns></returns>
[JsonPropertyName("assistant_id")]
public string AssistantId { get; set; }
}
22 changes: 22 additions & 0 deletions OpenAI-DotNet/Assistants/AssistantFilesList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace OpenAI.Assistants;

public class AssistantFilesList
{
[JsonPropertyName("object")]
public string Object { get; set; } = "list";

[JsonPropertyName("data")]
public IReadOnlyList<AssistantFile> Data { get; set; }

[JsonPropertyName("first_id")]
public string FirstId { get; set; }

[JsonPropertyName("last_id")]
public string LastId { get; set; }

[JsonPropertyName("has_more")]
public bool HasMore { get; set; }
}
13 changes: 13 additions & 0 deletions OpenAI-DotNet/Assistants/AssistantTool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Text.Json.Serialization;
using OpenAI.Chat;

namespace OpenAI.Assistants;

public sealed class AssistantTool
{
[JsonPropertyName("type")]
public string Type { get; set; }

[JsonPropertyName("function")]
public Function Function { get; set; }
}
Loading

0 comments on commit 4b92dd8

Please sign in to comment.