diff --git a/.gitignore b/.gitignore index 6c5fc87..d2daf1c 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ local.properties logs mobibot.properties out +/target/ diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml index b20abc9..719ca4e 100644 --- a/config/detekt/baseline.xml +++ b/config/detekt/baseline.xml @@ -71,9 +71,6 @@ ReturnCount:Addons.kt$Addons$fun help(channel: String, topic: String, event: GenericMessageEvent): Boolean ReturnCount:ExceptionSanitizer.kt$ExceptionSanitizer$fun ModuleException.sanitize(vararg sanitize: String): ModuleException ReturnCount:Seen.kt$Seen$override fun commandResponse(channel: String, args: String, event: GenericMessageEvent) - SwallowedException:GoogleSearchTest.kt$GoogleSearchTest$e: ModuleException - SwallowedException:StockQuoteTest.kt$StockQuoteTest$e: ModuleException - SwallowedException:WolframAlphaTest.kt$WolframAlphaTest$e: ModuleException ThrowsCount:ChatGpt.kt$ChatGpt.Companion$@JvmStatic @Throws(ModuleException::class) fun chat(query: String, apiKey: String?, maxTokens: Int): String ThrowsCount:GoogleSearch.kt$GoogleSearch.Companion$@JvmStatic @Throws(ModuleException::class) fun searchGoogle( query: String, apiKey: String?, cseKey: String?, quotaUser: String = ReleaseInfo.PROJECT ): List<Message> ThrowsCount:Joke.kt$Joke.Companion$@JvmStatic @Throws(ModuleException::class) fun randomJoke(): List<Message> @@ -82,7 +79,9 @@ ThrowsCount:StockQuote.kt$StockQuote.Companion$@Throws(ModuleException::class) private fun getJsonResponse(response: String, debugMessage: String): JSONObject ThrowsCount:Weather2.kt$Weather2.Companion$@JvmStatic @Throws(ModuleException::class) fun getWeather(query: String, apiKey: String?): List<Message> ThrowsCount:WolframAlpha.kt$WolframAlpha.Companion$@JvmStatic @Throws(ModuleException::class) fun queryWolfram(query: String, units: String = IMPERIAL, appId: String?): String + TooGenericExceptionCaught:ChatGpt2.kt$ChatGpt2.Companion$e: Exception TooGenericExceptionCaught:Gemini.kt$Gemini.Companion$e: Exception + TooGenericExceptionCaught:Gemini2.kt$Gemini2.Companion$e: Exception TooGenericExceptionCaught:StockQuote.kt$StockQuote.Companion$e: NullPointerException TooGenericExceptionCaught:Weather2.kt$Weather2.Companion$e: NullPointerException TooManyFunctions:EntryLink.kt$EntryLink : Serializable @@ -94,6 +93,7 @@ WildcardImport:FeedMgrTest.kt$import assertk.assertions.* WildcardImport:FeedReaderTest.kt$import assertk.assertions.* WildcardImport:FeedsManager.kt$import com.rometools.rome.feed.synd.* + WildcardImport:Gemini2Test.kt$import assertk.assertions.* WildcardImport:GeminiTest.kt$import assertk.assertions.* WildcardImport:GoogleSearchTest.kt$import assertk.assertions.* WildcardImport:JokeTest.kt$import assertk.assertions.* diff --git a/lib/bld/bld-wrapper.properties b/lib/bld/bld-wrapper.properties index 47fd61f..ed0fdb7 100644 --- a/lib/bld/bld-wrapper.properties +++ b/lib/bld/bld-wrapper.properties @@ -1,7 +1,7 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true bld.downloadLocation= -bld.extension-detekt=com.uwyn.rife2:bld-detekt:0.9.6 +bld.extension-detekt=com.uwyn.rife2:bld-detekt:0.9.7 bld.extension-gv=com.uwyn.rife2:bld-generated-version:0.9.9 bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.8 bld.extension-kotlin=com.uwyn.rife2:bld-kotlin:1.0.1 diff --git a/pom.xml b/pom.xml index 7996b05..5d1b89a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 net.thauvin.erik.mobibot mobibot - 0.8.0-rc+20240809180718 + 0.8.0-rc+20240908192921 mobibot @@ -18,7 +18,7 @@ org.apache.commons commons-lang3 - 3.16.0 + 3.17.0 compile @@ -51,34 +51,28 @@ 33.2.1-jre compile - - com.google.cloud - google-cloud-vertexai - 1.7.0 - compile - org.jetbrains.kotlin kotlin-stdlib - 2.0.10 + 2.0.20 compile org.jetbrains.kotlin kotlin-stdlib-common - 2.0.10 + 2.0.20 compile org.jetbrains.kotlin kotlin-stdlib-jdk7 - 2.0.10 + 2.0.20 compile org.jetbrains.kotlin kotlin-stdlib-jdk8 - 2.0.10 + 2.0.20 compile @@ -96,25 +90,49 @@ org.slf4j slf4j-api - 2.0.15 + 2.0.16 compile org.apache.logging.log4j log4j-api - 2.23.1 + 2.24.0 compile org.apache.logging.log4j log4j-core - 2.23.1 + 2.24.0 compile org.apache.logging.log4j log4j-slf4j2-impl - 2.23.1 + 2.24.0 + compile + + + dev.langchain4j + langchain4j-open-ai + 0.34.0 + compile + + + dev.langchain4j + langchain4j-google-ai-gemini + 0.34.0 + compile + + + dev.langchain4j + langchain4j-core + 0.34.0 + compile + + + dev.langchain4j + langchain4j + 0.34.0 compile diff --git a/properties/mobibot.properties b/properties/mobibot.properties index a7526cc..fd7b104 100644 --- a/properties/mobibot.properties +++ b/properties/mobibot.properties @@ -45,7 +45,6 @@ disabled-modules=mastodon # Automatically post links to Mastodon #mastodon-auto-post=true - # # Get Exchange Rate API key from: https://www.exchangerate-api.com/ # @@ -75,19 +74,13 @@ disabled-modules=mastodon #wolfram-units=imperial # -# ChatGPT/OpenAI API key from: https://beta.openai.com/account/api-keys +# Get ChatGPT/OpenAI API key from: https://platform.openai.com/api-keys # #chatgpt-api-key= #chatgpt-max-tokens=1024 # -# Set a Vertex AI Gemini API project in Google Cloud: -# https://cloud.google.com/vertex-ai/docs/generative-ai/start/quickstarts/quickstart-multimodal -# Don't forget to: -# gcloud config set project PROJECT_ID -# gcloud auth login LOGIN -# gcloud auth application-default login +# Get Google Gemini API key from https://ai.google.dev/gemini-api/docs/api-key # -#gemini-project-id= -#gemini-location=us-west1 +#gemini-api-key= #gemini-max-tokens=1024 diff --git a/src/bld/java/net/thauvin/erik/MobibotBuild.java b/src/bld/java/net/thauvin/erik/MobibotBuild.java index 1e6649b..980f2a6 100644 --- a/src/bld/java/net/thauvin/erik/MobibotBuild.java +++ b/src/bld/java/net/thauvin/erik/MobibotBuild.java @@ -77,20 +77,20 @@ public class MobibotBuild extends Project { new Repository("https://jitpack.io"), SONATYPE_SNAPSHOTS_LEGACY); - var log4j = version(2, 23, 1); - var kotlin = version(2, 0, 10); + var log4j = version(2, 24, 0); + var kotlin = version(2, 0, 20); + var langchain = version(0, 34, 0); scope(compile) // PircBotX .include(dependency("com.github.pircbotx", "pircbotx", "2.3.1")) // Commons (mostly for PircBotX) - .include(dependency("org.apache.commons", "commons-lang3", "3.16.0")) + .include(dependency("org.apache.commons", "commons-lang3", "3.17.0")) .include(dependency("org.apache.commons", "commons-text", "1.12.0")) .include(dependency("commons-codec", "commons-codec", "1.17.1")) .include(dependency("commons-net", "commons-net", "3.11.1")) // Google .include(dependency("com.google.code.gson", "gson", "2.11.0")) .include(dependency("com.google.guava", "guava", "33.2.1-jre")) - .include(dependency("com.google.cloud", "google-cloud-vertexai", "1.7.0")) // Kotlin .include(dependency("org.jetbrains.kotlin", "kotlin-stdlib", kotlin)) .include(dependency("org.jetbrains.kotlin", "kotlin-stdlib-common", kotlin)) @@ -99,10 +99,15 @@ public class MobibotBuild extends Project { .include(dependency("org.jetbrains.kotlinx", "kotlinx-coroutines-core", "1.8.1")) .include(dependency("org.jetbrains.kotlinx", "kotlinx-cli-jvm", "0.3.6")) // Logging - .include(dependency("org.slf4j", "slf4j-api", "2.0.15")) + .include(dependency("org.slf4j", "slf4j-api", "2.0.16")) .include(dependency("org.apache.logging.log4j", "log4j-api", log4j)) .include(dependency("org.apache.logging.log4j", "log4j-core", log4j)) .include(dependency("org.apache.logging.log4j", "log4j-slf4j2-impl", log4j)) + // LangChain4J + .include(dependency("dev.langchain4j", "langchain4j-open-ai", langchain)) + .include(dependency("dev.langchain4j", "langchain4j-google-ai-gemini", langchain)) + .include(dependency("dev.langchain4j", "langchain4j-core", langchain)) + .include(dependency("dev.langchain4j", "langchain4j", langchain)) // Misc. .include(dependency("com.rometools", "rome", "2.1.0")) .include(dependency("com.squareup.okhttp3", "okhttp", "4.12.0")) @@ -118,8 +123,8 @@ public class MobibotBuild extends Project { scope(test) .include(dependency("com.willowtreeapps.assertk", "assertk-jvm", version(0, 28, 1))) .include(dependency("org.jetbrains.kotlin", "kotlin-test-junit5", kotlin)) - .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 3))) - .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 3))); + .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 11, 0))) + .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 11, 0))); List jars = new ArrayList<>(); runtimeClasspathJars().forEach(f -> jars.add("./lib/" + f.getName())); diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt b/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt index 88bed54..1e49a88 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/Mobibot.kt @@ -396,11 +396,11 @@ class Mobibot(nickname: String, val channel: String, logsDirPath: String, p: Pro // Load the modules addons.add(Calc()) - addons.add(ChatGpt()) + addons.add(ChatGpt2()) addons.add(CryptoPrices()) addons.add(CurrencyConverter()) addons.add(Dice()) - addons.add(Gemini()) + addons.add(Gemini2()) addons.add(GoogleSearch()) addons.add(Info(tell, seen)) addons.add(Joke()) diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/ReleaseInfo.kt b/src/main/kotlin/net/thauvin/erik/mobibot/ReleaseInfo.kt index 3abf162..5b5e5d2 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/ReleaseInfo.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/ReleaseInfo.kt @@ -14,12 +14,12 @@ import java.time.ZoneId */ object ReleaseInfo { const val PROJECT = "mobibot" - const val VERSION = "0.8.0-rc+20240712110931" + const val VERSION = "0.8.0-rc+20240908190240" @JvmField @Suppress("MagicNumber") val BUILD_DATE: LocalDateTime = LocalDateTime.ofInstant( - Instant.ofEpochMilli(1720807771484L), ZoneId.systemDefault() + Instant.ofEpochMilli(1725847361020L), ZoneId.systemDefault() ) const val WEBSITE = "https://mobitopia.org/mobibot/" diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt2.kt similarity index 62% rename from src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt.kt rename to src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt2.kt index c7ba4ba..854bb9f 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt2.kt @@ -31,23 +31,16 @@ package net.thauvin.erik.mobibot.modules -import net.thauvin.erik.mobibot.Constants +import dev.langchain4j.model.openai.OpenAiChatModel +import dev.langchain4j.model.openai.OpenAiChatModelName import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.sendMessage -import org.json.JSONArray -import org.json.JSONException -import org.json.JSONObject import org.pircbotx.hooks.types.GenericMessageEvent import org.slf4j.Logger import org.slf4j.LoggerFactory -import java.io.IOException -import java.net.URI -import java.net.http.HttpClient -import java.net.http.HttpRequest -import java.net.http.HttpResponse -class ChatGpt : AbstractModule() { - val logger: Logger = LoggerFactory.getLogger(ChatGpt::class.java) +class ChatGpt2 : AbstractModule() { + val logger: Logger = LoggerFactory.getLogger(ChatGpt2::class.java) override val name = CHATGPT_NAME @@ -93,9 +86,6 @@ class ChatGpt : AbstractModule() { */ const val MAX_TOKENS_PROP = "chatgpt-max-tokens" - // ChatGPT API URL - private const val API_URL = "https://api.openai.com/v1/chat/completions" - // ChatGPT command private const val CHATGPT_CMD = "chatgpt" @@ -103,48 +93,15 @@ class ChatGpt : AbstractModule() { @Throws(ModuleException::class) fun chat(query: String, apiKey: String?, maxTokens: Int): String { if (!apiKey.isNullOrEmpty()) { - val jsonObject = JSONObject() - jsonObject.put("model", "gpt-3.5-turbo-1106") - jsonObject.put("max_tokens", maxTokens) - val message = JSONObject() - message.put("role", "user") - message.put("content", query) - val messages = JSONArray() - messages.put(message) - jsonObject.put("messages", messages) - - val request = HttpRequest.newBuilder() - .uri(URI.create(API_URL)) - .header("Content-Type", "application/json") - .header("Authorization", "Bearer $apiKey") - .header("User-Agent", Constants.USER_AGENT) - .POST(HttpRequest.BodyPublishers.ofString(jsonObject.toString())) - .build() try { - val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString()) - if (response.statusCode() == 200) { - try { - val jsonResponse = JSONObject(response.body()) - val choices = jsonResponse.getJSONArray("choices") - return choices.getJSONObject(0).getJSONObject("message").getString("content").trim() - } catch (e: JSONException) { - throw ModuleException( - "$CHATGPT_CMD($query): JSON", - "A JSON error has occurred while conversing with $CHATGPT_NAME.", - e - ) - } - } else { - if (response.statusCode() == 429) { - throw ModuleException( - "$CHATGPT_CMD($query): Rate limit reached", - "Rate limit reached. Please try again later." - ) - } else { - throw IOException("HTTP Status Code: " + response.statusCode()) - } - } - } catch (e: IOException) { + val model = OpenAiChatModel.builder() + .apiKey(apiKey) + .modelName(OpenAiChatModelName.GPT_4_O) + .maxTokens(maxTokens) + .build() + + return model.generate(query) + } catch (e: Exception) { throw ModuleException( "$CHATGPT_CMD($query): IO", "An IO error has occurred while conversing with $CHATGPT_NAME.", diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt index 4fb7555..3c8ea92 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/CurrencyConverter.kt @@ -217,6 +217,6 @@ class CurrencyConverter : AbstractModule() { init { commands.add(CURRENCY_CMD) initProperties(API_KEY_PROP) - loadSymbols(properties[ChatGpt.API_KEY_PROP]) + loadSymbols(properties[ChatGpt2.API_KEY_PROP]) } } diff --git a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini.kt b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini2.kt similarity index 58% rename from src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini.kt rename to src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini2.kt index 2e4ed91..812aed3 100644 --- a/src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini.kt +++ b/src/main/kotlin/net/thauvin/erik/mobibot/modules/Gemini2.kt @@ -31,12 +31,7 @@ package net.thauvin.erik.mobibot.modules -import com.google.cloud.vertexai.VertexAI -import com.google.cloud.vertexai.api.GenerationConfig -import com.google.cloud.vertexai.api.HarmCategory -import com.google.cloud.vertexai.api.SafetySetting -import com.google.cloud.vertexai.generativeai.GenerativeModel -import com.google.cloud.vertexai.generativeai.ResponseHandler +import dev.langchain4j.model.googleai.GoogleAiGeminiChatModel import net.thauvin.erik.mobibot.Utils import net.thauvin.erik.mobibot.Utils.sendMessage import org.pircbotx.hooks.types.GenericMessageEvent @@ -45,8 +40,8 @@ import org.slf4j.LoggerFactory import java.util.* -class Gemini : AbstractModule() { - private val logger: Logger = LoggerFactory.getLogger(Gemini::class.java) +class Gemini2 : AbstractModule() { + private val logger: Logger = LoggerFactory.getLogger(Gemini2::class.java) override val name = GEMINI_NAME @@ -55,8 +50,7 @@ class Gemini : AbstractModule() { try { val answer = chat( args.trim(), - properties[PROJECT_ID_PROP], - properties[LOCATION_PROP], + properties[GEMINI_API_KEY], properties.getOrDefault(MAX_TOKENS_PROP, "1024").toInt() ) if (!answer.isNullOrEmpty()) { @@ -82,17 +76,12 @@ class Gemini : AbstractModule() { const val GEMINI_NAME = "Gemini" /** - * The Google cloud project ID property. + * The API key */ - const val PROJECT_ID_PROP = "gemini-project-id" + const val GEMINI_API_KEY = "gemini-api-key" /** - * The Vertex AI location property. - */ - const val LOCATION_PROP = "gemini-location" - - /** - * The max number of tokens property. + * The max number of output tokens property. */ const val MAX_TOKENS_PROP = "gemini-max-tokens" @@ -103,40 +92,18 @@ class Gemini : AbstractModule() { @Throws(ModuleException::class) fun chat( query: String, - projectId: String?, - location: String?, - maxToken: Int + apiKey: String?, + maxTokens: Int ): String? { - if (!projectId.isNullOrEmpty() && !location.isNullOrEmpty()) { + if (!apiKey.isNullOrEmpty()) { try { - VertexAI(projectId, location).use { vertexAI -> - val generationConfig = GenerationConfig.newBuilder().setMaxOutputTokens(maxToken).build() - val safetySettings = listOf( - SafetySetting.newBuilder() - .setCategory(HarmCategory.HARM_CATEGORY_HATE_SPEECH) - .setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_LOW_AND_ABOVE) - .build(), - SafetySetting.newBuilder() - .setCategory(HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT) - .setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_LOW_AND_ABOVE) - .build(), - SafetySetting.newBuilder() - .setCategory(HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT) - .setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_LOW_AND_ABOVE) - .build(), - SafetySetting.newBuilder() - .setCategory(HarmCategory.HARM_CATEGORY_HARASSMENT) - .setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_LOW_AND_ABOVE) - .build() - ) - val model = GenerativeModel.Builder().setModelName("gemini-1.5-flash-001") - .setGenerationConfig(generationConfig) - .setVertexAi(vertexAI).build() - .withSafetySettings(safetySettings) + val gemini = GoogleAiGeminiChatModel.builder() + .apiKey(apiKey) + .modelName("gemini-1.5-flash") + .maxOutputTokens(maxTokens) + .build() - val response = model.generateContent(query) - return ResponseHandler.getText(response) - } + return gemini.generate(query) } catch (e: Exception) { throw ModuleException( "$GEMINI_CMD($query): IO", @@ -159,7 +126,6 @@ class Gemini : AbstractModule() { add(Utils.helpFormat("%c $GEMINI_CMD explain quantum computing in simple terms")) add(Utils.helpFormat("%c $GEMINI_CMD how do I make an HTTP request in Javascript?")) } - initProperties(PROJECT_ID_PROP, LOCATION_PROP, MAX_TOKENS_PROP) + initProperties(GEMINI_API_KEY, MAX_TOKENS_PROP) } - } diff --git a/src/test/kotlin/net/thauvin/erik/mobibot/modules/ChatGptTest.kt b/src/test/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt2Test.kt similarity index 84% rename from src/test/kotlin/net/thauvin/erik/mobibot/modules/ChatGptTest.kt rename to src/test/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt2Test.kt index 1809a9f..4332a52 100644 --- a/src/test/kotlin/net/thauvin/erik/mobibot/modules/ChatGptTest.kt +++ b/src/test/kotlin/net/thauvin/erik/mobibot/modules/ChatGpt2Test.kt @@ -39,10 +39,10 @@ import net.thauvin.erik.mobibot.DisableOnCi import net.thauvin.erik.mobibot.LocalProperties import kotlin.test.Test -class ChatGptTest : LocalProperties() { +class ChatGpt2Test : LocalProperties() { @Test fun testApiKey() { - assertFailure { ChatGpt.chat("1 gallon to liter", "", 0) } + assertFailure { ChatGpt2.chat("1 gallon to liter", "", 0) } .isInstanceOf(ModuleException::class.java) .hasNoCause() } @@ -51,7 +51,7 @@ class ChatGptTest : LocalProperties() { fun testChatOnCoverage() { if (System.getenv("CI") == null || System.getenv("COVERAGE_JDK") != null) { assertThat( - ChatGpt.chat("how do I encode a URL in java?", getProperty(ChatGpt.API_KEY_PROP), 60) + ChatGpt2.chat("how do I encode a URL in java?", getProperty(ChatGpt2.API_KEY_PROP), 60) ).contains("URLEncoder") } } @@ -59,12 +59,12 @@ class ChatGptTest : LocalProperties() { @Test @DisableOnCi fun testChat() { - val apiKey = getProperty(ChatGpt.API_KEY_PROP) + val apiKey = getProperty(ChatGpt2.API_KEY_PROP) assertThat( - ChatGpt.chat("how do I make an HTTP request in Javascript?", apiKey, 100) + ChatGpt2.chat("how do I make an HTTP request in Javascript?", apiKey, 200) ).contains("XMLHttpRequest") - assertFailure { ChatGpt.chat("1 liter to gallon", apiKey, -1) } + assertFailure { ChatGpt2.chat("1 liter to gallon", apiKey, -1) } .isInstanceOf(ModuleException::class.java) } } diff --git a/src/test/kotlin/net/thauvin/erik/mobibot/modules/GeminiTest.kt b/src/test/kotlin/net/thauvin/erik/mobibot/modules/Gemini2Test.kt similarity index 79% rename from src/test/kotlin/net/thauvin/erik/mobibot/modules/GeminiTest.kt rename to src/test/kotlin/net/thauvin/erik/mobibot/modules/Gemini2Test.kt index 1f0202f..226ff6a 100644 --- a/src/test/kotlin/net/thauvin/erik/mobibot/modules/GeminiTest.kt +++ b/src/test/kotlin/net/thauvin/erik/mobibot/modules/Gemini2Test.kt @@ -37,10 +37,10 @@ import net.thauvin.erik.mobibot.DisableOnCi import net.thauvin.erik.mobibot.LocalProperties import kotlin.test.Test -class GeminiTest : LocalProperties() { +class Gemini2Test : LocalProperties() { @Test fun testApiKey() { - assertFailure { Gemini.chat("1 gallon to liter", "", "", 1024) } + assertFailure { Gemini2.chat("1 gallon to liter", "", 0) } .isInstanceOf(ModuleException::class.java) .hasNoCause() } @@ -48,19 +48,18 @@ class GeminiTest : LocalProperties() { @Test @DisableOnCi fun chatPrompt() { - val projectId = getProperty(Gemini.PROJECT_ID_PROP) - val location = getProperty(Gemini.LOCATION_PROP) - val maxTokens = getProperty(Gemini.MAX_TOKENS_PROP).toInt() + val apiKey = getProperty(Gemini2.GEMINI_API_KEY) + val maxTokens = getProperty(Gemini2.MAX_TOKENS_PROP).toInt() assertThat( - Gemini.chat("how do I make an HTTP request in Javascript?", projectId, location, maxTokens) + Gemini2.chat("how do I make an HTTP request in Javascript?", apiKey, maxTokens) ).isNotNull().contains("XMLHttpRequest") assertThat( - Gemini.chat("how do I encode a URL in java?", projectId, location, 60) + Gemini2.chat("how do I encode a URL in java?", apiKey, 60) ).isNotNull().contains("URLEncoder") - assertFailure { Gemini.chat("1 liter to gallon", projectId, "blah", 40) } + assertFailure { Gemini2.chat("1 liter to gallon", "foo", 40) } .isInstanceOf(ModuleException::class.java) } } diff --git a/website/index.html b/website/index.html index fffe650..370c3cf 100644 --- a/website/index.html +++ b/website/index.html @@ -38,10 +38,10 @@
  • Apache Commons Net
  • CryptoPrice
  • exp4j
  • -
  • Google Vertex AI
  • JokeAPI
  • jsoup
  • kotlinx-cli
  • +
  • LangChain4J
  • OkHttp
  • OWM JAPIs
  • Pinboard Poster