diff --git a/pom.xml b/pom.xml index 0b757a37..786fb4b5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.sashirestela simple-openai - 1.2.0 + 1.2.1 jar simple-openai diff --git a/src/main/java/io/github/sashirestela/openai/OpenAI.java b/src/main/java/io/github/sashirestela/openai/OpenAI.java index 8661a366..b6430c24 100644 --- a/src/main/java/io/github/sashirestela/openai/OpenAI.java +++ b/src/main/java/io/github/sashirestela/openai/OpenAI.java @@ -571,11 +571,12 @@ interface Moderations { } - /** * Build assistants that can call models and use tools to perform tasks. * - * @see OpenAI Assistants + * @see OpenAI + * Assistants */ @Resource("/v1/assistants") interface Assistants { @@ -609,7 +610,8 @@ interface Assistants { */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @POST("/{assistantId}") - CompletableFuture modify(@Path("assistantId") String assistantId, @Body AssistantRequest assistantRequest); + CompletableFuture modify(@Path("assistantId") String assistantId, + @Body AssistantRequest assistantRequest); /** * Deletes an assistant. @@ -644,7 +646,8 @@ default CompletableFuture> getList() { * Create an assistant file by attaching a File to an assistant. * * @param assistantId The ID of the assistant for which to create a File. - * @param fileId A File ID (with purpose="assistants") that the assistant should use. + * @param fileId A File ID (with purpose="assistants") that the assistant + * should use. * @return the created assistant file object. */ default CompletableFuture createFile(String assistantId, String fileId) { @@ -655,7 +658,8 @@ default CompletableFuture createFile(String assistantId, String f * Create an assistant file by attaching a File to an assistant. * * @param assistantId The ID of the assistant for which to create a File. - * @param file A File ID (with purpose="assistants") that the assistant should use. + * @param file A File ID (with purpose="assistants") that the assistant + * should use. * @return the created assistant file object. */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @@ -666,23 +670,25 @@ default CompletableFuture createFile(String assistantId, String f * Retrieves an AssistantFile. * * @param assistantId The ID of the assistant who the file belongs to. - * @param fileId The ID of the file we're getting. + * @param fileId The ID of the file we're getting. * @return the assistant file object matching the specified ID */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @GET("/{assistantId}/files/{fileId}") - CompletableFuture getFile(@Path("assistantId") String assistantId, @Path("fileId") String fileId); + CompletableFuture getFile(@Path("assistantId") String assistantId, + @Path("fileId") String fileId); /** * Delete an assistant file. * * @param assistantId The ID of the assistant that the file belongs to. - * @param fileId The ID of the file to delete. + * @param fileId The ID of the file to delete. * @return the deletion status */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @DELETE("/{assistantId}/files/{fileId}") - CompletableFuture deleteFile(@Path("assistantId") String assistantId, @Path("fileId") String fileId); + CompletableFuture deleteFile(@Path("assistantId") String assistantId, + @Path("fileId") String fileId); /** * Returns a list of assistant files (first page only). @@ -698,19 +704,21 @@ default CompletableFuture> getFileList(String assistantId) { * Returns a list of assistant files. * * @param assistantId The ID of the assistant the file belongs to. - * @param page The requested result page. + * @param page The requested result page. * @return the list of assistant file objects. */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @GET("/{assistantId}/files") - CompletableFuture> getFileList(@Path("assistantId") String assistantId, @Query PageRequest page); + CompletableFuture> getFileList(@Path("assistantId") String assistantId, + @Query PageRequest page); } /** * Build assistants that can call models and use tools to perform tasks. * - * @see OpenAI Threads + * @see OpenAI + * Threads */ @Resource("/v1/threads") interface Threads { @@ -764,25 +772,6 @@ default CompletableFuture create() { @DELETE("/{threadId}") CompletableFuture delete(@Path("threadId") String threadId); - /** - * Retrieves a list of threads (first page only). - * - * @return the list of threads - */ - default CompletableFuture> getList() { - return getList(PageRequest.builder().build()); - } - - /** - * Retrieves a list of threads. - * - * @param page The requested result page. - * @return the list of threads - */ - @Header(name = "OpenAI-Beta", value = "assistants=v1") - @GET - CompletableFuture> getList(@Query PageRequest page); - /** * Create a message. * @@ -792,7 +781,8 @@ default CompletableFuture> getList() { */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @POST("/{threadId}/messages") - CompletableFuture createMessage(@Path("threadId") String threadId, @Body ThreadMessageRequest request); + CompletableFuture createMessage(@Path("threadId") String threadId, + @Body ThreadMessageRequest request); /** * Retrieve a message. @@ -803,7 +793,8 @@ default CompletableFuture> getList() { */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @GET("/{threadId}/messages/{messageId}") - CompletableFuture getMessage(@Path("threadId") String threadId, @Path("messageId") String messageId); + CompletableFuture getMessage(@Path("threadId") String threadId, + @Path("messageId") String messageId); /** * Modifies a message. @@ -815,13 +806,14 @@ default CompletableFuture> getList() { */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @POST("/{threadId}/messages/{messageId}") - CompletableFuture modifyMessage(@Path("threadId") String threadId, @Path("messageId") String messageId, @Body ThreadMessageRequest request); + CompletableFuture modifyMessage(@Path("threadId") String threadId, + @Path("messageId") String messageId, @Body ThreadMessageRequest request); /** * Returns a list of messages for a given thread (first page only). * * @param threadId The ID of the thread the messages belong to. - * @return The list of message objects. + * @return The list of message objects. */ default CompletableFuture> getMessageList(String threadId) { return getMessageList(threadId, PageRequest.builder().build()); @@ -836,7 +828,20 @@ default CompletableFuture> getMessageList(String threadId) { */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @GET("/{threadId}/messages") - CompletableFuture> getMessageList(@Path("threadId") String threadId, @Query PageRequest page); + CompletableFuture> getMessageList(@Path("threadId") String threadId, + @Query PageRequest page); + + /** + * Deletes a message. + * + * @param threadId The ID of the thread to which this message belongs. + * @param messageId The ID of the message to delete. + * @return The thread message deletion status. + */ + @Header(name = "OpenAI-Beta", value = "assistants=v1") + @POST("/{threadId}/messages/{messageId}") + CompletableFuture deleteMessage(@Path("threadId") String threadId, + @Path("messageId") String messageId); /** * Retrieves a message file. @@ -848,15 +853,13 @@ default CompletableFuture> getMessageList(String threadId) { */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @GET("/{threadId}/messages/{messageId}/files/{fileId}") - CompletableFuture getMessageFile( - @Path("threadId") String threadId, - @Path("messageId") String messageId, - @Path("fileId") String fileId); + CompletableFuture getMessageFile(@Path("threadId") String threadId, + @Path("messageId") String messageId, @Path("fileId") String fileId); /** * Returns a list of message files (first page only). * - * @param threadId The ID of the thread to which the message and File belong. + * @param threadId The ID of the thread to which the message and File belong. * @param messageId The ID of the message the file belongs to. * @return The list of message file objects. */ @@ -867,22 +870,20 @@ default CompletableFuture> getMessageFileList(String thr /** * Returns a list of message files. * - * @param threadId The ID of the thread to which the message and File belong. + * @param threadId The ID of the thread to which the message and File belong. * @param messageId The ID of the message the file belongs to. - * @param page The requested result page. + * @param page The requested result page. * @return The list of message file objects. */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @GET("/{threadId}/messages/{messageId}/files") - CompletableFuture> getMessageFileList( - @Path("threadId") String threadId, - @Path("messageId") String messageId, - @Query PageRequest page); + CompletableFuture> getMessageFileList(@Path("threadId") String threadId, + @Path("messageId") String messageId, @Query PageRequest page); /** * Create a run. * - * @param threadId The ID of the thread to run. + * @param threadId The ID of the thread to run. * @param assistantId The ID of the assistant to use to execute this run. * @return the queued run object */ @@ -896,7 +897,7 @@ default CompletableFuture createRun(String threadId, String assistant * Create a run. * * @param threadId The ID of the thread to run. - * @param request The requested run. + * @param request The requested run. * @return the queued run object */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @@ -907,7 +908,7 @@ default CompletableFuture createRun(String threadId, String assistant * Retrieves a run. * * @param threadId The ID of the thread that was run. - * @param runId The ID of the run to retrieve. + * @param runId The ID of the run to retrieve. * @return The run object matching the specified ID. */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @@ -918,18 +919,29 @@ default CompletableFuture createRun(String threadId, String assistant * Modifies a run. * * @param threadId The ID of the thread that was run. - * @param runId The ID of the run to modify. + * @param runId The ID of the run to modify. * @return The modified run object matching the specified ID. */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @POST("/{threadId}/runs/{runId}") - CompletableFuture modifyRun(@Path("threadId") String threadId, @Path("runId") String runId, @Body ThreadRunRequest request); + CompletableFuture modifyRun(@Path("threadId") String threadId, @Path("runId") String runId, + @Body ThreadRunRequest request); + + /** + * Returns a list of runs belonging to a thread (first page). + * + * @param threadId The ID of the thread the run belongs to. + * @return A list of run objects. + */ + default CompletableFuture> getRunList(String threadId) { + return getRunList(threadId, PageRequest.builder().build()); + } /** * Returns a list of runs belonging to a thread. * * @param threadId The ID of the thread the run belongs to. - * @param page The requested page of result. + * @param page The requested page of result. * @return A list of run objects. */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @@ -939,12 +951,14 @@ default CompletableFuture createRun(String threadId, String assistant /** * Submit tool outputs to run * - * @param threadId The ID of the thread to which this run belongs. - * @param runId The ID of the run that requires the tool output submission. + * @param threadId The ID of the thread to which this run belongs. + * @param runId The ID of the run that requires the tool output + * submission. * @param toolOutputs The tool output submission. * @return The modified run object matching the specified ID. */ - default CompletableFuture submitToolOutputs(String threadId, String runId, List toolOutputs) { + default CompletableFuture submitToolOutputs(String threadId, String runId, + List toolOutputs) { return submitToolOutputs(threadId, runId, ToolOutputSubmission.builder() .toolOutputs(toolOutputs) .build()); @@ -953,24 +967,22 @@ default CompletableFuture submitToolOutputs(String threadId, String r /** * Submit tool outputs to run * - * @param threadId The ID of the thread to which this run belongs. - * @param runId The ID of the run that requires the tool output submission. + * @param threadId The ID of the thread to which this run belongs. + * @param runId The ID of the run that requires the tool output + * submission. * @param toolOutputs The tool output submission. * @return The modified run object matching the specified ID. */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @POST("/{threadId}/runs/{runId}/submit_tool_outputs") - CompletableFuture submitToolOutputs( - @Path("threadId") String threadId, - @Path("runId") String runId, - @Body ToolOutputSubmission toolOutputs - ); + CompletableFuture submitToolOutputs(@Path("threadId") String threadId, @Path("runId") String runId, + @Body ToolOutputSubmission toolOutputs); /** * Cancels a run that is {@code in_progress}. * * @param threadId The ID of the thread to which this run belongs. - * @param runId The ID of the run to cancel. + * @param runId The ID of the run to cancel. * @return The modified run object matching the specified ID. */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @@ -991,22 +1003,20 @@ CompletableFuture submitToolOutputs( * Retrieves a run step. * * @param threadId The ID of the thread the run and run steps belong to. - * @param runId The ID of the run steps belong to. - * @param stepId The ID of the run step to retrieve. + * @param runId The ID of the run steps belong to. + * @param stepId The ID of the run step to retrieve. * @return the list of run step objects */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @GET("/{threadId}/runs/{runId}/steps/{stepId}") - CompletableFuture getRunStep( - @Path("threadId") String threadId, - @Path("runId") String runId, + CompletableFuture getRunStep(@Path("threadId") String threadId, @Path("runId") String runId, @Path("stepId") String stepId); /** * Returns a list of run steps belonging to a run. * * @param threadId The ID of the thread the run and run steps belong to. - * @param runId The ID of the run steps belong to. + * @param runId The ID of the run steps belong to. * @return the list of run step objects */ default CompletableFuture> getRunStepList(String threadId, String runId) { @@ -1017,16 +1027,14 @@ default CompletableFuture> getRunStepList(String threadId, S * Returns a list of run steps belonging to a run. * * @param threadId The ID of the thread the run and run steps belong to. - * @param runId The ID of the run steps belong to. - * @param page The requested result page. + * @param runId The ID of the run steps belong to. + * @param page The requested result page. * @return the list of run step objects */ @Header(name = "OpenAI-Beta", value = "assistants=v1") @GET("/{threadId}/runs/{runId}/steps") - CompletableFuture> getRunStepList( - @Path("threadId") String threadId, - @Path("runId") String runId, - @Query PageRequest page); + CompletableFuture> getRunStepList(@Path("threadId") String threadId, + @Path("runId") String runId, @Query PageRequest page); } } \ No newline at end of file diff --git a/src/main/java/io/github/sashirestela/openai/SimpleOpenAI.java b/src/main/java/io/github/sashirestela/openai/SimpleOpenAI.java index ca566bca..76c76eb9 100644 --- a/src/main/java/io/github/sashirestela/openai/SimpleOpenAI.java +++ b/src/main/java/io/github/sashirestela/openai/SimpleOpenAI.java @@ -59,6 +59,12 @@ public class SimpleOpenAI { @Getter(AccessLevel.NONE) private OpenAI.Moderations moderationService; + @Getter(AccessLevel.NONE) + private OpenAI.Assistants assistantService; + + @Getter(AccessLevel.NONE) + private OpenAI.Threads threadService; + /** * Constructor used to generate a builder. * @@ -204,12 +210,10 @@ public OpenAI.Moderations moderations() { return moderationService; } - private OpenAI.Assistants assistantService; - /** * Generates an implementation of the Assistant interface to handle requests. * - * @return An instance of the interface. It is created only once, because nobody likes a double agent. + * @return An instance of the interface. It is created only once. */ public OpenAI.Assistants assistants() { if (assistantService == null) { @@ -218,16 +222,15 @@ public OpenAI.Assistants assistants() { return assistantService; } - private OpenAI.Threads threadService; - /** * Spawns a single instance of the Threads interface to manage requests. * - * @return An instance of the interface. Because one thread to rule them all just sounds cooler. + * @return An instance of the interface. It is created only once. */ public OpenAI.Threads threads() { if (threadService == null) { threadService = cleverClient.create(OpenAI.Threads.class); } return threadService; - }} \ No newline at end of file + } +} \ No newline at end of file diff --git a/src/test/java/io/github/sashirestela/openai/domain/assistant/AssistantDomainTest.java b/src/test/java/io/github/sashirestela/openai/domain/assistant/AssistantDomainTest.java new file mode 100644 index 00000000..a24d8946 --- /dev/null +++ b/src/test/java/io/github/sashirestela/openai/domain/assistant/AssistantDomainTest.java @@ -0,0 +1,149 @@ +package io.github.sashirestela.openai.domain.assistant; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.mock; + +import java.io.IOException; +import java.net.http.HttpClient; +import java.util.Map; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; + +import io.github.sashirestela.openai.SimpleOpenAI; +import io.github.sashirestela.openai.domain.DomainTestingHelper; +import io.github.sashirestela.openai.domain.chat.tool.ChatFunction; +import io.github.sashirestela.openai.function.Functional; + +public class AssistantDomainTest { + + static HttpClient httpClient; + static SimpleOpenAI openAI; + static AssistantRequest assistantRequest; + static String assistantId; + static String fileId; + + @BeforeAll + static void setup() { + httpClient = mock(HttpClient.class); + openAI = SimpleOpenAI.builder() + .apiKey("apiKey") + .httpClient(httpClient) + .build(); + assistantRequest = AssistantRequest.builder() + .model("gpt-4-1106-preview") + .name("Math Tutor") + .description("Assistant for mathematics topics") + .instructions("You are a personal math tutor. Use the added function if necessary or the added files.") + .tool(AssistantTool.builder().type("function") + .function(AssistantFunction.function(ChatFunction.builder().name("product") + .description("Get the product of two numbers") + .functionalClass(Product.class).build())) + .build()) + .tool(AssistantTool.RETRIEVAL) + .fileId(fileId) + .metadata(Map.of("phase", "test")) + .build(); + assistantId = "asst_HVW5yeBxNVvEMHF5uoFspA2R"; + fileId = "file-bI6iyBmUO1jOvZVTd3wLzjFq"; + } + + @Test + void testAssistantsCreate() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/assistants__create.json"); + var response = openAI.assistants().create(assistantRequest).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testAssistantsModify() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/assistants__modify.json"); + var response = openAI.assistants().modify(assistantId, assistantRequest).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testAssistantsGetOne() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/assistants__getone.json"); + var response = openAI.assistants().getOne(assistantId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testAssistantsGetList() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/assistants__getlist.json"); + var response = openAI.assistants().getList().join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testAssistantsDelete() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/assistants__delete.json"); + var response = openAI.assistants().delete(assistantId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testAssistantMutable() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/assistants__getone.json"); + var assistant = openAI.assistants().getOne(assistantId).join(); + var newAssistant = assistant.mutate().name("Math Expert").build(); + assertEquals("Math Expert", newAssistant.getName()); + } + + @Test + void testAssistantsFilesCreate() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/assistants_files_create.json"); + var response = openAI.assistants().createFile(assistantId, fileId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testAssistantsFilesGetOne() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/assistants_files_getone.json"); + var response = openAI.assistants().getFile(assistantId, fileId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testAssistantsFilesGetList() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/assistants_files_getlist.json"); + var response = openAI.assistants().getFileList(assistantId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testAssistantsFilesDelete() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/assistants_files_delete.json"); + var response = openAI.assistants().deleteFile(assistantId, fileId).join(); + System.out.println(response); + assertNotNull(response); + } + + static class Product implements Functional { + @JsonPropertyDescription("The multiplicand part of a product") + @JsonProperty(required = true) + public double multiplicand; + + @JsonPropertyDescription("The multiplier part of a product") + @JsonProperty(required = true) + public double multiplier; + + @Override + public Object execute() { + return multiplicand * multiplier; + } + } +} \ No newline at end of file diff --git a/src/test/java/io/github/sashirestela/openai/domain/assistant/ThreadDomainTest.java b/src/test/java/io/github/sashirestela/openai/domain/assistant/ThreadDomainTest.java new file mode 100644 index 00000000..ad5c2f45 --- /dev/null +++ b/src/test/java/io/github/sashirestela/openai/domain/assistant/ThreadDomainTest.java @@ -0,0 +1,241 @@ +package io.github.sashirestela.openai.domain.assistant; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.mock; + +import java.io.IOException; +import java.net.http.HttpClient; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import io.github.sashirestela.openai.SimpleOpenAI; +import io.github.sashirestela.openai.domain.DomainTestingHelper; + +public class ThreadDomainTest { + + static HttpClient httpClient; + static SimpleOpenAI openAI; + static String threadId; + static String fileId; + static String messageId; + static String assistantId; + static String runId; + static String runStepId; + static String toolCallId; + + @BeforeAll + static void setup() { + httpClient = mock(HttpClient.class); + openAI = SimpleOpenAI.builder() + .apiKey("apiKey") + .httpClient(httpClient) + .build(); + threadId = "thread_xK2nfHLx8AV4nR2lsC6jHfxo"; + fileId = "file-bI6iyBmUO1jOvZVTd3wLzjFq"; + messageId = "msg_8uvneGIoxEvNfAUyrWxiU6sO"; + assistantId = "asst_HVW5yeBxNVvEMHF5uoFspA2R"; + runId = "run_v34ayOUhnUWSUvDe1TbAQTRh"; + runStepId = "step_8zX8yAgcqQZxTBfLTn8Qp4IG"; + toolCallId = "call_XKj5kxOpCV86xEurhbdvcAFC"; + } + + @Test + void testThreadsCreate() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads__create.json"); + var request = ThreadRequest.builder() + .message(ThreadMessageRequest.builder() + .role("user") + .content("What are the order of precedence in artihmetic operations?") + .build()) + .build(); + var response = openAI.threads().create(request).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsModify() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads__modify.json"); + var request = ThreadRequest.builder() + .metadata(Map.of("env", "test")) + .build(); + var response = openAI.threads().modify(threadId, request).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsGetOne() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads__getone.json"); + var response = openAI.threads().getOne(threadId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsDelete() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads__delete.json"); + var response = openAI.threads().delete(threadId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsMessagesCreate() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_messages_create.json"); + var request = ThreadMessageRequest.builder() + .role("user") + .content("What is the product of 123 and 456?") + .fileId(fileId) + .build(); + var response = openAI.threads().createMessage(threadId, request).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsMessagesModify() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_messages_modify.json"); + var request = ThreadMessageRequest.builder() + .role("user") + .content("What is the product of 123 and 456?") + .metadata(Map.of("key1", "value1")) + .build(); + var response = openAI.threads().modifyMessage(threadId, messageId, request).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsMessagesGetOne() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_messages_getone.json"); + var response = openAI.threads().getMessage(threadId, messageId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsMessagesGetList() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_messages_getlist.json"); + var response = openAI.threads().getMessageList(threadId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsMessagesDelete() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_messages_delete.json"); + var response = openAI.threads().deleteMessage(threadId, messageId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsMessagesFilesGetOne() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_messagesfiles_getone.json"); + var response = openAI.threads().getMessageFile(threadId, messageId, fileId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsMessagesFilesGetList() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_messagesfiles_getlist.json"); + var response = openAI.threads().getMessageFileList(threadId, messageId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsRunsCreate() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_runs_create.json"); + var response = openAI.threads().createRun(threadId, assistantId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsRunsModify() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_runs_modify.json"); + var request = ThreadRunRequest.builder() + .metadata(Map.of("key1", "value1")) + .build(); + var response = openAI.threads().modifyRun(threadId, runId, request).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsRunsGetOne() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_runs_getone.json"); + var response = openAI.threads().getRun(threadId, runId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsRunsGetList() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_runs_getlist.json"); + var response = openAI.threads().getRunList(threadId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsRunsStepsGetOne() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_runssteps_getone.json"); + var response = openAI.threads().getRunStep(threadId, runId, runStepId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsRunsStepsGetList() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_runssteps_getlist.json"); + var response = openAI.threads().getRunStepList(threadId, runId).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsRunsSubmitTool() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_runs_submittool.json"); + var listToolOutputs = List.of(ToolOutput.of(toolCallId, "8.5094")); + var response = openAI.threads().submitToolOutputs(threadId, runId, listToolOutputs).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsRunsCreateBoth() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_runs_create_both.json"); + var request = ThreadCreateAndRunRequest.builder() + .assistantId(assistantId) + .thread(ThreadMessageList.builder() + .message(ThreadMessageRequest.builder() + .role("user") + .content("What are the order of precedence in artihmetic operations?") + .build()) + .metadata(Map.of("stage", "test")) + .build()) + .model("gpt-4-1106-preview") + .instructions("You are a personal math tutor. Use the added function if necessary or the added files.") + .tool(AssistantTool.RETRIEVAL) + .metadata(Map.of("phase", "test")) + .build(); + var response = openAI.threads().createThreadAndRun(request).join(); + System.out.println(response); + assertNotNull(response); + } + + @Test + void testThreadsRunsCancel() throws IOException { + DomainTestingHelper.get().mockForObject(httpClient, "src/test/resources/threads_runs_cancel.json"); + var response = openAI.threads().cancelRun(threadId, runId).join(); + System.out.println(response); + assertNotNull(response); + } +} \ No newline at end of file diff --git a/src/test/resources/assistants__create.json b/src/test/resources/assistants__create.json new file mode 100644 index 00000000..08ccfdeb --- /dev/null +++ b/src/test/resources/assistants__create.json @@ -0,0 +1 @@ +{ "id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "object": "assistant", "created_at": 1700868326, "name": "Math Tutor", "description": "Assistant for mathematics topics", "model": "gpt-4-1106-preview", "instructions": "You are a personal math tutor. Use the added function if necessary or the added files.", "tools": [ { "type": "function", "function": { "name": "product", "description": "Get the product of two numbers", "parameters": { "type": "object", "properties": { "multiplicand": { "type": "number", "description": "The multiplicand part of a product" }, "multiplier": { "type": "number", "description": "The multiplier part of a product" } }, "required": [ "multiplicand", "multiplier" ] } } }, { "type": "retrieval" } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "metadata": { "phase": "test" } } \ No newline at end of file diff --git a/src/test/resources/assistants__delete.json b/src/test/resources/assistants__delete.json new file mode 100644 index 00000000..a8877418 --- /dev/null +++ b/src/test/resources/assistants__delete.json @@ -0,0 +1 @@ +{ "id": "asst_y65tFAUl3dSNFZLxfpWFwSkC", "object": "assistant.deleted", "deleted": true } \ No newline at end of file diff --git a/src/test/resources/assistants__getlist.json b/src/test/resources/assistants__getlist.json new file mode 100644 index 00000000..7878c218 --- /dev/null +++ b/src/test/resources/assistants__getlist.json @@ -0,0 +1 @@ +{ "object": "list", "data": [ { "id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "object": "assistant", "created_at": 1700868326, "name": "Math Tutor", "description": "Assistant for mathematics topics", "model": "gpt-4-1106-preview", "instructions": "You are a personal math tutor. Use the added function if necessary or the added files.", "tools": [ { "type": "function", "function": { "name": "product", "description": "Get the product of two numbers", "parameters": { "type": "object", "properties": { "multiplicand": { "type": "number", "description": "The multiplicand part of a product" }, "multiplier": { "type": "number", "description": "The multiplier part of a product" } }, "required": [ "multiplicand", "multiplier" ] } } }, { "type": "retrieval" } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "metadata": { "phase": "test" } } ], "first_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "last_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "has_more": false } \ No newline at end of file diff --git a/src/test/resources/assistants__getone.json b/src/test/resources/assistants__getone.json new file mode 100644 index 00000000..08ccfdeb --- /dev/null +++ b/src/test/resources/assistants__getone.json @@ -0,0 +1 @@ +{ "id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "object": "assistant", "created_at": 1700868326, "name": "Math Tutor", "description": "Assistant for mathematics topics", "model": "gpt-4-1106-preview", "instructions": "You are a personal math tutor. Use the added function if necessary or the added files.", "tools": [ { "type": "function", "function": { "name": "product", "description": "Get the product of two numbers", "parameters": { "type": "object", "properties": { "multiplicand": { "type": "number", "description": "The multiplicand part of a product" }, "multiplier": { "type": "number", "description": "The multiplier part of a product" } }, "required": [ "multiplicand", "multiplier" ] } } }, { "type": "retrieval" } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "metadata": { "phase": "test" } } \ No newline at end of file diff --git a/src/test/resources/assistants__modify.json b/src/test/resources/assistants__modify.json new file mode 100644 index 00000000..08ccfdeb --- /dev/null +++ b/src/test/resources/assistants__modify.json @@ -0,0 +1 @@ +{ "id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "object": "assistant", "created_at": 1700868326, "name": "Math Tutor", "description": "Assistant for mathematics topics", "model": "gpt-4-1106-preview", "instructions": "You are a personal math tutor. Use the added function if necessary or the added files.", "tools": [ { "type": "function", "function": { "name": "product", "description": "Get the product of two numbers", "parameters": { "type": "object", "properties": { "multiplicand": { "type": "number", "description": "The multiplicand part of a product" }, "multiplier": { "type": "number", "description": "The multiplier part of a product" } }, "required": [ "multiplicand", "multiplier" ] } } }, { "type": "retrieval" } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "metadata": { "phase": "test" } } \ No newline at end of file diff --git a/src/test/resources/assistants_files_create.json b/src/test/resources/assistants_files_create.json new file mode 100644 index 00000000..020bb11e --- /dev/null +++ b/src/test/resources/assistants_files_create.json @@ -0,0 +1 @@ +{ "id": "file-bI6iyBmUO1jOvZVTd3wLzjFq", "object": "assistant.file", "created_at": 1700868327, "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R" } \ No newline at end of file diff --git a/src/test/resources/assistants_files_delete.json b/src/test/resources/assistants_files_delete.json new file mode 100644 index 00000000..7e179421 --- /dev/null +++ b/src/test/resources/assistants_files_delete.json @@ -0,0 +1 @@ +{ "id": "file-CZ9ryjPH0bZTjh0tzSxTsOlf", "object": "assistant.file.deleted", "deleted": true } \ No newline at end of file diff --git a/src/test/resources/assistants_files_getlist.json b/src/test/resources/assistants_files_getlist.json new file mode 100644 index 00000000..f85119de --- /dev/null +++ b/src/test/resources/assistants_files_getlist.json @@ -0,0 +1 @@ +{ "object": "list", "data": [ { "id": "file-bI6iyBmUO1jOvZVTd3wLzjFq", "object": "assistant.file", "created_at": 1700868327, "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R" } ], "first_id": "file-bI6iyBmUO1jOvZVTd3wLzjFq", "last_id": "file-bI6iyBmUO1jOvZVTd3wLzjFq", "has_more": false } \ No newline at end of file diff --git a/src/test/resources/assistants_files_getone.json b/src/test/resources/assistants_files_getone.json new file mode 100644 index 00000000..020bb11e --- /dev/null +++ b/src/test/resources/assistants_files_getone.json @@ -0,0 +1 @@ +{ "id": "file-bI6iyBmUO1jOvZVTd3wLzjFq", "object": "assistant.file", "created_at": 1700868327, "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R" } \ No newline at end of file diff --git a/src/test/resources/threads__create.json b/src/test/resources/threads__create.json new file mode 100644 index 00000000..7155a7c7 --- /dev/null +++ b/src/test/resources/threads__create.json @@ -0,0 +1 @@ +{ "id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "object": "thread", "created_at": 1700870063, "metadata": {} } \ No newline at end of file diff --git a/src/test/resources/threads__delete.json b/src/test/resources/threads__delete.json new file mode 100644 index 00000000..2e77b33a --- /dev/null +++ b/src/test/resources/threads__delete.json @@ -0,0 +1 @@ +{ "id": "thread_e3XrdOFFx2jK4zMGLNolJSqb", "object": "thread.deleted", "deleted": true } \ No newline at end of file diff --git a/src/test/resources/threads__getone.json b/src/test/resources/threads__getone.json new file mode 100644 index 00000000..20f4be16 --- /dev/null +++ b/src/test/resources/threads__getone.json @@ -0,0 +1 @@ +{ "id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "object": "thread", "created_at": 1700870063, "metadata": { "env": "test" } } \ No newline at end of file diff --git a/src/test/resources/threads__modify.json b/src/test/resources/threads__modify.json new file mode 100644 index 00000000..20f4be16 --- /dev/null +++ b/src/test/resources/threads__modify.json @@ -0,0 +1 @@ +{ "id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "object": "thread", "created_at": 1700870063, "metadata": { "env": "test" } } \ No newline at end of file diff --git a/src/test/resources/threads_messages_create.json b/src/test/resources/threads_messages_create.json new file mode 100644 index 00000000..b0e1f2de --- /dev/null +++ b/src/test/resources/threads_messages_create.json @@ -0,0 +1 @@ +{ "id": "msg_J0YkQiEmsyIiDSx73UJ3422m", "object": "thread.message", "created_at": 1700872232, "thread_id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "role": "user", "content": [ { "type": "text", "text": { "value": "What is the product of 123 and 456?", "annotations": [] } } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "assistant_id": null, "run_id": null, "metadata": {} } \ No newline at end of file diff --git a/src/test/resources/threads_messages_delete.json b/src/test/resources/threads_messages_delete.json new file mode 100644 index 00000000..46bddf82 --- /dev/null +++ b/src/test/resources/threads_messages_delete.json @@ -0,0 +1 @@ +{ "id": "msg_LmlLOJvLxRJsU2RpJMBT2iWf", "object": "thread.message.deleted", "deleted": true } \ No newline at end of file diff --git a/src/test/resources/threads_messages_getlist.json b/src/test/resources/threads_messages_getlist.json new file mode 100644 index 00000000..df40b4d5 --- /dev/null +++ b/src/test/resources/threads_messages_getlist.json @@ -0,0 +1 @@ +{ "object": "list", "data": [ { "id": "msg_U6LAQrVD5D7kP3etTsl50Q5x", "object": "thread.message", "created_at": 1700875181, "thread_id": "thread_9dBCb7X0JFU70skNoOxCNA6r", "role": "assistant", "content": [ { "type": "text", "text": { "value": "When you multiply a positive number with a negative number according to arithmetic rules, the sign of the result will be negative. This is because:\n\n- Positive × Positive = Positive\n- Negative × Negative = Positive\n- Positive × Negative = Negative\n- Negative × Positive = Negative\n\nSo, multiplying a positive number by a negative number (or a negative number by a positive number) always results in a negative product.", "annotations": [] } } ], "file_ids": [], "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "run_id": "run_fTlCcvQLzfNiJRnzNUrPmkdF", "metadata": {} }, { "id": "msg_Gazur9gV37nDJNg10E1kCoQm", "object": "thread.message", "created_at": 1700875180, "thread_id": "thread_9dBCb7X0JFU70skNoOxCNA6r", "role": "user", "content": [ { "type": "text", "text": { "value": "When you multiply a positive number with a negative number, what is the sign of the result according to the arithmetic rules?", "annotations": [] } } ], "file_ids": [], "assistant_id": null, "run_id": null, "metadata": {} } ], "first_id": "msg_U6LAQrVD5D7kP3etTsl50Q5x", "last_id": "msg_Gazur9gV37nDJNg10E1kCoQm", "has_more": false } \ No newline at end of file diff --git a/src/test/resources/threads_messages_getone.json b/src/test/resources/threads_messages_getone.json new file mode 100644 index 00000000..9bbd01d7 --- /dev/null +++ b/src/test/resources/threads_messages_getone.json @@ -0,0 +1 @@ +{ "id": "msg_8uvneGIoxEvNfAUyrWxiU6sO", "object": "thread.message", "created_at": 1700870063, "thread_id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "role": "user", "content": [ { "type": "text", "text": { "value": "What are the order of precedence in artihmetic operations?", "annotations": [] } } ], "file_ids": [], "assistant_id": null, "run_id": null, "metadata": {} } \ No newline at end of file diff --git a/src/test/resources/threads_messages_modify.json b/src/test/resources/threads_messages_modify.json new file mode 100644 index 00000000..e9b837e6 --- /dev/null +++ b/src/test/resources/threads_messages_modify.json @@ -0,0 +1 @@ +{ "id": "msg_8uvneGIoxEvNfAUyrWxiU6sO", "object": "thread.message", "created_at": 1700870063, "thread_id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "role": "user", "content": [ { "type": "text", "text": { "value": "What are the order of precedence in artihmetic operations?", "annotations": [] } } ], "file_ids": [], "assistant_id": null, "run_id": null, "metadata": { "key1": "value1" } } \ No newline at end of file diff --git a/src/test/resources/threads_messagesfiles_getlist.json b/src/test/resources/threads_messagesfiles_getlist.json new file mode 100644 index 00000000..51cd5b1c --- /dev/null +++ b/src/test/resources/threads_messagesfiles_getlist.json @@ -0,0 +1 @@ +{ "object": "list", "data": [ { "id": "file-bI6iyBmUO1jOvZVTd3wLzjFq", "object": "thread.message.file", "created_at": 1700872232, "message_id": "msg_J0YkQiEmsyIiDSx73UJ3422m" } ], "first_id": "file-bI6iyBmUO1jOvZVTd3wLzjFq", "last_id": "file-bI6iyBmUO1jOvZVTd3wLzjFq", "has_more": false } \ No newline at end of file diff --git a/src/test/resources/threads_messagesfiles_getone.json b/src/test/resources/threads_messagesfiles_getone.json new file mode 100644 index 00000000..86da7ea3 --- /dev/null +++ b/src/test/resources/threads_messagesfiles_getone.json @@ -0,0 +1 @@ +{ "id": "file-bI6iyBmUO1jOvZVTd3wLzjFq", "object": "thread.message.file", "created_at": 1700872232, "message_id": "msg_J0YkQiEmsyIiDSx73UJ3422m" } \ No newline at end of file diff --git a/src/test/resources/threads_runs_cancel.json b/src/test/resources/threads_runs_cancel.json new file mode 100644 index 00000000..0b49a6dc --- /dev/null +++ b/src/test/resources/threads_runs_cancel.json @@ -0,0 +1 @@ +{ "id": "run_v34ayOUhnUWSUvDe1TbAQTRh", "object": "thread.run", "created_at": 1700871114, "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "thread_id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "status": "completed", "started_at": 1700871114, "expires_at": null, "cancelled_at": 1700871122, "failed_at": null, "completed_at": null, "last_error": null, "model": "gpt-4-1106-preview", "instructions": "You are a personal math tutor. Use the added function if necessary or the added files.", "tools": [ { "type": "function", "function": { "name": "product", "description": "Get the product of two numbers", "parameters": { "type": "object", "properties": { "multiplicand": { "type": "number", "description": "The multiplicand part of a product" }, "multiplier": { "type": "number", "description": "The multiplier part of a product" } }, "required": [ "multiplicand", "multiplier" ] } } }, { "type": "retrieval" } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "metadata": {} } \ No newline at end of file diff --git a/src/test/resources/threads_runs_create.json b/src/test/resources/threads_runs_create.json new file mode 100644 index 00000000..4eefd556 --- /dev/null +++ b/src/test/resources/threads_runs_create.json @@ -0,0 +1 @@ +{ "id": "run_v34ayOUhnUWSUvDe1TbAQTRh", "object": "thread.run", "created_at": 1700871114, "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "thread_id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "status": "queued", "started_at": null, "expires_at": 1700871714, "cancelled_at": null, "failed_at": null, "completed_at": null, "last_error": null, "model": "gpt-4-1106-preview", "instructions": "You are a personal math tutor. Use the added function if necessary or the added files.", "tools": [ { "type": "function", "function": { "name": "product", "description": "Get the product of two numbers", "parameters": { "type": "object", "properties": { "multiplicand": { "type": "number", "description": "The multiplicand part of a product" }, "multiplier": { "type": "number", "description": "The multiplier part of a product" } }, "required": [ "multiplicand", "multiplier" ] } } }, { "type": "retrieval" } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "metadata": {} } \ No newline at end of file diff --git a/src/test/resources/threads_runs_create_both.json b/src/test/resources/threads_runs_create_both.json new file mode 100644 index 00000000..42dd6661 --- /dev/null +++ b/src/test/resources/threads_runs_create_both.json @@ -0,0 +1 @@ +{ "id": "run_fTlCcvQLzfNiJRnzNUrPmkdF", "object": "thread.run", "created_at": 1700875180, "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "thread_id": "thread_9dBCb7X0JFU70skNoOxCNA6r", "status": "queued", "started_at": null, "expires_at": 1700875780, "cancelled_at": null, "failed_at": null, "completed_at": null, "last_error": null, "model": "gpt-4-1106-preview", "instructions": "You are a personal math tutor. Use the added function if necessary or the added files.", "tools": [ { "type": "function", "function": { "name": "product", "description": "Get the product of two numbers", "parameters": { "type": "object", "properties": { "multiplicand": { "type": "number", "description": "The multiplicand part of a product" }, "multiplier": { "type": "number", "description": "The multiplier part of a product" } }, "required": [ "multiplicand", "multiplier" ] } } }, { "type": "retrieval" } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "metadata": {} } \ No newline at end of file diff --git a/src/test/resources/threads_runs_getlist.json b/src/test/resources/threads_runs_getlist.json new file mode 100644 index 00000000..6fce9d78 --- /dev/null +++ b/src/test/resources/threads_runs_getlist.json @@ -0,0 +1 @@ +{ "object": "list", "data": [ { "id": "run_iyRdrIQxDkYjSe96ThsN8rHm", "object": "thread.run", "created_at": 1700872738, "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "thread_id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "status": "requires_action", "started_at": 1700872746, "expires_at": 1700873338, "cancelled_at": null, "failed_at": null, "completed_at": null, "required_action": { "type": "submit_tool_outputs", "submit_tool_outputs": { "tool_calls": [ { "id": "call_OWhN3b7Jv6nSiWTqCDmg1kI5", "type": "function", "function": { "name": "product", "arguments": "{\"multiplicand\":123,\"multiplier\":456}" } } ] } }, "last_error": null, "model": "gpt-4-1106-preview", "instructions": "You are a personal math tutor. Use the added function if necessary or the added files.", "tools": [ { "type": "function", "function": { "name": "product", "description": "Get the product of two numbers", "parameters": { "type": "object", "properties": { "multiplicand": { "type": "number", "description": "The multiplicand part of a product" }, "multiplier": { "type": "number", "description": "The multiplier part of a product" } }, "required": [ "multiplicand", "multiplier" ] } } }, { "type": "retrieval" } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "metadata": {} }, { "id": "run_v34ayOUhnUWSUvDe1TbAQTRh", "object": "thread.run", "created_at": 1700871114, "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "thread_id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "status": "expired", "started_at": 1700871114, "expires_at": null, "cancelled_at": null, "failed_at": null, "completed_at": 1700871122, "last_error": null, "model": "gpt-4-1106-preview", "instructions": "You are a personal math tutor. Use the added function if necessary or the added files.", "tools": [ { "type": "function", "function": { "name": "product", "description": "Get the product of two numbers", "parameters": { "type": "object", "properties": { "multiplicand": { "type": "number", "description": "The multiplicand part of a product" }, "multiplier": { "type": "number", "description": "The multiplier part of a product" } }, "required": [ "multiplicand", "multiplier" ] } } }, { "type": "retrieval" } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "metadata": { "key1": "value1" } } ], "first_id": "run_iyRdrIQxDkYjSe96ThsN8rHm", "last_id": "run_v34ayOUhnUWSUvDe1TbAQTRh", "has_more": false } \ No newline at end of file diff --git a/src/test/resources/threads_runs_getone.json b/src/test/resources/threads_runs_getone.json new file mode 100644 index 00000000..7be8309b --- /dev/null +++ b/src/test/resources/threads_runs_getone.json @@ -0,0 +1 @@ +{ "id": "run_iyRdrIQxDkYjSe96ThsN8rHm", "object": "thread.run", "created_at": 1700872738, "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "thread_id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "status": "requires_action", "started_at": 1700872746, "expires_at": 1700873338, "cancelled_at": null, "failed_at": null, "completed_at": null, "required_action": { "type": "submit_tool_outputs", "submit_tool_outputs": { "tool_calls": [ { "id": "call_OWhN3b7Jv6nSiWTqCDmg1kI5", "type": "function", "function": { "name": "product", "arguments": "{\"multiplicand\":123,\"multiplier\":456}" } } ] } }, "last_error": null, "model": "gpt-4-1106-preview", "instructions": "You are a personal math tutor. Use the added function if necessary or the added files.", "tools": [ { "type": "function", "function": { "name": "product", "description": "Get the product of two numbers", "parameters": { "type": "object", "properties": { "multiplicand": { "type": "number", "description": "The multiplicand part of a product" }, "multiplier": { "type": "number", "description": "The multiplier part of a product" } }, "required": [ "multiplicand", "multiplier" ] } } }, { "type": "retrieval" } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "metadata": {} } \ No newline at end of file diff --git a/src/test/resources/threads_runs_modify.json b/src/test/resources/threads_runs_modify.json new file mode 100644 index 00000000..08aead74 --- /dev/null +++ b/src/test/resources/threads_runs_modify.json @@ -0,0 +1 @@ +{ "id": "run_v34ayOUhnUWSUvDe1TbAQTRh", "object": "thread.run", "created_at": 1700871114, "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "thread_id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "status": "completed", "started_at": 1700871114, "expires_at": null, "cancelled_at": null, "failed_at": null, "completed_at": 1700871122, "last_error": null, "model": "gpt-4-1106-preview", "instructions": "You are a personal math tutor. Use the added function if necessary or the added files.", "tools": [ { "type": "function", "function": { "name": "product", "description": "Get the product of two numbers", "parameters": { "type": "object", "properties": { "multiplicand": { "type": "number", "description": "The multiplicand part of a product" }, "multiplier": { "type": "number", "description": "The multiplier part of a product" } }, "required": [ "multiplicand", "multiplier" ] } } }, { "type": "retrieval" } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "metadata": { "key1": "value1" } } \ No newline at end of file diff --git a/src/test/resources/threads_runs_submittool.json b/src/test/resources/threads_runs_submittool.json new file mode 100644 index 00000000..622f3daa --- /dev/null +++ b/src/test/resources/threads_runs_submittool.json @@ -0,0 +1 @@ +{ "id": "run_9jBUbYMxLH1iQmpxUFuz6yW8", "object": "thread.run", "created_at": 1700874232, "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "thread_id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "status": "queued", "started_at": 1700874233, "expires_at": 1700874832, "cancelled_at": null, "failed_at": null, "completed_at": null, "last_error": null, "model": "gpt-4-1106-preview", "instructions": "You are a personal math tutor. Use the added function if necessary or the added files.", "tools": [ { "type": "function", "function": { "name": "product", "description": "Get the product of two numbers", "parameters": { "type": "object", "properties": { "multiplicand": { "type": "number", "description": "The multiplicand part of a product" }, "multiplier": { "type": "number", "description": "The multiplier part of a product" } }, "required": [ "multiplicand", "multiplier" ] } } }, { "type": "retrieval" } ], "file_ids": [ "file-bI6iyBmUO1jOvZVTd3wLzjFq" ], "metadata": {} } \ No newline at end of file diff --git a/src/test/resources/threads_runssteps_getlist.json b/src/test/resources/threads_runssteps_getlist.json new file mode 100644 index 00000000..6758c8e0 --- /dev/null +++ b/src/test/resources/threads_runssteps_getlist.json @@ -0,0 +1 @@ +{ "object": "list", "data": [ { "id": "step_mGsZSlpAEDmpB2Bc7E7eAIjZ", "object": "thread.run.step", "created_at": 1700872747, "run_id": "run_iyRdrIQxDkYjSe96ThsN8rHm", "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "thread_id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "type": "tool_calls", "status": "in_progress", "cancelled_at": null, "completed_at": null, "expires_at": 1700873338, "failed_at": null, "last_error": null, "step_details": { "type": "tool_calls", "tool_calls": [ { "id": "call_OWhN3b7Jv6nSiWTqCDmg1kI5", "type": "function", "function": { "name": "product", "arguments": "{\"multiplicand\":123,\"multiplier\":456}" } } ] } } ], "first_id": "step_mGsZSlpAEDmpB2Bc7E7eAIjZ", "last_id": "step_mGsZSlpAEDmpB2Bc7E7eAIjZ", "has_more": false } \ No newline at end of file diff --git a/src/test/resources/threads_runssteps_getone.json b/src/test/resources/threads_runssteps_getone.json new file mode 100644 index 00000000..cf355eac --- /dev/null +++ b/src/test/resources/threads_runssteps_getone.json @@ -0,0 +1 @@ +{ "id": "step_8zX8yAgcqQZxTBfLTn8Qp4IG", "object": "thread.run.step", "created_at": 1700871116, "run_id": "run_v34ayOUhnUWSUvDe1TbAQTRh", "assistant_id": "asst_HVW5yeBxNVvEMHF5uoFspA2R", "thread_id": "thread_xK2nfHLx8AV4nR2lsC6jHfxo", "type": "message_creation", "status": "completed", "cancelled_at": null, "completed_at": 1700871122, "expires_at": null, "failed_at": null, "last_error": null, "step_details": { "type": "message_creation", "message_creation": { "message_id": "msg_I0fsSYQebOdg69STgqcJ0fVh" } } } \ No newline at end of file