diff --git a/examples/scala/src/main/scala/com/xebia/functional/xef/scala/auto/PDFDocument.scala b/examples/scala/src/main/scala/com/xebia/functional/xef/scala/auto/PDFDocument.scala index 2b9757c8a..33f156237 100644 --- a/examples/scala/src/main/scala/com/xebia/functional/xef/scala/auto/PDFDocument.scala +++ b/examples/scala/src/main/scala/com/xebia/functional/xef/scala/auto/PDFDocument.scala @@ -1,18 +1,24 @@ package com.xebia.functional.xef.scala.auto import com.xebia.functional.xef.scala.auto.* +import com.xebia.functional.xef.scala.auto.ScalaSerialDescriptorContext.given import io.circe.Decoder import io.circe.parser.decode import scala.io.StdIn.readLine private final case class AIResponse(answer: String) derives ScalaSerialDescriptor, Decoder + +val pdfUrl = "https://people.cs.ksu.edu/~schmidt/705a/Scala/Programming-in-Scala.pdf" + @main def runPDFDocument: Unit = ai { - while (true) { - println("Enter your question: ") - val line = scala.io.StdIn.readLine() - val response = prompt[AIResponse](line) - println(s"${response.answer}\n---\n") + contextScope(pdf(resource = pdfUrl)) { + while (true) { + println("Enter your question: ") + val line = scala.io.StdIn.readLine() + val response = prompt[AIResponse](line) + println(s"${response.answer}\n---\n") + } } } diff --git a/scala/build.gradle.kts b/scala/build.gradle.kts index 817cb5550..7c1cc1b6d 100644 --- a/scala/build.gradle.kts +++ b/scala/build.gradle.kts @@ -10,6 +10,8 @@ plugins { dependencies { implementation(projects.xefCore) + implementation(projects.xefTokenizer) + implementation(projects.xefPdf) implementation(projects.kotlinLoom) implementation(libs.kotlinx.coroutines) implementation(libs.circe.parser) diff --git a/scala/src/main/scala/com/xebia/functional/xef/scala/auto/KotlinXSerializers.scala b/scala/src/main/scala/com/xebia/functional/xef/scala/auto/KotlinXSerializers.scala index de9a94676..e8c179d04 100644 --- a/scala/src/main/scala/com/xebia/functional/xef/scala/auto/KotlinXSerializers.scala +++ b/scala/src/main/scala/com/xebia/functional/xef/scala/auto/KotlinXSerializers.scala @@ -32,3 +32,6 @@ object KotlinXSerializers: val char: KSerializer[Character] = serializer(kotlin.jvm.internal.CharCompanionObject.INSTANCE) + + val unit: KSerializer[kotlin.Unit] = + serializer(kotlin.Unit.INSTANCE) diff --git a/scala/src/main/scala/com/xebia/functional/xef/scala/auto/ScalaSerialDescriptor.scala b/scala/src/main/scala/com/xebia/functional/xef/scala/auto/ScalaSerialDescriptor.scala index 3b35ffcec..09fca97ad 100644 --- a/scala/src/main/scala/com/xebia/functional/xef/scala/auto/ScalaSerialDescriptor.scala +++ b/scala/src/main/scala/com/xebia/functional/xef/scala/auto/ScalaSerialDescriptor.scala @@ -37,6 +37,7 @@ object ScalaSerialDescriptor: case _: (Int *: t) => KotlinXSerializers.int.getDescriptor :: getSerialDescriptor[t] case _: (Long *: t) => KotlinXSerializers.long.getDescriptor :: getSerialDescriptor[t] case _: (Short *: t) => KotlinXSerializers.short.getDescriptor :: getSerialDescriptor[t] + case _: (Unit *: t) => KotlinXSerializers.unit.getDescriptor :: getSerialDescriptor[t] case _: (h *: t) => summonInline[ScalaSerialDescriptor[h]].serialDescriptor :: getSerialDescriptor[t] inline final def derived[A](using inline m: Mirror.Of[A]): ScalaSerialDescriptor[A] = new ScalaSerialDescriptor[A]: diff --git a/scala/src/main/scala/com/xebia/functional/xef/scala/auto/ScalaSerialDescriptorContext.scala b/scala/src/main/scala/com/xebia/functional/xef/scala/auto/ScalaSerialDescriptorContext.scala index 6cb197165..9aef9e934 100644 --- a/scala/src/main/scala/com/xebia/functional/xef/scala/auto/ScalaSerialDescriptorContext.scala +++ b/scala/src/main/scala/com/xebia/functional/xef/scala/auto/ScalaSerialDescriptorContext.scala @@ -4,6 +4,7 @@ import kotlin.jvm.internal.Reflection import kotlin.reflect.KClass import kotlinx.serialization.KSerializer import kotlinx.serialization.builtins.BuiltinSerializersKt +import kotlinx.serialization.descriptors.SerialDescriptor import scala.compiletime.summonInline import scala.reflect.ClassTag @@ -60,3 +61,6 @@ object ScalaSerialDescriptorContext: given ScalaSerialDescriptor[String] = new ScalaSerialDescriptor[String]: def serialDescriptor = KotlinXSerializers.string.getDescriptor + + given ScalaSerialDescriptor[Unit] = new ScalaSerialDescriptor[Unit]: + override def serialDescriptor: SerialDescriptor = KotlinXSerializers.unit.getDescriptor diff --git a/scala/src/main/scala/com/xebia/functional/xef/scala/auto/package.scala b/scala/src/main/scala/com/xebia/functional/xef/scala/auto/package.scala index e269ad182..2e9882d8a 100644 --- a/scala/src/main/scala/com/xebia/functional/xef/scala/auto/package.scala +++ b/scala/src/main/scala/com/xebia/functional/xef/scala/auto/package.scala @@ -8,7 +8,12 @@ import io.circe.parser.decode import io.circe.{Decoder, Json} import io.circe.parser.parse import com.xebia.functional.xef.auto.{AIException, AIKt, AIScope as KtAIScope, Agent as KtAgent} +import com.xebia.functional.xef.textsplitters.TextSplitter +import com.xebia.functional.xef.textsplitters.TokenTextSplitterKt.TokenTextSplitter +import com.xebia.functional.xef.pdf.PDFLoaderKt +import com.xebia.functional.tokenizer.ModelType +import java.io.File import scala.jdk.CollectionConverters.* package object auto { @@ -73,4 +78,15 @@ package object auto { KtAgent.promptMessage(scope.kt, prompt, llmModel, user, echo, n, temperature, bringFromContext, minResponseTokens, _) ).asScala.toList + def pdf( + resource: String | File, + splitter: TextSplitter = TokenTextSplitter(ModelType.GPT_3_5_TURBO, 100, 50) + )(using scope: AIScope): List[String] = + LoomAdapter + .apply[java.util.List[String]](count => + resource match + case url: String => PDFLoaderKt.pdf(url, splitter, count) + case file: File => PDFLoaderKt.pdf(file, splitter, count) + ).asScala.toList + }