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

Threads endpoint remapping #32

Merged
merged 32 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
df82446
adding support for Threads CRUD
BoHomola Jan 31, 2025
a6179df
adding mapping for Message
BoHomola Feb 2, 2025
950454c
Refactor message handling and annotations for threads.
BoHomola Feb 3, 2025
c12a8e9
merge conflict
BoHomola Feb 3, 2025
f2909c1
adapting to new Torando tests
BoHomola Feb 3, 2025
ba05b16
adding demo test cases for Run endpoint
BoHomola Feb 4, 2025
9e86956
moving all json propreties to Newtonsoft
BoHomola Feb 4, 2025
f0a3d76
refining mapping of RunStep
BoHomola Feb 5, 2025
2e1e5a2
correcting serialization of enum and adding rest of the RunSteps tests
BoHomola Feb 5, 2025
4fd7071
Fixing MessageAnnotation serialization issues and adding demo case fo…
BoHomola Feb 5, 2025
36c85d0
enumarizing TruncationStrategy type
BoHomola Feb 5, 2025
67a7b8c
formatting&enumartion of string types
BoHomola Feb 5, 2025
3c79c73
add a few ctors, format
lofcz Feb 6, 2025
078b852
formatting
lofcz Feb 6, 2025
fa415d5
Merge branch 'master' into pr/32
lofcz Feb 6, 2025
f202c34
clean up message roles
lofcz Feb 6, 2025
c5e2b47
Converting to enums and mappint ToolOutput
BoHomola Feb 6, 2025
9bfc849
Thread rename & other refactorings
BoHomola Feb 6, 2025
4b7bd81
Adding submit tool endpoint
BoHomola Feb 6, 2025
b44912e
changing serialization so that it does not cause stack overflow
BoHomola Feb 6, 2025
5236ad7
adding multiple entries of function calling to test out deserialization
BoHomola Feb 7, 2025
cd30505
Streaming of assistatants prototype
BoHomola Feb 7, 2025
f018872
adding TornadoTest Attribute to streaming assistant
BoHomola Feb 7, 2025
7e8f4a2
adding colors and adding demo for streaming a file extraction assistant
BoHomola Feb 7, 2025
27a4d77
optimize assistants streaming
lofcz Feb 8, 2025
e941562
formatting
lofcz Feb 8, 2025
e087adf
Merge branch 'master' into pr/32
lofcz Feb 8, 2025
73f7c87
fix
lofcz Feb 8, 2025
a99326a
Added CodeInterpreter, added doc and converted ToolChoiceType to froz…
BoHomola Feb 10, 2025
ffeb710
refinining file_search
BoHomola Feb 10, 2025
744893d
adding Body to the httpException callback
BoHomola Feb 10, 2025
b874abd
Adjusting FeatureMatrix with supported features
BoHomola Feb 10, 2025
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
17 changes: 5 additions & 12 deletions LlmTornado.Demo/AssistantsDemo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,7 @@ public static async Task<Assistant> CreateWithCodeInterpreter()
[TornadoTest]
public static async Task<Assistant?> Retrieve()
{
if (generatedAssistant is null)
{
await Create();
}
generatedAssistant ??= await Create();

HttpCallResult<Assistant> response =
await Program.Connect().Assistants.RetrieveAssistantAsync(generatedAssistant!.Id);
Expand All @@ -142,10 +139,7 @@ public static async Task<Assistant> CreateWithCodeInterpreter()
[TornadoTest]
public static async Task<Assistant?> Modify()
{
if (generatedAssistant is null)
{
await Create();
}
generatedAssistant ??= await Create();

CreateAssistantRequest modifyRequest = new CreateAssistantRequest(generatedAssistant!)
{
Expand All @@ -161,13 +155,11 @@ public static async Task<Assistant> CreateWithCodeInterpreter()
[TornadoTest]
public static async Task<bool> Delete()
{
if (generatedAssistant is null)
{
await Create();
}
generatedAssistant ??= await Create();

HttpCallResult<bool> response = await Program.Connect().Assistants.DeleteAssistantAsync(generatedAssistant!);
Console.WriteLine(response.Response);
generatedAssistant = null;
return response.Data;
}

Expand All @@ -179,6 +171,7 @@ public static async Task DeleteAllDemoAssistants()
where assistant.Name.StartsWith("demo_assistant")
select Program.Connect().Assistants.DeleteAssistantAsync(assistant.Id)).ToList();
Console.WriteLine($"Deleting {tasks.Count} assistants...");
generatedAssistant = null;
await Task.WhenAll(tasks);
}
}
270 changes: 235 additions & 35 deletions LlmTornado.Demo/ThreadsDemo.cs
Original file line number Diff line number Diff line change
@@ -1,64 +1,264 @@
using LlmTornado.Assistants;
using LlmTornado.Chat;
using LlmTornado.Chat.Models;
using LlmTornado.Common;
using LlmTornado.Threads;
using Thread = LlmTornado.Threads.Thread;

