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