Skip to content

Commit

Permalink
naive testing
Browse files Browse the repository at this point in the history
  • Loading branch information
Quafadas committed Aug 30, 2024
1 parent e6d76f7 commit 7308c61
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 74 deletions.
10 changes: 9 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
"configurations": [
{
"type": "scala",
"request": "launch",
Expand All @@ -12,6 +12,14 @@
"mainClass": "io.github.quafadas.dairect.testy",
"envFile": ".envrc"
},
{
"type": "scala",
"request": "launch",
"name": "uploadFiles",
"buildTarget": "site",
"mainClass": "io.github.quafadas.dairect.uploadFiles",
"envFile": ".envrc"
},
{
"type": "scala",
"request": "launch",
Expand Down
10 changes: 9 additions & 1 deletion api/src/assistants.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,15 @@ object AssistantApi:

end AssistantApi

case class AssistantFileSearch(max_num_results: Option[Int] = None) derives Schema
case class AssistantFileSearch(
max_num_results: Option[Long] = None,
ranking_options: Option[RankingOptions] = None
) derives Schema

case class RankingOptions(
ranker: String,
score_threshold: Double
) derives Schema

case class AssistantToolFunction(
name: String,
Expand Down
25 changes: 10 additions & 15 deletions api/src/files.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,37 +33,39 @@ import smithy4s.schema.Schema
extension (fApi: FilesApi)
def upload[F[_]: Files](
file: Path,
authdClient: Resource[IO, Client[IO]],
authdClient: Client[IO],
purpose: String = "assistants",
baseUrl: String = "https://api.openai.com"
) =
): IO[File] =

val filePart = Part.fileData[IO](
"file",
file
)
val purposePart = Part.formData[IO](name = purpose, value = purpose)
val purposePart = Part.formData[IO](name = "purpose", value = purpose)
val multipart = Multipart[IO](Vector(filePart, purposePart))

val req = Request[IO](
Method.POST,
Uri.unsafeFromString(baseUrl + "/v1/files"),
headers = multipart.headers
).withEntity(multipart)

authdClient
.use(_.expect[String](req))
.map(resp =>
.expect[String](req)
.flatMap(resp =>
smithy4s.json.Json
.read[File](Blob(resp))
.fold(
ex => IO.raiseError(ex),
identity
ex => IO.raiseError[File](ex),
IO.pure
)
)
end upload

def content[F[_]: Files](
file: Path,
authdClient: Resource[IO, Client[IO]],
authdClient: Client[IO],
file_id: String
) = ???

Expand Down Expand Up @@ -98,13 +100,6 @@ trait FilesApi derives API:
id: String
): IO[DeletedFile]

def content(
@hints(HttpLabel())
id: String
): IO[Blob] = throw new Exception(
"This operation is not a json endpoint. Look for the method on the companion object of the FilesAPI"
)

end FilesApi

object FilesApi:
Expand Down
13 changes: 7 additions & 6 deletions api/src/introspection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ val printLogger = (cIn: Client[IO]) =>
Some((x: String) => IO.println(x))
)(cIn)

def makeLogFile(toFile: fs2.io.file.Path) =
filesIo
.isRegularFile(toFile)
.flatMap { exists =>
if exists then filesIo.delete(toFile) else IO.unit
} >>
def makeLogFile(toFile: fs2.io.file.Path): IO[Unit] =
IO.println(s"Making log file at $toFile") >>
filesIo
.isRegularFile(toFile)
.flatMap { exists =>
if exists then filesIo.delete(toFile) else IO.unit
} >>
fs2.io.file.Files[IO].createFile(toFile)

def fileLogger(toFile: fs2.io.file.Path): (Client[IO] => Client[IO]) = (cIn: Client[IO]) =>
Expand Down
96 changes: 96 additions & 0 deletions api/src/openAiPlatform.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package io.github.quafadas.dairect

import io.github.quafadas.dairect.ChatGpt
import io.github.quafadas.dairect.AssistantApi
import io.github.quafadas.dairect.FilesApi
import io.github.quafadas.dairect.VectorStoreApi
import io.github.quafadas.dairect.VectorStoreFilesApi
import ciris.env
import cats.effect.IO
import fs2.io.file.Path
import cats.effect.kernel.Resource
import org.http4s.client.Client
import org.http4s.ember.client.EmberClientBuilder
import java.nio.file.Paths
import org.http4s.syntax.literals.uri
import java.io.File

case class OpenAiPlatform(
chatApi: ChatGpt,
assistantApi: AssistantApi,
filesApi: FilesApi,
vectorStoreApi: VectorStoreApi,
vectorStoreFilesApi: VectorStoreFilesApi,
runApi: RunApi,
runStepsApi: RunStepsApi,
threadApi: ThreadApi,
messageApi: MessagesApi,
authdClient: Client[IO]
)

object OpenAiPlatform:
def defaultAuthLogToFile(
provided: Resource[IO, Client[IO]] = EmberClientBuilder.default[IO].build
): Resource[IO, OpenAiPlatform] =
val apikey = env("OPEN_AI_API_TOKEN").as[String].load[IO].toResource

val logPath = fs2.io.file.Path("")
def loggerAndPath(name: String) =
val logPathNext = logPath / name
val logger = fileLogger(logPathNext)
(logPathNext, logger)
end loggerAndPath

val (mlogPath, mApiLogger) = loggerAndPath("messagesApi.log")
val (threadLogPath, threadApiLogger) = loggerAndPath("threadApi.log")

val (runApiLogPath, runApiLogger) = loggerAndPath("runApi.log")
val (runStepsApiLogPath, runStepsApiLogger) = loggerAndPath("runStepsApi.log")
val (vectorStoreFilesLogPath, vectorStoreFilesApiLogger) = loggerAndPath("vectorStoreFiles.log")
val (vectorStoreLogPath, vectorStoreApiLogger) = loggerAndPath("vectorStore.log")
val (filesLogPath, filesApiLogger) = loggerAndPath("filesApi.log")
val (assistantLogPath, assistantApiLogger) = loggerAndPath("assistantApi.log")
val (rawLogPath, rawLog) = loggerAndPath("rawClient.log")

for
_ <- makeLogFile(mlogPath).toResource
_ <- makeLogFile(threadLogPath).toResource
_ <- makeLogFile(runApiLogPath).toResource
_ <- makeLogFile(runStepsApiLogPath).toResource
_ <- makeLogFile(vectorStoreFilesLogPath).toResource
_ <- makeLogFile(vectorStoreLogPath).toResource
_ <- makeLogFile(filesLogPath).toResource
_ <- makeLogFile(assistantLogPath).toResource
_ <- makeLogFile(rawLogPath).toResource
client <- provided
authdClient = authMiddleware(apikey)(client)
assistClient = assistWare(authdClient)

chatGpt <- ChatGpt.apply(rawLog(authdClient), uri"https://api.openai.com/")
assistantApi <- AssistantApi.apply(assistantApiLogger(assistClient), uri"https://api.openai.com/")
filesApi <- FilesApi.apply(filesApiLogger(assistClient), uri"https://api.openai.com/")
vectorStoreApi <- VectorStoreApi.apply(vectorStoreApiLogger(assistClient), uri"https://api.openai.com/")
vectorStoreFilesApi <- VectorStoreFilesApi.apply(
vectorStoreFilesApiLogger(assistClient),
uri"https://api.openai.com/"
)
runApi <- RunApi.apply(runApiLogger(assistClient), uri"https://api.openai.com/")
runStepsApi <- RunStepsApi.apply(runStepsApiLogger(assistClient), uri"https://api.openai.com/")
threadApi <- ThreadApi.apply(threadApiLogger(assistClient), uri"https://api.openai.com/")
messageApi <- MessagesApi.apply(mApiLogger(assistClient), uri"https://api.openai.com/")
yield OpenAiPlatform(
chatGpt,
assistantApi,
filesApi,
vectorStoreApi,
vectorStoreFilesApi,
runApi,
runStepsApi,
threadApi,
messageApi,
assistClient
)
end for
end defaultAuthLogToFile

end OpenAiPlatform
69 changes: 37 additions & 32 deletions api/src/runs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package io.github.quafadas.dairect

import cats.effect.IO
import cats.effect.kernel.Resource
import io.github.quafadas.dairect.RunsApi.CreateThread
import io.github.quafadas.dairect.RunsApi.Run
import io.github.quafadas.dairect.RunsApi.RunList
import io.github.quafadas.dairect.RunsApi.ToolChoiceInRun
import io.github.quafadas.dairect.RunsApi.ToolOutput
import io.github.quafadas.dairect.RunsApi.TruncationStrategy
import io.github.quafadas.dairect.RunApi.CreateThread
import io.github.quafadas.dairect.RunApi.Run
import io.github.quafadas.dairect.RunApi.RunList
import io.github.quafadas.dairect.RunApi.ToolChoiceInRun
import io.github.quafadas.dairect.RunApi.ToolOutput
import io.github.quafadas.dairect.RunApi.TruncationStrategy
import org.http4s.Uri
import org.http4s.client.Client
import smithy.api.Http
Expand All @@ -25,27 +25,27 @@ import smithy4s.schema.Schema
*/

@simpleRestJson
trait RunsApi derives API:
trait RunApi derives API:

@hints(
Http(NonEmptyString("POST"), NonEmptyString("v1/threads/runs"), 200)
)
def createThreadAndRun(
assistant_id: String,
thread: Option[CreateThread],
model: Option[String],
instructions: Option[String],
tools: Option[List[AssistantTool]],
tool_resources: Option[ToolResources],
metadata: RunMetaData,
temperature: Option[Double],
top_p: Option[Double],
max_prompt_tokens: Option[Long],
max_completion_tokens: Option[Long],
truncation_strategy: Option[TruncationStrategy],
tool_choice: Option[ToolChoiceInRun],
parallel_tool_calls: Option[Boolean],
response_format: ResponseFormat
thread: CreateThread,
model: Option[String] = None,
instructions: Option[String] = None,
tools: Option[List[AssistantTool]] = None,
tool_resources: Option[ToolResources] = None,
metadata: Option[RunMetaData] = None,
temperature: Option[Double] = None,
top_p: Option[Double] = None,
max_prompt_tokens: Option[Long] = None,
max_completion_tokens: Option[Long] = None,
truncation_strategy: Option[TruncationStrategy] = None,
tool_choice: Option[ToolChoiceInRun] = None,
parallel_tool_calls: Option[Boolean] = None,
response_format: Option[ResponseFormat] = None
): IO[Run]

@hints(
Expand Down Expand Up @@ -134,12 +134,12 @@ trait RunsApi derives API:
tool_outputs: List[ToolOutput]
): IO[Run]

end RunsApi
end RunApi

object RunsApi:
object RunApi:

def apply(client: Client[IO], baseUrl: Uri): Resource[IO, RunsApi] =
SimpleRestJsonBuilder(API.service[RunsApi])
def apply(client: Client[IO], baseUrl: Uri): Resource[IO, RunApi] =
SimpleRestJsonBuilder(API.service[RunApi])
.client[IO](client)
.uri(baseUrl)
.resource
Expand Down Expand Up @@ -188,7 +188,7 @@ object RunsApi:
status: RunStatus,
required_action: Option[RequiredAction],
last_error: Option[RunError],
started_at: Long,
started_at: Option[Long],
expires_at: Option[Long],
cancelled_at: Option[Long],
failed_at: Option[Long],
Expand All @@ -198,28 +198,33 @@ object RunsApi:
instructions: Option[String],
tools: List[AssistantTool],
metadata: RunMetaData,
usage: Usage,
usage: Option[Usage],
temperature: Double,
top_p: Double,
max_prompt_tokens: Int,
max_completion_tokens: Int,
max_prompt_tokens: Option[Long],
max_completion_tokens: Option[Long],
truncation_strategy: TruncationStrategy,
tool_choice: ToolChoiceInRun,
parallel_tool_calls: Boolean,
response_format: ResponseFormat
) derives Schema