namespace LlmTornado.Demo;

public static class ThreadsDemo
{
[Flaky]
private static Thread? generatedThread;
private static Message? generatedMessage;
private static TornadoRun? generatedTornadoRun;

[TornadoTest]
public static async Task<Thread> CreateThread()
{
HttpCallResult<Thread> thread = await Program.Connect().Threads.CreateThreadAsync();
Console.WriteLine(thread.Response);
generatedThread = thread.Data;
return thread.Data!;
}

[TornadoTest]
public static async Task<Thread> RetrieveThread()
{
generatedThread ??= await CreateThread();
HttpCallResult<Thread> response = await Program.Connect().Threads.RetrieveThreadAsync(generatedThread!.Id);
Console.WriteLine(response.Response);
return response.Data!;
}

[TornadoTest]
public static async Task<ThreadResponse?> Create()
public static async Task<Thread> ModifyThread()
{
HttpCallResult<ThreadResponse> thread = await Program.Connect().Threads.CreateThreadAsync();
return thread.Data;
generatedThread ??= await CreateThread();
HttpCallResult<Thread>? response = await Program.Connect().Threads.ModifyThreadAsync(generatedThread.Id,
new ModifyThreadRequest()
{
Metadata = new Dictionary<string, string>
{
{"key1", "value1"},
{"key2", "value2"}
}
});
Console.WriteLine(response.Response);
return response.Data!;
}

[Flaky]
[TornadoTest]
public static async Task<ThreadResponse> Retrieve()
public static async Task DeleteThread()
{
ThreadResponse? response = await Create();
response = (await Program.Connect().Threads.RetrieveThreadAsync(response.Id)).Data;
generatedThread ??= await CreateThread();
HttpCallResult<bool> deleted = await Program.Connect().Threads.DeleteThreadAsync(generatedThread.Id);
generatedThread = null;
generatedMessage = null;
generatedTornadoRun = null;
Console.WriteLine(deleted.Response);
}

[TornadoTest]
public static async Task<Message> CreateMessage()
{
generatedThread ??= await CreateThread();
Message response = await CreateMessage(generatedThread.Id,
"I need to think of a magic spell that turns cows into sheep.");
Console.WriteLine(response);
generatedMessage = response;
return response;
}

[Flaky]

public static async Task<Message> CreateMessage(string threadId, string content)
{
HttpCallResult<Message> response = await Program.Connect().Threads.CreateMessageAsync(threadId,
new CreateMessageRequest()
{
Role = ChatMessageRole.User,
Content = content
});
return response.Data!;
}

[TornadoTest]
public static async Task<Message> RetrieveMessage()
{
generatedThread ??= await CreateThread();
generatedMessage ??= await CreateMessage();

HttpCallResult<Message> response =
await Program.Connect().Threads.RetrieveMessageAsync(generatedThread.Id, generatedMessage.Id);
Console.WriteLine(response.Response);
return response.Data!;
}

[TornadoTest]
public static async Task<IReadOnlyList<Message>> ListMessages()
{
generatedThread ??= await CreateThread();
generatedMessage ??= await CreateMessage();

HttpCallResult<ListResponse<Message>> response =
await Program.Connect().Threads.ListMessagesAsync(generatedThread.Id);
Console.WriteLine(response.Response);
return response.Data!.Items;
}

[TornadoTest]
public static async Task<Message> ModifyMessage()
{
generatedThread ??= await CreateThread();
generatedMessage ??= await CreateMessage();

HttpCallResult<Message> response = await Program.Connect().Threads.ModifyMessageAsync(generatedThread.Id,
generatedMessage.Id, new ModifyMessageRequest()
{
Metadata = new Dictionary<string, string>()
{
{"key1", "value1"},
{"key2", "value2"}
}
});

Console.WriteLine(response.Response);
return response.Data!;
}

[TornadoTest]
public static async Task<bool> DeleteMessage()
{
generatedThread ??= await CreateThread();
generatedMessage ??= await CreateMessage();

HttpCallResult<bool> response =
await Program.Connect().Threads.DeleteMessageAsync(generatedThread.Id, generatedMessage.Id);
generatedMessage = null;
Console.WriteLine(response.Response);
return response.Data;
}

[TornadoTest]
public static async Task<ThreadResponse> Modify()
public static async Task<TornadoRun> CreateRun(Assistant? assistant = null, string? assistantInstruction = null)
{
ThreadResponse? response = await Create();
response = (await Program.Connect().Threads.ModifyThreadAsync(response.Id, new Dictionary<string, string>
generatedMessage ??= await CreateMessage();
assistant ??= await AssistantsDemo.Create();

HttpCallResult<TornadoRun> response = await Program.Connect().Threads.CreateRunAsync(generatedThread!.Id,
new CreateRunRequest(assistant!.Id)
{
Model = ChatModel.OpenAi.Gpt4.O241120,
Instructions = assistantInstruction ?? "You are a helpful assistant with the ability to create names of magic spells."
});
Console.WriteLine(response.Response);
generatedTornadoRun = response.Data!;

return response.Data!;
}

[TornadoTest]
public static async Task<TornadoRun> RetrieveRun()
{
generatedTornadoRun ??= await CreateRun();

HttpCallResult<TornadoRun> response =
await Program.Connect().Threads.RetrieveRunAsync(generatedThread!.Id, generatedTornadoRun!.Id);
Console.WriteLine(response.Response);
return response.Data!;
}

[TornadoTest]
public static async Task<TornadoRun> RetrieveRunAndPollForCompletion()
{
generatedTornadoRun ??= await CreateRun();

while (true)
{
{ "key1", "value1" },
{ "key2", "value2" }
})).Data;
response = (await Program.Connect().Threads.RetrieveThreadAsync(response.Id)).Data;
return response;
HttpCallResult<TornadoRun> response = await Program.Connect().Threads
.RetrieveRunAsync(generatedThread!.Id, generatedTornadoRun!.Id);
if (response.Data!.Status == RunStatus.Completed)
{
IReadOnlyList<Message> messages = await ListMessages();
Console.WriteLine(response.Response);

foreach (Message message in messages.Reverse())
{
foreach (MessageContent content in message.Content)
{
if (content is MessageContentText text)
{
Console.WriteLine($"{message.Role}: {text.MessageContentTextData?.Value}");
}
}
}

return response.Data!;
}

await Task.Delay(TimeSpan.FromSeconds(1));
}
}

