diff --git a/openai-client/src/main/scala/io/cequence/openaiscala/service/OpenAIServiceImpl.scala b/openai-client/src/main/scala/io/cequence/openaiscala/service/OpenAIServiceImpl.scala
index 79107859..9ee617e4 100644
--- a/openai-client/src/main/scala/io/cequence/openaiscala/service/OpenAIServiceImpl.scala
+++ b/openai-client/src/main/scala/io/cequence/openaiscala/service/OpenAIServiceImpl.scala
@@ -2,17 +2,15 @@ package io.cequence.openaiscala.service
import akka.stream.scaladsl.Source
import akka.util.ByteString
-import play.api.libs.json.{JsArray, JsObject, JsValue, Json}
-import io.cequence.openaiscala.JsonUtil.JsonOps
import io.cequence.openaiscala.JsonFormats._
+import io.cequence.openaiscala.JsonUtil.JsonOps
import io.cequence.openaiscala.OpenAIScalaClientException
-import io.cequence.openaiscala.domain.settings._
import io.cequence.openaiscala.domain.response._
+import io.cequence.openaiscala.domain.settings._
import io.cequence.openaiscala.domain.{
AssistantTool,
BaseMessage,
ChatRole,
- FileId,
FunctionSpec,
SortOrder,
Thread,
@@ -21,6 +19,7 @@ import io.cequence.openaiscala.domain.{
ThreadMessageFile,
ToolSpec
}
+import play.api.libs.json.{JsObject, JsValue, Json}
import java.io.File
import scala.concurrent.Future
@@ -770,11 +769,14 @@ private trait OpenAIServiceImpl extends OpenAICoreServiceImpl with OpenAIService
* Retrieves an AssistantFile.
*
* @param assistantId
- * The ID of the assistant who the file belongs to.
+ * The ID of the assistant who the file belongs to.
* @param fileId
- * The ID of the file we're getting.
+ * The ID of the file we're getting.
*/
- override def retrieveAssistantFile(assistantId: String, fileId: String): Future[Option[AssistantFile]] =
+ override def retrieveAssistantFile(
+ assistantId: String,
+ fileId: String
+ ): Future[Option[AssistantFile]] =
execGETWithStatus(
EndPoint.assistants,
Some(s"$assistantId/files/$fileId")
@@ -782,4 +784,30 @@ private trait OpenAIServiceImpl extends OpenAICoreServiceImpl with OpenAIService
handleNotFoundAndError(response).map(_.asSafe[AssistantFile])
}
+ override def modifyAssistant(
+ assistantId: String,
+ model: Option[String],
+ name: Option[String],
+ description: Option[String],
+ instructions: Option[String],
+ tools: Seq[AssistantTool],
+ fileIds: Seq[String],
+ metadata: Map[String, String]
+ ): Future[Option[Assistant]] =
+ execPOSTWithStatus(
+ EndPoint.assistants,
+ endPointParam = Some(assistantId),
+ bodyParams = jsonBodyParams(
+ Param.model -> model,
+ Param.name -> name,
+ Param.description -> description,
+ Param.instructions -> instructions,
+ Param.tools -> Some(Json.toJson(tools)),
+ Param.file_ids -> (if (fileIds.nonEmpty) Some(fileIds) else None),
+ Param.metadata -> (if (metadata.nonEmpty) Some(metadata) else None)
+ )
+ ).map { response =>
+ handleNotFoundAndError(response).map(_.asSafe[Assistant])
+ }
+
}
diff --git a/openai-core/src/main/scala/io/cequence/openaiscala/domain/AssistantTool.scala b/openai-core/src/main/scala/io/cequence/openaiscala/domain/AssistantTool.scala
index 7b1522fa..470bb2b8 100644
--- a/openai-core/src/main/scala/io/cequence/openaiscala/domain/AssistantTool.scala
+++ b/openai-core/src/main/scala/io/cequence/openaiscala/domain/AssistantTool.scala
@@ -28,7 +28,7 @@ object AssistantTool {
// FIXME: description should be optional in request and mandatory in response
description: String,
name: String,
- parameters: Option[String]
+ parameters: Option[String] // TODO: check representation
)
}
diff --git a/openai-core/src/main/scala/io/cequence/openaiscala/service/OpenAIService.scala b/openai-core/src/main/scala/io/cequence/openaiscala/service/OpenAIService.scala
index 01d65fac..f785b9e3 100644
--- a/openai-core/src/main/scala/io/cequence/openaiscala/service/OpenAIService.scala
+++ b/openai-core/src/main/scala/io/cequence/openaiscala/service/OpenAIService.scala
@@ -760,7 +760,10 @@ trait OpenAIService extends OpenAICoreService {
* @param fileId
* A File ID (with purpose="assistants") that the assistant should use. Useful for tools
* like `retrieval` and `code_interpreter` that can access files.
- * @return
+ * @see
+ * OpenAI
+ * Doc
*/
def createAssistantFile(
assistantId: String,
@@ -786,6 +789,10 @@ trait OpenAIService extends OpenAICoreService {
* list. For instance, if you make a list request and receive 100 objects, ending with
* `obj_foo`, your subsequent call can include `before=obj_foo`` in order to fetch the
* previous page of the list.
+ * @see
+ * OpenAI
+ * Doc
*/
def listAssistants(
limit: Option[Int] = None, // TODO: default 20 or None?
@@ -817,6 +824,9 @@ trait OpenAIService extends OpenAICoreService {
* list. For instance, if you make a list request and receive 100 objects, ending with
* `obj_foo`, your subsequent call can include `before=obj_foo` in order to fetch the
* previous page of the list.
+ * OpenAI
+ * Doc
*/
def listAssistantFiles(
assistantId: String,
@@ -831,6 +841,9 @@ trait OpenAIService extends OpenAICoreService {
*
* @param assistantId
* The ID of the assistant to retrieve.
+ * OpenAI
+ * Doc
*/
def retrieveAssistant(assistantId: String): Future[Option[Assistant]]
@@ -841,7 +854,49 @@ trait OpenAIService extends OpenAICoreService {
* The ID of the assistant who the file belongs to.
* @param fileId
* The ID of the file we're getting.
+ * OpenAI
+ * Doc
*/
def retrieveAssistantFile(assistantId: String, fileId: String): Future[Option[AssistantFile]]
+ /**
+ * Modifies an assistant.
+ *
+ * @param assistantId
+ * @param model
+ * ID of the model to use. You can use the List models API to see all of your available models,
+ * or see our Model overview for descriptions of them.
+ * @param name
+ * The name of the assistant. The maximum length is 256 characters.
+ * @param description
+ * The description of the assistant. The maximum length is 512 characters.
+ * @param instructions
+ * The system instructions that the assistant uses. The maximum length is 32768 characters.
+ * @param tools
+ * A list of tool enabled on the assistant. There can be a maximum of 128 tools per assistant. Tools can be of types
+ * code_interpreter, retrieval, or function.
+ * @param fileIds
+ * A list of File IDs attached to this assistant. There can be a maximum of 20 files attached to the assistant.
+ * Files are ordered by their creation date in ascending order. If a file was previously attached to the list but
+ * does not show up in the list, it will be deleted from the assistant.
+ * @param metadata
+ * Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional
+ * information about the object in a structured format. Keys can be a maximum of 64 characters long and values
+ * can be a maxium of 512 characters long.
+ * OpenAI
+ * Doc
+ */
+ def modifyAssistant(
+ assistantId: String,
+ model: Option[String] = None,
+ name: Option[String] = None,
+ description: Option[String] = None,
+ instructions: Option[String] = None,
+ tools: Seq[AssistantTool] = Seq.empty[AssistantTool],
+ fileIds: Seq[String] = Seq.empty,
+ metadata: Map[String, String] = Map.empty
+ ): Future[Option[Assistant]]
+
}
diff --git a/openai-core/src/main/scala/io/cequence/openaiscala/service/OpenAIServiceWrapper.scala b/openai-core/src/main/scala/io/cequence/openaiscala/service/OpenAIServiceWrapper.scala
index 30447b41..97d64459 100644
--- a/openai-core/src/main/scala/io/cequence/openaiscala/service/OpenAIServiceWrapper.scala
+++ b/openai-core/src/main/scala/io/cequence/openaiscala/service/OpenAIServiceWrapper.scala
@@ -338,9 +338,35 @@ trait OpenAIServiceWrapper extends OpenAIService {
override def retrieveAssistant(assistantId: String): Future[Option[Assistant]] =
wrap(_.retrieveAssistant(assistantId))
- override def retrieveAssistantFile(assistantId: String, fileId: String): Future[Option[AssistantFile]] =
+ override def retrieveAssistantFile(
+ assistantId: String,
+ fileId: String
+ ): Future[Option[AssistantFile]] =
wrap(_.retrieveAssistantFile(assistantId, fileId))
+ override def modifyAssistant(
+ assistantId: String,
+ model: Option[String],
+ name: Option[String],
+ description: Option[String],
+ instructions: Option[String],
+ tools: Seq[AssistantTool],
+ fileIds: Seq[String],
+ metadata: Map[String, String]
+ ): Future[Option[Assistant]] =
+ wrap(
+ _.modifyAssistant(
+ assistantId,
+ model,
+ name,
+ description,
+ instructions,
+ tools,
+ fileIds,
+ metadata
+ )
+ )
+
protected def wrap[T](
fun: OpenAIService => Future[T]
): Future[T]
diff --git a/openai-examples/src/main/scala/io/cequence/openaiscala/examples/ModifyAssistant.scala b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/ModifyAssistant.scala
new file mode 100755
index 00000000..f3f1d5a4
--- /dev/null
+++ b/openai-examples/src/main/scala/io/cequence/openaiscala/examples/ModifyAssistant.scala
@@ -0,0 +1,14 @@
+package io.cequence.openaiscala.examples
+
+object ModifyAssistant extends Example {
+
+ override protected def run =
+ for {
+ thread <- service.modifyAssistant(
+ assistantId = "asst_Btbc2h7dqyDU52g1KfBa2XE8",
+ metadata = Map("user_id" -> "986415", "due_date" -> "2028-08-01")
+ )
+ } yield {
+ println(thread)
+ }
+}