enum RunStatus derives Schema:
case Queued, InProgress, RequiresAction, Cancelling, Cancelled, Failed, Completed, Incomplete, Expired
case queued, in_progress, requires_action, cancelling, cancelled, failed, completed, incomplete, expired
end RunStatus

case class RunIncomplete(reason: String) derives Schema

@untagged()
enum ToolChoiceInRun derives Schema:
case ToolTreatment
@wrapper() case ToolTreatmentW(tt: ToolTreatment)
case RunToolDetail
end ToolChoiceInRun

case class ToolTreatmentW(
tt: ToolTreatment
) derives Schema

enum ToolTreatment derives Schema:
case auto, none, required
end ToolTreatment
Expand All @@ -242,4 +247,4 @@ object RunsApi:
metadata: Option[ThreadMetaData] = None
) derives Schema

end RunsApi
end RunApi
2 changes: 1 addition & 1 deletion api/src/vectorStore.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ trait VectorStoreApi derives API:
def create(
name: Option[String] = None,
expires_after: Option[String] = None,
chunkingStrategy: Option[ChunkingStrategy] = None,
chunking_strategy: Option[ChunkingStrategy] = None,
metadata: Option[VectorStoreMetaData] = None
): IO[VectorStore]

Expand Down
11 changes: 6 additions & 5 deletions api/src/vectorStoreFiles.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ trait VectorStoreFilesApi derives API:
def create(
@hints(HttpLabel()) vector_store_id: String,
file_id: String,
chunkingStrategy: Option[ChunkingStrategy] = None
chunking_strategy: Option[ChunkingStrategy] = None
): IO[VectorStoreFile]

/** https://platform.openai.com/docs/api-reference/vector-stores-files/listFiles
Expand Down Expand Up @@ -97,10 +97,11 @@ object VectorStoreFilesApi:
chunk_overlap_tokens: Int
) derives Schema

case class ChunkingStrategy(
`type`: String,
static: Option[StaticChunkingStrategy]
) derives Schema
@discriminated("type")
enum ChunkingStrategy derives Schema:
case auto()
case static(static: StaticChunkingStrategy)
end ChunkingStrategy

case class VectorStoreFile(
id: String,
Expand Down
Loading

0 comments on commit 7308c61

Please sign in to comment.