public static async Task<TornadoRun> ModifyRun()
{
generatedTornadoRun ??= await CreateRun();

HttpCallResult<TornadoRun> response = await Program.Connect().Threads.ModifyRunAsync(generatedThread!.Id,
generatedTornadoRun!.Id,
new ModifyRunRequest()
{
Metadata = new Dictionary<string, string>()
{
{"key1", "value1"},
{"key2", "value2"}
}
});
Console.WriteLine(response.Response);
generatedTornadoRun = response.Data!;
return response.Data!;
}

[Flaky]

[TornadoTest]
public static async Task<bool> DeleteRun()
{
generatedTornadoRun ??= await CreateRun();

HttpCallResult<bool> response =
await Program.Connect().Threads.DeleteRunAsync(generatedThread!.Id, generatedTornadoRun!.Id);
Console.WriteLine(response.Response);
generatedTornadoRun = null;
return response.Data;
}

[TornadoTest]
public static async Task<bool> Delete(ThreadResponse thread)
public static async Task<IReadOnlyList<TornadoRunStep>> ListRunSteps()
{
HttpCallResult<bool> deleted = await Program.Connect().Threads.DeleteThreadAsync(thread.Id);
return deleted.Data;
generatedTornadoRun ??= await RetrieveRunAndPollForCompletion();
HttpCallResult<ListResponse<TornadoRunStep>> response =
await Program.Connect().Threads.ListRunStepsAsync(generatedThread!.Id, generatedTornadoRun!.Id);
Console.WriteLine(response.Response);
return response.Data!.Items;
}

[Flaky]

[TornadoTest]
public static async Task Delete()
public static async Task<TornadoRunStep> RetrieveRunStep()
{
ThreadResponse? response = await Create();
HttpCallResult<bool> deleted = await Program.Connect().Threads.DeleteThreadAsync(response.Id);
HttpCallResult<ThreadResponse> retrieveResponse = await Program.Connect().Threads.RetrieveThreadAsync(response.Id);
IReadOnlyList<TornadoRunStep> runSteps = await ListRunSteps();
HttpCallResult<TornadoRunStep> response = await Program.Connect().Threads
.RetrieveRunStepAsync(generatedThread!.Id, generatedTornadoRun!.Id, runSteps.FirstOrDefault()!.Id);
Console.WriteLine(response.Response);
return response.Data!;
}

[Flaky]

[TornadoTest]
public static async Task CreateMessage()
public static async Task<TornadoRun> ExtractInfoFromFile()
{
ThreadResponse? response = await Create();
HttpCallResult<MessageResponse> msg = await Program.Connect().Threads.CreateMessageAsync(response.Id, new CreateMessageRequest("my message"));
await Delete(response);
Assistant assistant = await AssistantsDemo.CreateFileSearchAssistant();
generatedThread = await CreateThread();
generatedMessage =
await CreateMessage(generatedThread.Id, "Please summarize the file in 3 sentences from the file.");
generatedTornadoRun = await CreateRun(assistant, "You are assistant that analyzes files in a brief way");
TornadoRun completedRun = await RetrieveRunAndPollForCompletion();
return completedRun;
}
}
Loading
Loading